fix: correctly re-mounting camera

This commit is contained in:
TrèsAbhi committed 2024-07-22 20:47:29 -05:00
1 parent ffdb75d028
commit a237e1541b
3 files changed
+42 -47

No files matched your search

@@ -1,4 +1,3 @@
import { PerspectiveCamera } from '@react-three/drei';
import { Canvas } from '@react-three/fiber'; import { Canvas } from '@react-three/fiber';
import { Suspense, use, useEffect, useRef } from 'react'; import { Suspense, use, useEffect, useRef } from 'react';
import { Armor } from '../../../../../../components/Armor'; import { Armor } from '../../../../../../components/Armor';
@@ -121,10 +120,7 @@ export function TankSandbox() {
return ( return (
<Canvas <Canvas
gl={{ gl={{ clippingPlanes: Object.freeze([]), localClippingEnabled: true }}
clippingPlanes: Object.freeze([]),
localClippingEnabled: true,
}}
shadows shadows
ref={canvas} ref={canvas}
onPointerDown={handlePointerDown} onPointerDown={handlePointerDown}
@@ -133,11 +129,9 @@ export function TankSandbox() {
draft.shot = undefined; draft.shot = undefined;
}); });
}} }}
style={{ style={{ userSelect: 'none' }}
userSelect: 'none', camera={{ fov: 25, far: 32 }}
}}
> >
<PerspectiveCamera makeDefault fov={25} far={32} />
<Controls /> <Controls />
<SceneProps /> <SceneProps />
@@ -33,6 +33,37 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
const tankopediaPersistentStore = TankopediaPersistent.useStore(); const tankopediaPersistentStore = TankopediaPersistent.useStore();
const initialTankopediaState = tankopediaPersistentStore.getState(); const initialTankopediaState = tankopediaPersistentStore.getState();
const protagonist = Duel.use((draft) => draft.protagonist); const protagonist = Duel.use((draft) => draft.protagonist);
const tank = Duel.use((state) => state.protagonist.tank);
const track = Duel.use((state) => state.protagonist.track);
const turret = Duel.use((state) => state.protagonist.turret);
const gun = Duel.use((state) => state.protagonist.gun);
const armorGltf = useArmor(tank.id);
const { gltf: modelGltf } = useModel(tank.id);
const armorNodes = Object.values(armorGltf.nodes);
const modelNodes = Object.values(modelGltf.nodes);
const tankModelDefinition = modelDefinitions[tank.id];
const trackModelDefinition = tankModelDefinition.tracks[track.id];
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
const gunModelDefinition = turretModelDefinition.guns[gun.id];
const hullOrigin = new Vector3(
trackModelDefinition.origin[0],
trackModelDefinition.origin[1],
-trackModelDefinition.origin[2],
).applyAxisAngle(I_HAT, Math.PI / 2);
const turretOrigin = new Vector3(
tankModelDefinition.turretOrigin[0],
tankModelDefinition.turretOrigin[1],
-tankModelDefinition.turretOrigin[2],
).applyAxisAngle(I_HAT, Math.PI / 2);
const gunOrigin = new Vector3(
turretModelDefinition.gunOrigin[0],
turretModelDefinition.gunOrigin[1],
-turretModelDefinition.gunOrigin[2],
).applyAxisAngle(I_HAT, Math.PI / 2);
const maskOrigin =
gunModelDefinition.mask === undefined
? undefined
: gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y;
useEffect(() => { useEffect(() => {
if (!modelDefinitions) return; if (!modelDefinitions) return;
@@ -120,38 +151,6 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
return unsubscribe; return unsubscribe;
}); });
const tank = Duel.use((state) => state.protagonist.tank);
const track = Duel.use((state) => state.protagonist.track);
const turret = Duel.use((state) => state.protagonist.turret);
const gun = Duel.use((state) => state.protagonist.gun);
const armorGltf = useArmor(tank.id);
const { gltf: modelGltf } = useModel(tank.id);
const armorNodes = Object.values(armorGltf.nodes);
const modelNodes = Object.values(modelGltf.nodes);
const tankModelDefinition = modelDefinitions[tank.id];
const trackModelDefinition = tankModelDefinition.tracks[track.id];
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
const gunModelDefinition = turretModelDefinition.guns[gun.id];
const hullOrigin = new Vector3(
trackModelDefinition.origin[0],
trackModelDefinition.origin[1],
-trackModelDefinition.origin[2],
).applyAxisAngle(I_HAT, Math.PI / 2);
const turretOrigin = new Vector3(
tankModelDefinition.turretOrigin[0],
tankModelDefinition.turretOrigin[1],
-tankModelDefinition.turretOrigin[2],
).applyAxisAngle(I_HAT, Math.PI / 2);
const gunOrigin = new Vector3(
turretModelDefinition.gunOrigin[0],
turretModelDefinition.gunOrigin[1],
-turretModelDefinition.gunOrigin[2],
).applyAxisAngle(I_HAT, Math.PI / 2);
const maskOrigin =
gunModelDefinition.mask === undefined
? undefined
: gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y;
return ( return (
<group <group
ref={wrapper} ref={wrapper}
@@ -1,4 +1,5 @@
import { useThree } from '@react-three/fiber'; import { useThree } from '@react-three/fiber';
import { useCallback } from 'react';
import { import {
Intersection, Intersection,
MeshBasicMaterial, MeshBasicMaterial,
@@ -49,9 +50,6 @@ export type ArmorUserData = {
variant: ExternalModuleVariant; variant: ExternalModuleVariant;
} }
); );
type ArmorMeshIntersection = Intersection & {
object: Object3D & { userData: ArmorUserData };
};
const omitMaterial = new MeshBasicMaterial({ const omitMaterial = new MeshBasicMaterial({
colorWrite: false, colorWrite: false,
@@ -76,12 +74,13 @@ export function SpacedArmorSceneComponent({
const camera = useThree((state) => state.camera); const camera = useThree((state) => state.camera);
const duelStore = Duel.useStore(); const duelStore = Duel.useStore();
async function shoot( const shoot = useCallback(
async (
point: Vector3, point: Vector3,
intersections: Intersection[], intersections: Intersection[],
allowRicochet: boolean, allowRicochet: boolean,
remainingPenetrationInput?: number, remainingPenetrationInput?: number,
) { ) => {
const { antagonist, protagonist } = duelStore.getState(); const { antagonist, protagonist } = duelStore.getState();
const shell = antagonist.shell; const shell = antagonist.shell;
const cameraNormal = camera.position.clone().sub(point).normalize(); const cameraNormal = camera.position.clone().sub(point).normalize();
@@ -189,6 +188,7 @@ export function SpacedArmorSceneComponent({
isExplosive(shell.type) ? 90 : shell.ricochet!, isExplosive(shell.type) ? 90 : shell.ricochet!,
); );
const angle = surfaceNormal.angleTo(cameraNormal); const angle = surfaceNormal.angleTo(cameraNormal);
const threeCalibersRule = const threeCalibersRule =
shell.caliber > thickness * 3 || index > 0 || !allowRicochet; shell.caliber > thickness * 3 || index > 0 || !allowRicochet;
const twoCalibersRule = shell.caliber > thickness * 2; const twoCalibersRule = shell.caliber > thickness * 2;
@@ -349,7 +349,9 @@ export function SpacedArmorSceneComponent({
} }
return shot; return shot;
} },
[camera],
);
return ( return (
<> <>