mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 12:09:51 +02:00
fix: correctly re-mounting camera
This commit is contained in:
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 (
|
||||||
<>
|
<>
|
||||||
|
|||||||
Reference in new issue
Block a user