diff --git a/public/test/7425.glb b/public/test/7425.glb new file mode 100644 index 000000000..ce27c7394 Binary files /dev/null and b/public/test/7425.glb differ diff --git a/scripts/buildAssets.ts b/scripts/buildAssets.ts index 1b5d0efdb..7ad84351b 100644 --- a/scripts/buildAssets.ts +++ b/scripts/buildAssets.ts @@ -586,7 +586,8 @@ if (allTargets || targets?.includes('tankModels')) { const id = (nationVehicleId << 8) + (NATION_IDS[nation] << 4) + 1; // if (id !== 15697) continue; // chieftain TODO: investigate vertices stream over read - if (id !== 24609) continue; // concept 1b + // if (id !== 24609) continue; // concept 1b + if (id !== 7425) continue; // isu 152 // if (id !== 4417) continue; // amx m4 mle // if (id !== 7297) continue; // 60tp // if (id !== 1) continue; // t-34 diff --git a/src/app/tools/tankopedia/[id]/components/tankAlignment.tsx b/src/app/tools/tankopedia/[id]/components/tankAlignment.tsx deleted file mode 100644 index 68ca5872b..000000000 --- a/src/app/tools/tankopedia/[id]/components/tankAlignment.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { OrbitControls } from '@react-three/drei'; -import { useThree } from '@react-three/fiber'; -import { RefObject, memo, useEffect, useRef } from 'react'; -import { Box3, Group, Vector3 } from 'three'; -import { OrbitControls as OrbitControlsImpl } from 'three-stdlib'; - -interface TankAlignmentProps { - model: RefObject; - orbit: boolean; -} - -export const TankAlignment = memo( - ({ model, orbit }: TankAlignmentProps) => { - const controls = useRef(null); - const camera = useThree((state) => state.camera); - - useEffect(() => { - const box = new Box3().setFromObject(model.current!); - controls.current?.target.set(0, (2 * box.min.y + box.max.y) / 3, 0); - camera.position.set(-5, (box.min.y + box.max.y) / 2, -15); - }, []); - - return ( - - ); - }, - () => false, -); diff --git a/src/app/tools/tankopedia/[id]/page.tsx b/src/app/tools/tankopedia/[id]/page.tsx index f696994fd..54a839174 100644 --- a/src/app/tools/tankopedia/[id]/page.tsx +++ b/src/app/tools/tankopedia/[id]/page.tsx @@ -40,7 +40,6 @@ import { } from '../../../../core/blitzkrieg/tankDefinitions'; import { normalizeAnglePI } from '../../../../core/math/normalizeAngle180'; import * as styles from '../page.css'; -import { TankAlignment } from './components/TankAlignment'; const X_AXIS = new Vector3(1, 0, 0); @@ -82,7 +81,6 @@ export default function Page({ params }: { params: { id: string } }) { const [turretYaw, setTurretYaw] = useState(0); const [hullYaw, setHullYaw] = useState(0); const [gunPitch, setGunPitch] = useState(0); - const [orbitControlsEnabled, setOrbitControlsEnabled] = useState(true); const turretYawInput = useRef(null); const hullYawInput = useRef(null); const gunPitchInput = useRef(null); @@ -146,17 +144,7 @@ export default function Page({ params }: { params: { id: string } }) {
- event.preventDefault()} - camera={{ fov: 20 }} - > - - + {gltf.scene.children[0].children.map((child) => { - const isGun = - child.name.startsWith('gun_') && - !child.name.endsWith('_mask'); - const isMantlet = - child.name.startsWith('gun_') && - child.name.endsWith('_mask'); - const isVisible = isGun || isMantlet; + const isCurrentMantlet = + child.name === + `gun_${gunModelDefinition.model + .toString() + .padStart(2, '0')}_mask`; + const isCurrentGun = + child.name === + `gun_${gunModelDefinition.model + .toString() + .padStart(2, '0')}`; + const isVisible = isCurrentGun || isCurrentMantlet; let draftMantletPitch = 0; + let draftTurretYaw = 0; function handlePointerDown( event: ThreeEvent, ) { event.stopPropagation(); draftMantletPitch = gunPitch; - setOrbitControlsEnabled(false); + draftTurretYaw = turretYaw; window.addEventListener( 'pointermove', handlePointerMove, @@ -365,6 +354,21 @@ export default function Page({ params }: { params: { id: string } }) { ); } function handlePointerMove(event: PointerEvent) { + if (turretModelDefinition.yaw) { + draftTurretYaw = clamp( + draftTurretYaw + + event.movementX * + (Math.PI / canvas.current!.width), + -turretModelDefinition.yaw.max * + (Math.PI / 180), + -turretModelDefinition.yaw.min * + (Math.PI / 180), + ); + } else { + draftTurretYaw += + event.movementX * + ((2 * Math.PI) / canvas.current!.width); + } draftMantletPitch = clamp( draftMantletPitch - event.movementY * @@ -387,10 +391,23 @@ export default function Page({ params }: { params: { id: string } }) { gunContainer.current.rotation.x = draftMantletPitch; } + + if (turretContainer.current) { + turretContainer.current.position + .set(0, 0, 0) + .sub(turretOrigin) + .applyAxisAngle( + new Vector3(0, 0, 1), + draftTurretYaw, + ) + .add(turretOrigin); + turretContainer.current.rotation.z = + draftTurretYaw; + } } function handlePointerUp() { - setOrbitControlsEnabled(true); setGunPitch(normalizeAnglePI(draftMantletPitch)); + setTurretYaw(normalizeAnglePI(draftTurretYaw)); window.removeEventListener( 'pointermove', handlePointerMove,