diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Control.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Control.tsx index 8ae5711a4..260f958ec 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Control.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Control.tsx @@ -1,7 +1,7 @@ import { OrbitControls } from '@react-three/drei'; import { invalidate, useThree } from '@react-three/fiber'; import { useEffect, useRef, useState } from 'react'; -import { AxesHelper, PerspectiveCamera, Vector2, Vector3 } from 'three'; +import { PerspectiveCamera, Vector3 } from 'three'; import { OrbitControls as OrbitControlsClass } from 'three-stdlib'; import { degToRad } from 'three/src/math/MathUtils.js'; import { awaitableModelDefinitions } from '../../../../../../core/awaitables/modelDefinitions'; @@ -20,12 +20,11 @@ const poseDistances: Record = { const modelDefinitions = await awaitableModelDefinitions; -const ARCADE_MODE_DISTANCE = 16; +const ARCADE_MODE_DISTANCE = 12; const ARCADE_MODE_ANGLE = Math.PI / 8; export const ARCADE_MODE_FOV = 54; export const INSPECT_MODE_FOV = 25; - export function Controls() { const display = TankopediaEphemeral.use((state) => state.display); const duelStore = Duel.useStore(); @@ -92,13 +91,13 @@ export function Controls() { ); orbitControls.current.target.set(0, gunHeight + 3, 0); orbitControls.current.enablePan = false; - orbitControls.current.enableZoom = false; + // orbitControls.current.enableZoom = false; } else { (camera as PerspectiveCamera).fov = INSPECT_MODE_FOV; camera.position.set(...initialPosition); orbitControls.current.target.set(0, gunHeight / 2, 0); orbitControls.current.enablePan = true; - orbitControls.current.enableZoom = true; + // orbitControls.current.enableZoom = true; } camera.updateProjectionMatrix(); diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/SceneProps.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/SceneProps.tsx index c9939c48e..4179280ea 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/SceneProps.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/SceneProps.tsx @@ -9,6 +9,7 @@ import { Vector2, Vector3, } from 'three'; +import { degToRad } from 'three/src/math/MathUtils.js'; import { awaitableModelDefinitions } from '../../../../../../core/awaitables/modelDefinitions'; import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits'; import { modelTransformEvent } from '../../../../../../core/blitzkit/modelTransform'; @@ -26,6 +27,11 @@ export function SceneProps() { (state) => state.showGrid && !state.showEnvironment, ); const texture = useLoader(TextureLoader, 'https://i.imgur.com/C28Z8nU.png'); + + texture.anisotropy = 2; + + let lastPitch = Duel.use((state) => state.protagonist.pitch); + let lastYaw = Duel.use((state) => state.protagonist.yaw); const material = useRef(null); const display = TankopediaEphemeral.use((state) => state.display); const playground = useRef(null); @@ -63,6 +69,10 @@ export function SceneProps() { protagonistTurretModelDefinition.gun_origin.y, 0, ); + const turretRotationSpeed = degToRad(protagonistTurret.traverse_speed); + const gunRotationSpeed = degToRad( + protagonistGun.gun_type!.value.base.rotation_speed, + ); const shellOrigin = new Vector3() .add(protagonistHullOrigin) .add(protagonistTurretOrigin) @@ -73,7 +83,7 @@ export function SceneProps() { material.current.opacity = clamp(0.5 * camera.position.y, 0, 1); }); - texture.anisotropy = 2; + let lastTime = 0; useFrame(({ raycaster, camera, clock }) => { if ( @@ -108,13 +118,29 @@ export function SceneProps() { shellPathHelper.current.setDirection(direction); shellPathHelper.current.setLength(length); + const deltaT = clock.elapsedTime - lastTime; + lastTime = clock.elapsedTime; + const desiredPitch = Math.asin(direction.y); + const desiredYaw = Math.atan2(-direction.x, -direction.z); + const deltaPitch = desiredPitch - lastPitch; + const deltaYaw = desiredYaw - lastYaw; + const maxDeltaPitch = + Math.sign(deltaPitch) * + Math.min(gunRotationSpeed * deltaT, Math.abs(deltaPitch)); + const maxDeltaYaw = + Math.sign(deltaYaw) * + Math.min(turretRotationSpeed * deltaT, Math.abs(deltaYaw)); + const [pitch, yaw] = applyPitchYawLimits( - Math.asin(direction.y), - Math.atan2(-direction.x, -direction.z), + lastPitch + maxDeltaPitch, + lastYaw + maxDeltaYaw, protagonistGunModelDefinition.pitch, + protagonistTurretModelDefinition.yaw, ); modelTransformEvent.emit({ pitch, yaw }); + lastPitch = pitch; + lastYaw = yaw; }); return (