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 8f95b066c..edfc695ce 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 { PerspectiveCamera, Vector3 } from 'three'; +import { AxesHelper, PerspectiveCamera, Vector2, Vector3 } from 'three'; import { OrbitControls as OrbitControlsClass } from 'three-stdlib'; import { degToRad } from 'three/src/math/MathUtils.js'; import { awaitableModelDefinitions } from '../../../../../../core/awaitables/modelDefinitions'; @@ -22,11 +22,13 @@ const modelDefinitions = await awaitableModelDefinitions; const ARCADE_MODE_DISTANCE = 16; const ARCADE_MODE_ANGLE = Math.PI / 8; - export const ARCADE_MODE_FOV = 54; export const INSPECT_MODE_FOV = 25; +const emptyVector = new Vector2(); + export function Controls() { + const helper = useRef(null); const display = TankopediaEphemeral.use((state) => state.display); const duelStore = Duel.useStore(); const tankopediaEphemeralStore = TankopediaEphemeral.useStore(); @@ -79,6 +81,8 @@ export function Controls() { protagonistTurretOrigin.y + protagonistGunOrigin.y; const initialPosition = [-8, gunHeight + 4, -13] as const; + const raycaster = useThree((state) => state.raycaster); + const scene = useThree((state) => state.scene); useEffect(() => { if (!orbitControls.current) return; @@ -232,19 +236,39 @@ export function Controls() { }; }, []); - useEffect(() => {}, [display]); - return ( - + <> + + { + if (display !== TankopediaDisplay.ShootingRange || !helper.current) { + return; + } + + raycaster.setFromCamera(emptyVector, camera); + + const intersections = raycaster.intersectObjects( + scene.children, + true, + ); + const first = intersections.find( + (intersection) => intersection.object !== helper.current, + ); + + if (first === undefined) return; + + helper.current.position.copy(first.point); + }} + /> + ); } diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Lighting.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Lighting.tsx index 431d43b3c..d77023572 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Lighting.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Lighting.tsx @@ -34,6 +34,7 @@ export function Lighting() { {times(LIGHTS_COUNT, (index) => ( ( const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation(); const canvas = useRef(null); const hasImprovedVerticalStabilizer = useEquipment(122); - const protagonist = Duel.use((state) => state.protagonist); + const protagonistGun = Duel.use((state) => state.protagonist.gun); + const protagonistTurret = Duel.use((state) => state.protagonist.turret); const mutateDuel = Duel.useMutation(); const tankModelDefinition = useTankModelDefinition(); const turretModelDefinition = - tankModelDefinition.turrets[protagonist.turret.id]; + tankModelDefinition.turrets[protagonistTurret.id]; const gunModelDefinition = - turretModelDefinition.guns[protagonist.gun.gun_type!.value.base.id]; + turretModelDefinition.guns[protagonistGun.gun_type!.value.base.id]; const display = TankopediaEphemeral.use((state) => state.display); - const tankopediaPersistentStore = TankopediaPersistent.useStore(); const onScreen = useOnScreen(canvas); useImperativeHandle(ref, () => canvas.current!, []); @@ -141,7 +140,7 @@ export const TankSandbox = forwardRef( hasImprovedVerticalStabilizer, ); }); - }, [protagonist.gun, protagonist.turret]); + }, [protagonistGun, protagonistTurret]); useEffect(() => { if (display !== TankopediaDisplay.DynamicArmor) {