From 7f49245f15ff9e923a3d174a8f78dc3ce756db3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 28 Feb 2024 23:06:37 -0600 Subject: [PATCH] feat: more progress --- .../[id]/components/Model/TankSandbox.tsx | 3 +- .../{ShotScene.tsx => ShotDisplay.tsx} | 51 +++++---- .../SpacedArmorSceneComponent/index.tsx | 101 +++++++++++------- src/components/Armor/index.tsx | 7 -- 4 files changed, 95 insertions(+), 67 deletions(-) rename src/components/Armor/components/{ShotScene.tsx => ShotDisplay.tsx} (60%) diff --git a/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx b/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx index ed1d98ae0..e7e9744a6 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx @@ -5,7 +5,7 @@ import { Canvas } from '@react-three/fiber'; import { Suspense, use, useEffect, useRef, useState } from 'react'; import { isMobile } from 'react-device-detect'; import { Armor } from '../../../../../../components/Armor'; -import { ShotScene } from '../../../../../../components/Armor/components/ShotScene'; +import { ShotDisplay } from '../../../../../../components/Armor/components/ShotDisplay'; import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits'; import { modelDefinitions } from '../../../../../../core/blitzkrieg/modelDefinitions'; import { modelTransformEvent } from '../../../../../../core/blitzkrieg/modelTransform'; @@ -201,6 +201,7 @@ export function TankSandbox() { + diff --git a/src/components/Armor/components/ShotScene.tsx b/src/components/Armor/components/ShotDisplay.tsx similarity index 60% rename from src/components/Armor/components/ShotScene.tsx rename to src/components/Armor/components/ShotDisplay.tsx index 9fa423a3c..2009a7288 100644 --- a/src/components/Armor/components/ShotScene.tsx +++ b/src/components/Armor/components/ShotDisplay.tsx @@ -1,6 +1,6 @@ import { Text } from '@radix-ui/themes'; import { Html } from '@react-three/drei'; -import { DoubleSide, Euler, Quaternion, Vector3 } from 'three'; +import { Euler, Quaternion, Vector3 } from 'three'; import { J_HAT } from '../../../constants/axis'; import { ShotLayerGap, @@ -22,7 +22,7 @@ import { // const THICKNESS = 0.05; // const LENGTH = 4; -export function ShotScene() { +export function ShotDisplay() { const shot = useTankopediaTemporary((state) => state.shot); return ( @@ -39,28 +39,39 @@ export function ShotScene() { return ( <> - - - - - {shot.length > 1 && ( - - {layer.index + 1} + +
+ + {layer.index + 1} + +
)} @@ -73,9 +84,9 @@ export function ShotScene() { } return ( - + - + ); })()} diff --git a/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx b/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx index 81950104e..5ac920e80 100644 --- a/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx +++ b/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx @@ -8,13 +8,17 @@ import { Scene, Vector3, } from 'three'; -import { degToRad, radToDeg } from 'three/src/math/MathUtils'; +import { degToRad } from 'three/src/math/MathUtils'; import { isExplosive } from '../../../../core/blitz/isExplosive'; import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetration'; import { hasEquipment } from '../../../../core/blitzkrieg/hasEquipment'; import { jsxTree } from '../../../../core/blitzkrieg/jsxTree'; import { useDuel } from '../../../../stores/duel'; -import { Shot, useTankopediaTemporary } from '../../../../stores/tankopedia'; +import { + Shot, + ShotLayerBase, + useTankopediaTemporary, +} from '../../../../stores/tankopedia'; import { ArmorType } from '../SpacedArmorScene'; import { SpacedArmorSubExternal } from './components/SpacedArmorSubExternal'; import { SpacedArmorSubSpaced } from './components/SpacedArmorSubSpaced'; @@ -68,7 +72,7 @@ export function SpacedArmorSceneComponent({ ...props }: SpacedArmorSceneComponentProps) { const camera = useThree((state) => state.camera); - const cameraNormal = new Vector3(); + // const cameraNormal = new Vector3(); return ( <> @@ -104,26 +108,26 @@ export function SpacedArmorSceneComponent({ .clone() .sub(event.point) .normalize(); - shellNormal - .copy(camera.getWorldDirection(cameraNormal)) - .multiplyScalar(-1); + const cameraNormal = shellNormal.clone().multiplyScalar(-1); + pushLogs( shellNormal, + cameraNormal, filterIntersections(event.intersections), - true, + 0, ); - console.clear(); - console.log( - JSON.stringify( - shot.map((i) => ({ - ...i, - ...(i.angle ? { angle: radToDeg(i.angle) } : {}), - })), - null, - 2, - ), - ); + // console.clear(); + // console.log( + // JSON.stringify( + // shot.map((i) => ({ + // ...i, + // ...(i.angle ? { angle: radToDeg(i.angle) } : {}), + // })), + // null, + // 2, + // ), + // ); function filterIntersections(intersectionsRaw: Intersection[]) { const intersectionsAll = intersectionsRaw.filter( @@ -166,15 +170,35 @@ export function SpacedArmorSceneComponent({ }); } + console.log( + JSON.stringify( + intersections.map((i) => i.object.userData), + null, + 2, + ), + ); + return intersections; } function pushLogs( shellNormal: Vector3, + cameraNormal: Vector3, intersections: ArmorMeshIntersection[], - allowRicochets: boolean, + startingIndex: number, ) { - let index = 0; + let layerIndex = startingIndex; + let loopIndex = 0; + + if (layerIndex !== 0) { + shot.push({ + type: null, + distance: (shot.at(-1) as ShotLayerBase).point.distanceTo( + intersections[0].point, + ), + }); + } + for (const intersection of intersections) { const surfaceNormal = intersection .normal!.clone() @@ -184,8 +208,8 @@ export function SpacedArmorSceneComponent({ const thickness = thicknessCoefficient * intersection.object.userData.thickness; - if (index !== 0) { - const previousIntersection = intersections[index - 1]; + if (layerIndex !== 0 && startingIndex === 0) { + const previousIntersection = intersections[layerIndex - 1]; shot.push({ type: null, distance: @@ -199,7 +223,7 @@ export function SpacedArmorSceneComponent({ shot.push({ type: ArmorType.External, - index, + index: layerIndex, shellNormal, surfaceNormal, point: intersection.point, @@ -210,19 +234,11 @@ export function SpacedArmorSceneComponent({ if (blocked) break; } else { const type = intersection.object.userData.type; - shellNormal.copy( - cameraNormal - .copy(camera.position) - .sub(event.point) - .normalize(), - ); const angle = surfaceNormal.angleTo(shellNormal); const ricochet = degToRad(shell.ricochet ?? 90); const normalization = degToRad(shell.normalization ?? 0); const threeCalibersRule = - shell.caliber > thickness * 3 || - index > 0 || - !allowRicochets; + shell.caliber > thickness * 3 || layerIndex > 0; const twoCalibersRule = shell.caliber > thickness * 2; const finalNormalization = twoCalibersRule ? (1.4 * normalization * shell.caliber) / (2.0 * thickness) @@ -234,7 +250,7 @@ export function SpacedArmorSceneComponent({ if (!threeCalibersRule && angle >= ricochet) { shot.push({ type, - index, + index: layerIndex, shellNormal, surfaceNormal, point: intersection.point, @@ -245,15 +261,21 @@ export function SpacedArmorSceneComponent({ }); const raycaster = new Raycaster(); - const newShellNormal = cameraNormal + const newShellNormal = shellNormal .clone() .reflect(surfaceNormal); + const newCameraNormal = newShellNormal + .clone() + .multiplyScalar(-1); - raycaster.set(intersection.point, newShellNormal); + raycaster.set(intersection.point, newCameraNormal); pushLogs( newShellNormal, - raycaster.intersectObjects(scene.children, true), - false, + newCameraNormal, + filterIntersections( + raycaster.intersectObjects(scene.children, true), + ), + layerIndex + 1, ); break; @@ -261,7 +283,7 @@ export function SpacedArmorSceneComponent({ const blocked = remainingPenetration < 0; shot.push({ type, - index, + index: layerIndex, shellNormal, surfaceNormal, point: intersection.point, @@ -273,7 +295,8 @@ export function SpacedArmorSceneComponent({ } } - index++; + layerIndex++; + loopIndex++; } } diff --git a/src/components/Armor/index.tsx b/src/components/Armor/index.tsx index c3a889805..67ac23c84 100644 --- a/src/components/Armor/index.tsx +++ b/src/components/Armor/index.tsx @@ -3,19 +3,16 @@ import { memo, useState } from 'react'; import { DepthTexture, Scene, Vector2 } from 'three'; import { CoreArmorScene } from './components/CoreArmorScene'; import { spacedArmorRenderTarget } from './components/CoreArmorSceneComponent'; -import { ShotScene } from './components/ShotScene'; import { SpacedArmorScene } from './components/SpacedArmorScene'; export const Armor = memo(() => { const [spacedArmorScene] = useState(() => new Scene()); const [coreArmorScene] = useState(() => new Scene()); - const [shotScene] = useState(() => new Scene()); const spacedArmorPortal = createPortal( , spacedArmorScene, ); const coreArmorPortal = createPortal(, coreArmorScene); - const shotPortal = createPortal(, shotScene); const renderSize = new Vector2(); const newRenderSize = new Vector2(); @@ -44,16 +41,12 @@ export const Armor = memo(() => { gl.clearDepth(); gl.render(coreArmorScene, camera); - - gl.clearDepth(); - gl.render(shotScene, camera); }, 1); return ( <> {spacedArmorPortal} {coreArmorPortal} - {shotPortal} ); });