From 578f6f4d0f956dc5e9021b05189e03ae8c7585c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Tue, 16 Jan 2024 09:05:07 -0600 Subject: [PATCH] feat: accurate external module thickness --- .../components/ArmorHighlighting.tsx | 12 ++++--- .../components/ExternalModuleMask.tsx | 15 +++++++++ .../ArmorMesh/components/Armor/index.tsx | 3 ++ .../components/Armor/shaders/fragment.glsl | 10 +++--- .../components/ExternalModuleMask.tsx | 32 +++++++++++++------ 5 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/ArmorHighlighting.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/ArmorHighlighting.tsx index b6d3d7003..2d6fc6589 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/ArmorHighlighting.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor/components/ArmorHighlighting.tsx @@ -115,13 +115,8 @@ export function ArmorHighlighting({ duel }: ArmorHighlightingProps) { GLTFLoader, asset(`3d/tanks/armor/${duel.protagonist.tank.id}.glb`), ); - const modelGltf = useLoader( - GLTFLoader, - asset(`3d/tanks/models/${duel.protagonist.tank.id}.glb`), - ); const armorNodes = Object.values(armorGltf.nodes); - const modelNodes = Object.values(modelGltf.nodes); const tankModelDefinition = awaitedModelDefinitions[duel.protagonist.tank.id]; const turretModelDefinition = tankModelDefinition.turrets[duel.protagonist.turret.id]; @@ -137,6 +132,10 @@ export function ArmorHighlighting({ duel }: ArmorHighlightingProps) { turretModelDefinition.gunOrigin[1], -turretModelDefinition.gunOrigin[2], ).applyAxisAngle(X_AXIS, Math.PI / 2); + const maxExternalModuleThickness = Math.max( + tankModelDefinition.trackThickness, + gunModelDefinition.barrelThickness, + ); return ( (({ duel }) => { const wrapper = useRef(null); const awaitedModelDefinitions = useModelDefinitions(); @@ -127,6 +134,10 @@ export const ExternalModuleMask = memo(({ duel }) => { tankModelDefinition.turrets[duel.protagonist.turret.id]; const gunModelDefinition = turretModelDefinition.guns[duel.protagonist.gun.id]; + const maxThickness = Math.max( + tankModelDefinition.trackThickness, + gunModelDefinition.barrelThickness, + ); const turretOrigin = new Vector3( tankModelDefinition.turretOrigin[0], tankModelDefinition.turretOrigin[1], @@ -178,6 +189,8 @@ export const ExternalModuleMask = memo(({ duel }) => { return ( @@ -251,6 +264,8 @@ export const ExternalModuleMask = memo(({ duel }) => { return ( diff --git a/src/components/ArmorMesh/components/Armor/index.tsx b/src/components/ArmorMesh/components/Armor/index.tsx index 93fd1ca57..8e93bec83 100644 --- a/src/components/ArmorMesh/components/Armor/index.tsx +++ b/src/components/ArmorMesh/components/Armor/index.tsx @@ -17,12 +17,14 @@ interface ArmorMeshProps extends MeshProps { isSpaced: boolean; isExternalModule?: boolean; thickness: number; + maxExternalModuleThickness: number; } export function ArmorMesh({ isSpaced, isExternalModule = false, thickness, + maxExternalModuleThickness, duel, ...props }: ArmorMeshProps) { @@ -68,6 +70,7 @@ export function ArmorMesh({ projectionMatrixInverse: { value: null }, zNear: { value: camera.near }, zFar: { value: camera.far }, + maxExternalModuleThickness: { value: maxExternalModuleThickness }, isSpaced: { value: isSpaced }, isExplosive: { value: isExplosive(shell.type) }, canSplash: { value: canSplash(shell.type) }, diff --git a/src/components/ArmorMesh/components/Armor/shaders/fragment.glsl b/src/components/ArmorMesh/components/Armor/shaders/fragment.glsl index 11131d107..977133ad4 100644 --- a/src/components/ArmorMesh/components/Armor/shaders/fragment.glsl +++ b/src/components/ArmorMesh/components/Armor/shaders/fragment.glsl @@ -12,6 +12,7 @@ uniform sampler2D externalModuleMask; uniform sampler2D spacedArmorDepth; uniform vec2 resolution; varying mat4 vProjectionMatrix; +uniform float maxExternalModuleThickness; float depthToDistance(float depth) { mat4 projectionMatrixInverse = inverse(vProjectionMatrix); @@ -46,10 +47,11 @@ void main() { } else { float piercedPenetration = penetration; - // if (isUnderExternalModule) { - // // TODO: ADD - // piercedPenetration -= 50.0; - // } + if (isUnderExternalModule) { + float normalizedExternalModuleThickness = externalModuleMaskColor.g; + float externalModuleThickness = normalizedExternalModuleThickness * maxExternalModuleThickness; + piercedPenetration -= externalModuleThickness; + } if (isExplosive) { // 50% loss of remaining penetration per meter diff --git a/src/components/ArmorMesh/components/ExternalModuleMask.tsx b/src/components/ArmorMesh/components/ExternalModuleMask.tsx index 6c7c0d1f2..91f20c079 100644 --- a/src/components/ArmorMesh/components/ExternalModuleMask.tsx +++ b/src/components/ArmorMesh/components/ExternalModuleMask.tsx @@ -3,25 +3,37 @@ import { WebGLRenderTarget } from 'three'; export const externalModuleMaskRenderTarget = new WebGLRenderTarget(); -interface ArmorMeshExternalModuleMaskProps extends MeshProps { - exclude?: boolean; -} +type ArmorMeshExternalModuleMaskProps = MeshProps & + ( + | { + exclude?: false; + maxThickness: number; + thickness: number; + } + | { + exclude: true; + } + ); -export function ArmorMeshExternalModuleMask({ - exclude = false, - ...props -}: ArmorMeshExternalModuleMaskProps) { +export function ArmorMeshExternalModuleMask( + props: ArmorMeshExternalModuleMaskProps, +) { return ( <> - {exclude && ( + {props.exclude && ( )} - {!exclude && ( + {!props.exclude && ( - + )}