diff --git a/.vscode/settings.json b/.vscode/settings.json index bebb6611c..13d0a5a5d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -130,6 +130,7 @@ "wargaming", "webp", "winrate", + "wireframe", "wotblitz", "xffn", "xkdkw", diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx index 2ea2ac0e1..a19a4cb34 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx @@ -27,6 +27,9 @@ export function Options({ isFullScreen, canvas }: OptionsProps) { const greenPenetration = useTankopediaPersistent( (state) => state.model.visual.greenPenetration, ); + const wireframe = useTankopediaPersistent( + (state) => state.model.visual.wireframe, + ); const fullScreenAvailable = typeof document !== 'undefined' && document.fullscreenEnabled; const environment = useTankopediaPersistent( @@ -126,6 +129,17 @@ export function Options({ isFullScreen, canvas }: OptionsProps) { + + { + mutateTankopediaPersistent((draft) => { + draft.model.visual.wireframe = checked; + }); + }} + > + Wireframe + diff --git a/src/components/ArmorMesh/components/Armor/index.tsx b/src/components/ArmorMesh/components/Armor/index.tsx index c67135079..2f51b9f78 100644 --- a/src/components/ArmorMesh/components/Armor/index.tsx +++ b/src/components/ArmorMesh/components/Armor/index.tsx @@ -57,6 +57,7 @@ export function ArmorMesh({ const scene = useThree((state) => state.scene); const hasCalibratedShells = useAwait(hasEquipment(103)); const hasEnhancedArmor = useAwait(hasEquipment(110)); + const wireframe = initialTankopedia.model.visual.wireframe; useEffect(() => { async function updateQuickEquipments() { @@ -109,6 +110,15 @@ export function ArmorMesh({ } }, ), + useTankopediaPersistent.subscribe( + (state) => state.model.visual.wireframe, + (wireframe) => { + if (material.current) { + material.current.wireframe = wireframe; + material.current.uniforms.wireframe.value = wireframe; + } + }, + ), ]; return () => { @@ -386,44 +396,48 @@ export function ArmorMesh({ }); }} > - + {true && ( + + )} ); diff --git a/src/components/ArmorMesh/components/Armor/shaders/fragment.glsl b/src/components/ArmorMesh/components/Armor/shaders/fragment.glsl index b7387df3b..13eb9dbd0 100644 --- a/src/components/ArmorMesh/components/Armor/shaders/fragment.glsl +++ b/src/components/ArmorMesh/components/Armor/shaders/fragment.glsl @@ -19,6 +19,7 @@ uniform float maxThickness; uniform bool greenPenetration; uniform float damage; uniform float explosionRadius; +uniform bool wireframe; float depthToDistance(float depth) { mat4 projectionMatrixInverse = inverse(vProjectionMatrix); @@ -107,8 +108,8 @@ void main() { } vec3 color = vec3(1.0, splashChance * 0.392, 0.0); - if (greenPenetration) { - gl_FragColor = vec4(mix(color, vec3(0.0, 1.0, 0.0), penetrationChance), 0.5); + if (greenPenetration || wireframe) { + gl_FragColor = vec4(mix(color, vec3(0.0, 1.0, 0.0), penetrationChance), wireframe ? 1.0 : 0.5); } else { gl_FragColor = vec4(color, (1.0 - penetrationChance) * 0.5); } diff --git a/src/stores/tankopedia.ts b/src/stores/tankopedia.ts index da7e5067b..c77da8907 100644 --- a/src/stores/tankopedia.ts +++ b/src/stores/tankopedia.ts @@ -30,6 +30,7 @@ export interface DuelMember { interface TankopediaPersistent { model: { visual: { + wireframe: boolean; environment: (typeof ENVIRONMENTS)[number]; controlsEnabled: boolean; showGrid: boolean; @@ -131,6 +132,7 @@ export const useTankopediaPersistent = create()( subscribeWithSelector(() => ({ model: { visual: { + wireframe: false, environment: ENVIRONMENTS[0], controlsEnabled: true, showGrid: true,