feat: separate target circle

This commit is contained in:
tresabhi committed 2024-12-02 18:39:27 -06:00
1 parent 26d3bdaac7
commit 20f54a39d6
2 files changed
+62 -50

No files matched your search

@@ -0,0 +1,37 @@
import { imgur } from '@blitzkit/core';
import { Box, type BoxProps } from '@radix-ui/themes';
import { forwardRef } from 'react';
import { Var } from '../../../../../../../../core/radix/var';
export const TargetCircle = forwardRef<HTMLDivElement, BoxProps>(
({ style, ...props }, ref) => {
return (
<Box
ref={ref}
width="10em"
height="10em"
style={{
borderRadius: '50%',
border: `0.125rem solid ${Var('green-9')}`,
...style,
}}
position="relative"
{...props}
>
<Box
width="1rem"
height="1rem"
position="absolute"
top="50%"
left="50%"
style={{
backgroundImage: `url(${imgur('kU9Xejd')})`,
backgroundSize: 'contain',
transform: 'translateX(-50%) scale(90%)',
borderRadius: '50%',
}}
/>
</Box>
);
},
);
@@ -1,5 +1,4 @@
import { asset, I_HAT, imgur, J_HAT } from '@blitzkit/core'; import { asset, I_HAT, imgur, J_HAT } from '@blitzkit/core';
import { Box } from '@radix-ui/themes';
import { Html } from '@react-three/drei'; import { Html } from '@react-three/drei';
import { useFrame, useLoader } from '@react-three/fiber'; import { useFrame, useLoader } from '@react-three/fiber';
import { clamp } from 'lodash-es'; import { clamp } from 'lodash-es';
@@ -14,17 +13,17 @@ import {
} from 'three'; } from 'three';
import { GLTFLoader } from 'three/examples/jsm/Addons.js'; import { GLTFLoader } from 'three/examples/jsm/Addons.js';
import { degToRad } from 'three/src/math/MathUtils.js'; import { degToRad } from 'three/src/math/MathUtils.js';
import { awaitableEquipmentDefinitions } from '../../../../../../core/awaitables/equipmentDefinitions'; import { awaitableEquipmentDefinitions } from '../../../../../../../core/awaitables/equipmentDefinitions';
import { awaitableModelDefinitions } from '../../../../../../core/awaitables/modelDefinitions'; import { awaitableModelDefinitions } from '../../../../../../../core/awaitables/modelDefinitions';
import { awaitableProvisionDefinitions } from '../../../../../../core/awaitables/provisionDefinitions'; import { awaitableProvisionDefinitions } from '../../../../../../../core/awaitables/provisionDefinitions';
import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits'; import { applyPitchYawLimits } from '../../../../../../../core/blitz/applyPitchYawLimits';
import { modelTransformEvent } from '../../../../../../core/blitzkit/modelTransform'; import { modelTransformEvent } from '../../../../../../../core/blitzkit/modelTransform';
import { tankCharacteristics } from '../../../../../../core/blitzkit/tankCharacteristics'; import { tankCharacteristics } from '../../../../../../../core/blitzkit/tankCharacteristics';
import { Var } from '../../../../../../core/radix/var'; import { Duel } from '../../../../../../../stores/duel';
import { Duel } from '../../../../../../stores/duel'; import { TankopediaEphemeral } from '../../../../../../../stores/tankopediaEphemeral';
import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral'; import { TankopediaPersistent } from '../../../../../../../stores/tankopediaPersistent';
import { TankopediaPersistent } from '../../../../../../stores/tankopediaPersistent'; import { TankopediaDisplay } from '../../../../../../../stores/tankopediaPersistent/constants';
import { TankopediaDisplay } from '../../../../../../stores/tankopediaPersistent/constants'; import { TargetCircle } from './components/TargetCircle';
const [modelDefinitions, equipmentDefinitions, provisionDefinitions] = const [modelDefinitions, equipmentDefinitions, provisionDefinitions] =
await Promise.all([ await Promise.all([
@@ -40,17 +39,14 @@ export function SceneProps() {
const show = TankopediaPersistent.use( const show = TankopediaPersistent.use(
(state) => state.showGrid && !state.showEnvironment, (state) => state.showGrid && !state.showEnvironment,
); );
const targetCircle = useRef<Group>(null); const targetCircleWrapper = useRef<Group>(null);
const targetCircleDots = useRef<HTMLDivElement>(null); const targetCircle = useRef<HTMLDivElement>(null);
const texture = useLoader(TextureLoader, imgur('C28Z8nU')); const material = useRef<MeshStandardMaterial>(null);
const playground = useRef<Group>(null);
texture.anisotropy = 2;
let lastPitch = Duel.use((state) => state.protagonist.pitch); let lastPitch = Duel.use((state) => state.protagonist.pitch);
let lastYaw = Duel.use((state) => state.protagonist.yaw); let lastYaw = Duel.use((state) => state.protagonist.yaw);
const material = useRef<MeshStandardMaterial>(null);
const display = TankopediaEphemeral.use((state) => state.display); const display = TankopediaEphemeral.use((state) => state.display);
const playground = useRef<Group>(null);
const turret = Duel.use((state) => state.protagonist.turret); const turret = Duel.use((state) => state.protagonist.turret);
const track = Duel.use((state) => state.protagonist.track); const track = Duel.use((state) => state.protagonist.track);
const tank = Duel.use((state) => state.protagonist.tank); const tank = Duel.use((state) => state.protagonist.tank);
@@ -110,7 +106,10 @@ export function SceneProps() {
}, },
{ equipmentDefinitions, provisionDefinitions, tankModelDefinition }, { equipmentDefinitions, provisionDefinitions, tankModelDefinition },
); );
const mockTank = useLoader(GLTFLoader, asset(`3d/tanks/models/12305.glb`)); const mockTank = useLoader(GLTFLoader, asset(`3d/tanks/models/12305.glb`));
const texture = useLoader(TextureLoader, imgur('C28Z8nU'));
texture.anisotropy = 2;
useFrame(({ camera }) => { useFrame(({ camera }) => {
if (!material.current) return; if (!material.current) return;
@@ -124,9 +123,9 @@ export function SceneProps() {
if ( if (
display !== TankopediaDisplay.ShootingRange || display !== TankopediaDisplay.ShootingRange ||
!playground.current || !playground.current ||
!targetCircle.current || !targetCircleWrapper.current ||
DEBUG_disable || DEBUG_disable ||
!targetCircleDots.current !targetCircle.current
) { ) {
return; return;
} }
@@ -196,14 +195,13 @@ export function SceneProps() {
gunTarget = gunIntersections[0].point; gunTarget = gunIntersections[0].point;
} }
targetCircle.current.position.copy(gunTarget); targetCircleWrapper.current.position.copy(gunTarget);
const distanceToTarget = gunTarget.distanceTo(shellOrigin); const distanceToTarget = gunTarget.distanceTo(shellOrigin);
const dispersionRadius = const dispersionRadius =
characteristics.dispersion * (distanceToTarget / 100); characteristics.dispersion * (distanceToTarget / 100);
const dispersionSize = 2 * dispersionRadius; const dispersionSize = 2 * dispersionRadius;
const targetDistanceFromCamera = gunTarget.distanceTo(camera.position); const targetDistanceFromCamera = gunTarget.distanceTo(camera.position);
document.title = `${targetDistanceFromCamera}`;
const angularSize = const angularSize =
2 * Math.atan(dispersionSize / (2 * targetDistanceFromCamera)); 2 * Math.atan(dispersionSize / (2 * targetDistanceFromCamera));
const verticalScreenSize = const verticalScreenSize =
@@ -212,8 +210,8 @@ export function SceneProps() {
gl.domElement.clientHeight * (angularSize / verticalScreenSize); gl.domElement.clientHeight * (angularSize / verticalScreenSize);
const targetCircleDotsSize = `${Math.max(38, screenSpaceSize)}px`; const targetCircleDotsSize = `${Math.max(38, screenSpaceSize)}px`;
targetCircleDots.current.style.width = targetCircleDotsSize; targetCircle.current.style.width = targetCircleDotsSize;
targetCircleDots.current.style.height = targetCircleDotsSize; targetCircle.current.style.height = targetCircleDotsSize;
}); });
return ( return (
@@ -227,32 +225,9 @@ export function SceneProps() {
{display === TankopediaDisplay.ShootingRange && ( {display === TankopediaDisplay.ShootingRange && (
<> <>
<group ref={targetCircle}> <group ref={targetCircleWrapper}>
<Html center occlude={false} zIndexRange={[0, 0]}> <Html center occlude={false} zIndexRange={[0, 0]}>
<Box <TargetCircle ref={targetCircle} />
ref={targetCircleDots}
width="10em"
height="10em"
style={{
borderRadius: '50%',
border: `0.125rem solid ${Var('green-9')}`,
}}
position="relative"
>
<Box
width="1rem"
height="1rem"
position="absolute"
top="50%"
left="50%"
style={{
backgroundImage: `url(${imgur('kU9Xejd')})`,
backgroundSize: 'contain',
transform: 'translateX(-50%) scale(90%)',
borderRadius: '50%',
}}
/>
</Box>
</Html> </Html>
</group> </group>