From 191d6133b2304ee3ffd301c9d8dcdfac30035817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Sun, 17 Mar 2024 22:11:56 -0500 Subject: [PATCH] feat: togglable spaced armor --- .../components/Model/components/Options.tsx | 18 ++++++++++++++++++ .../CoreArmorSceneComponent/index.tsx | 2 ++ .../shaders/fragment.glsl | 3 ++- .../SpacedArmorSceneComponent/index.tsx | 15 ++++++++++++--- src/stores/tankopedia.ts | 2 ++ 5 files changed, 36 insertions(+), 4 deletions(-) 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 e3ac0d6c9..fcbd8b5cd 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/Options.tsx @@ -8,6 +8,7 @@ import { Button, DropdownMenu, Flex } from '@radix-ui/themes'; import { RefObject } from 'react'; import { Pose, poseEvent } from '../../../../../../../core/blitzkrieg/pose'; import mutateTankopediaPersistent, { + mutateTankopediaTemporary, useTankopediaPersistent, } from '../../../../../../../stores/tankopedia'; import { ENVIRONMENTS } from '../../Lighting'; @@ -30,6 +31,9 @@ export function Options({ isFullScreen, canvasWrapper }: OptionsProps) { const wireframe = useTankopediaPersistent( (state) => state.model.visual.wireframe, ); + const showSpacedArmor = useTankopediaPersistent( + (state) => state.model.visual.showSpacedArmor, + ); const opaque = useTankopediaPersistent((state) => state.model.visual.opaque); const fullScreenAvailable = typeof document !== 'undefined' && document.fullscreenEnabled; @@ -81,6 +85,20 @@ export function Options({ isFullScreen, canvasWrapper }: OptionsProps) { Armor + { + mutateTankopediaPersistent((draft) => { + draft.model.visual.showSpacedArmor = checked; + }); + mutateTankopediaTemporary((draft) => { + draft.shot = undefined; + }); + }} + > + Spaced armor + + { diff --git a/src/components/Armor/components/CoreArmorSceneComponent/index.tsx b/src/components/Armor/components/CoreArmorSceneComponent/index.tsx index 3a3d5955b..d5e8d9fde 100644 --- a/src/components/Armor/components/CoreArmorSceneComponent/index.tsx +++ b/src/components/Armor/components/CoreArmorSceneComponent/index.tsx @@ -48,6 +48,7 @@ export function CoreArmorSceneComponent({ explosionRadius: { value: null }, greenPenetration: { value: null }, opaque: { value: null }, + useSpacedArmor: { value: null }, resolution: { value: new Vector2() }, spacedArmorBuffer: { value: null }, @@ -75,6 +76,7 @@ export function CoreArmorSceneComponent({ ) { material.uniforms.greenPenetration.value = visual.greenPenetration; material.uniforms.opaque.value = visual.opaque || visual.wireframe; + material.uniforms.useSpacedArmor.value = visual.showSpacedArmor; material.wireframe = visual.wireframe; } async function handleProtagonistEquipmentChange( diff --git a/src/components/Armor/components/CoreArmorSceneComponent/shaders/fragment.glsl b/src/components/Armor/components/CoreArmorSceneComponent/shaders/fragment.glsl index 7975e2c20..6a294b366 100644 --- a/src/components/Armor/components/CoreArmorSceneComponent/shaders/fragment.glsl +++ b/src/components/Armor/components/CoreArmorSceneComponent/shaders/fragment.glsl @@ -14,6 +14,7 @@ uniform float damage; uniform float explosionRadius; uniform bool greenPenetration; uniform bool opaque; +uniform bool useSpacedArmor; uniform highp sampler2D spacedArmorBuffer; uniform highp sampler2D spacedArmorDepth; @@ -49,7 +50,7 @@ void main() { float coreArmorDistance = depthToDistance(gl_FragCoord.z); float distanceFromSpacedArmor = coreArmorDistance - spacedArmorDistance; - if (isUnderSpacedArmor) { + if (useSpacedArmor && isUnderSpacedArmor) { float spacedArmorThickness = spacedArmorBufferFragment.r * penetration; remainingPenetration -= spacedArmorThickness; diff --git a/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx b/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx index 9f1890888..cfd7314d4 100644 --- a/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx +++ b/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx @@ -18,6 +18,7 @@ import { useDuel } from '../../../../stores/duel'; import { Shot, ShotLayerBase, + useTankopediaPersistent, useTankopediaTemporary, } from '../../../../stores/tankopedia'; import { ArmorType } from '../SpacedArmorScene'; @@ -115,12 +116,20 @@ export function SpacedArmorSceneComponent({ pushLogs(shellNormal, filterIntersections(event.intersections), 0); function filterIntersections(intersectionsRaw: Intersection[]) { - const intersectionsAll = intersectionsRaw.filter( + const showSpacedArmor = + useTankopediaPersistent.getState().model.visual.showSpacedArmor; + const intersectionsTyped = intersectionsRaw.filter( ({ object }) => object.userData.type !== undefined, ) as ArmorMeshIntersection[]; - const intersectionsWithDuplicates = intersectionsAll.slice( + const intersectionsFiltered = intersectionsTyped.filter( + ({ object }) => + showSpacedArmor + ? true + : object.userData.type === ArmorType.Core, + ); + const intersectionsWithDuplicates = intersectionsFiltered.slice( 0, - intersectionsAll.findIndex( + intersectionsFiltered.findIndex( ({ object }) => object.userData.type === ArmorType.Core, ) + 1, ); diff --git a/src/stores/tankopedia.ts b/src/stores/tankopedia.ts index f4dd7946c..92a5fee0c 100644 --- a/src/stores/tankopedia.ts +++ b/src/stores/tankopedia.ts @@ -23,6 +23,7 @@ export interface TankopediaPersistent { showGrid: boolean; greenPenetration: boolean; showEnvironment: boolean; + showSpacedArmor: boolean; }; }; sort: { @@ -123,6 +124,7 @@ export const useTankopediaPersistent = create()( subscribeWithSelector(() => ({ model: { visual: { + showSpacedArmor: true, wireframe: false, opaque: false, environment: ENVIRONMENTS[0],