feat: turret moment

This commit is contained in:
tresabhi committed 2024-12-01 22:48:18 -06:00
1 parent 7f9a54ef85
commit e5ddbc7297
1 file changed
+72 -5
@@ -2,20 +2,28 @@ import { useFrame, useLoader } from '@react-three/fiber';
import { clamp } from 'lodash-es';
import { useRef } from 'react';
import {
ArrowHelper,
AxesHelper,
Group,
MeshStandardMaterial,
TextureLoader,
Vector2,
Vector3,
} from 'three';
import { awaitableModelDefinitions } from '../../../../../../core/awaitables/modelDefinitions';
import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits';
import { modelTransformEvent } from '../../../../../../core/blitzkit/modelTransform';
import { Duel } from '../../../../../../stores/duel';
import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral';
import { TankopediaPersistent } from '../../../../../../stores/tankopediaPersistent';
import { TankopediaDisplay } from '../../../../../../stores/tankopediaPersistent/constants';
const emptyVector = new Vector2();
const modelDefinitions = await awaitableModelDefinitions;
export function SceneProps() {
const helper = useRef<AxesHelper>(null);
const shellTargetHelper = useRef<AxesHelper>(null);
const shellPathHelper = useRef<ArrowHelper>(null);
const show = TankopediaPersistent.use(
(state) => state.showGrid && !state.showEnvironment,
);
@@ -23,6 +31,44 @@ export function SceneProps() {
const material = useRef<MeshStandardMaterial>(null);
const display = TankopediaEphemeral.use((state) => state.display);
const playground = useRef<Group>(null);
const protagonistTurret = Duel.use((state) => state.protagonist.turret);
const protagonistTrack = Duel.use((state) => state.protagonist.track);
const protagonistTank = Duel.use((state) => state.protagonist.tank);
const protagonistGun = Duel.use((state) => state.protagonist.gun);
const protagonistModelDefinition =
modelDefinitions.models[protagonistTank.id];
const protagonistTrackModelDefinition =
modelDefinitions.models[protagonistTank.id].tracks[protagonistTrack.id];
const protagonistGunModelDefinition =
protagonistModelDefinition.turrets[protagonistTurret.id].guns[
protagonistGun.gun_type!.value.base.id
];
const protagonistTurretModelDefinition =
protagonistModelDefinition.turrets[protagonistTurret.id];
const protagonistHullOrigin = new Vector3(
protagonistTrackModelDefinition.origin.x,
protagonistTrackModelDefinition.origin.y,
-protagonistTrackModelDefinition.origin.z,
);
const protagonistTurretOrigin = new Vector3(
protagonistModelDefinition.turret_origin.x,
protagonistModelDefinition.turret_origin.y,
-protagonistModelDefinition.turret_origin.z,
);
const protagonistGunOrigin = new Vector3(
protagonistTurretModelDefinition.gun_origin.x,
protagonistTurretModelDefinition.gun_origin.y,
-protagonistTurretModelDefinition.gun_origin.z,
);
const protagonistGunOriginOnlyY = new Vector3(
0,
protagonistTurretModelDefinition.gun_origin.y,
0,
);
const shellOrigin = new Vector3()
.add(protagonistHullOrigin)
.add(protagonistTurretOrigin)
.add(protagonistGunOriginOnlyY);
useFrame(({ camera }) => {
if (!material.current) return;
@@ -31,11 +77,12 @@ export function SceneProps() {
texture.anisotropy = 2;
useFrame(({ raycaster, scene, camera }) => {
useFrame(({ raycaster, camera, clock }) => {
if (
display !== TankopediaDisplay.ShootingRange ||
!playground.current ||
!helper.current
!shellTargetHelper.current ||
!shellPathHelper.current
) {
return;
}
@@ -49,7 +96,21 @@ export function SceneProps() {
if (intersections.length === 0) return;
helper.current.position.copy(intersections[0].point);
const target = intersections[0].point;
const path = target.clone().sub(shellOrigin);
const direction = path.clone().normalize();
shellTargetHelper.current.position.copy(intersections[0].point);
shellPathHelper.current.setDirection(direction);
shellPathHelper.current.setLength(path.length());
const [pitch, yaw] = applyPitchYawLimits(
Math.asin(direction.y),
Math.atan2(-direction.x, -direction.z),
protagonistGunModelDefinition.pitch,
);
modelTransformEvent.emit({ pitch, yaw });
});
return (
@@ -63,7 +124,8 @@ export function SceneProps() {
{display === TankopediaDisplay.ShootingRange && (
<>
<axesHelper ref={helper} />
<axesHelper ref={shellTargetHelper} />
<arrowHelper ref={shellPathHelper} position={shellOrigin} />
<group ref={playground}>
<mesh rotation={[-Math.PI / 2, 0, 0]} receiveShadow>
@@ -80,6 +142,11 @@ export function SceneProps() {
<boxGeometry args={[1, 3, 1]} />
<meshStandardMaterial color={0xff8040} />
</mesh>
<mesh position={shellOrigin}>
<sphereGeometry args={[0.1, 32, 32]} />
<meshStandardMaterial depthTest={false} />
</mesh>
</group>
</>
)}