feat: consistent zoom

This commit is contained in:
tresabhi committed 2024-12-12 19:35:10 -06:00
1 parent 2f9791d34c
commit d19d4e0e26
3 files changed
+51 -15

No files matched your search

@@ -8,6 +8,10 @@ import { degToRad } from 'three/src/math/MathUtils.js';
import { awaitableModelDefinitions } from '../../../../../../core/awaitables/modelDefinitions';
import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits';
import { hasEquipment } from '../../../../../../core/blitzkit/hasEquipment';
import {
modelTransformEvent,
type ModelTransformEventData,
} from '../../../../../../core/blitzkit/modelTransform';
import { Pose, poseEvent } from '../../../../../../core/blitzkit/pose';
import { Duel } from '../../../../../../stores/duel';
import {
@@ -16,6 +20,7 @@ import {
TankopediaEphemeral,
} from '../../../../../../stores/tankopediaEphemeral';
import { TankopediaDisplay } from '../../../../../../stores/tankopediaPersistent/constants';
import { aimTarget } from './SceneProps/constants';
const poseDistances: Record<Pose, number> = {
[Pose.HullDown]: 15,
@@ -199,6 +204,8 @@ export function Controls() {
}, [camera, protagonistTank.id, antagonistTank.id]);
useEffect(() => {
let isInitialIteration = true;
function handleDisturbance() {
setAutoRotate(false);
}
@@ -243,6 +250,8 @@ export function Controls() {
document.body.addEventListener('scroll', handleScroll);
const sniperModeCameraOffset = new Vector3();
let pitch = 0;
let yaw = 0;
function updateCamera() {
if (!orbitControls.current) return;
@@ -261,19 +270,32 @@ export function Controls() {
if (shootingRangeZoom === ShootingRangeZoom.Arcade) {
orbitControls.current.target.set(0, gunHeight + 3, 0);
camera.position.set(
0,
gunHeight + ARCADE_MODE_DISTANCE * Math.sin(ARCADE_MODE_ANGLE),
ARCADE_MODE_DISTANCE * Math.cos(ARCADE_MODE_ANGLE),
);
if (isInitialIteration) {
isInitialIteration = false;
camera.position.set(
0,
gunHeight + ARCADE_MODE_DISTANCE * Math.sin(ARCADE_MODE_ANGLE),
ARCADE_MODE_DISTANCE * Math.cos(ARCADE_MODE_ANGLE),
);
} else {
camera.position
.copy(aimTarget)
.sub(orbitControls.current.target)
.normalize()
.multiplyScalar(-ARCADE_MODE_DISTANCE)
.add(orbitControls.current.target);
}
} else {
orbitControls.current.target.copy(shellOrigin);
camera.position.copy(
sniperModeCameraOffset.set(0, 0, 1e-4).add(shellOrigin),
);
}
console.log(ShootingRangeZoom[shootingRangeZoom], camera.zoom);
camera.position
.copy(aimTarget)
.sub(shellOrigin)
.normalize()
.multiplyScalar(-1e-4)
.add(shellOrigin);
}
} else {
camera.position.set(...inspectModeInitialPosition);
orbitControls.current.target.set(0, gunHeight / 2, 0);
@@ -285,6 +307,13 @@ export function Controls() {
camera.updateProjectionMatrix();
}
function handleModelTransform(event: ModelTransformEventData) {
pitch = event.pitch;
yaw = event.yaw ?? yaw;
}
modelTransformEvent.on(handleModelTransform);
updateCamera();
const unsubscribeDisplay = tankopediaEphemeralStore.subscribe(
@@ -308,6 +337,7 @@ export function Controls() {
window.removeEventListener('keydown', handleKeyDown);
canvas.removeEventListener('wheel', handleWheel);
document.body.removeEventListener('scroll', handleScroll);
modelTransformEvent.off(handleModelTransform);
};
}, [display === TankopediaDisplay.ShootingRange]);
@@ -0,0 +1,3 @@
import { Vector3 } from 'three';
export const aimTarget = new Vector3();
@@ -24,6 +24,7 @@ import { TankopediaEphemeral } from '../../../../../../../stores/tankopediaEphem
import { TankopediaPersistent } from '../../../../../../../stores/tankopediaPersistent';
import { TankopediaDisplay } from '../../../../../../../stores/tankopediaPersistent/constants';
import { TargetCircle } from './components/TargetCircle';
import { aimTarget } from './constants';
const [modelDefinitions, equipmentDefinitions, provisionDefinitions] =
await Promise.all([
@@ -106,6 +107,8 @@ export function SceneProps() {
const gunRotationSpeed = degToRad(characteristics.gunTraverseSpeed);
const mockTank = useLoader(GLTFLoader, asset(`3d/tanks/models/12305.glb`));
const texture = useLoader(TextureLoader, imgur('C28Z8nU'));
const path = new Vector3();
const direction = new Vector3();
texture.anisotropy = 2;
useFrame(({ camera }) => {
@@ -136,16 +139,16 @@ export function SceneProps() {
);
let length: number;
let direction: Vector3;
if (cameraIntersections.length === 0) {
length = FAR_DISTANCE;
direction = new Vector3(0, 0, -1).applyQuaternion(camera.quaternion);
direction.set(0, 0, -1).applyQuaternion(camera.quaternion);
aimTarget.copy(shellOrigin).addScaledVector(direction, length);
} else {
const target = cameraIntersections[0].point;
const path = target.clone().sub(shellOrigin);
aimTarget.copy(cameraIntersections[0].point);
path.copy(aimTarget).sub(shellOrigin);
length = path.length();
direction = path.clone().normalize();
direction.copy(path).normalize();
}
const deltaT = clock.elapsedTime - lastTime;