fix: render tracer over armor

This commit is contained in:
TrèsAbhi committed 2024-05-27 20:57:04 -05:00
1 parent 2b34863b53
commit 00cee28e08
3 files changed
+100 -63

No files matched your search

@@ -2,7 +2,6 @@ import { PerspectiveCamera } from '@react-three/drei';
import { Canvas } from '@react-three/fiber'; import { Canvas } from '@react-three/fiber';
import { Suspense, use, useEffect, useRef } from 'react'; import { Suspense, use, useEffect, useRef } from 'react';
import { Armor } from '../../../../../../components/Armor'; import { Armor } from '../../../../../../components/Armor';
import { ShotDisplay } from '../../../../../../components/Armor/components/ShotDisplay';
import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits'; import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits';
import { modelDefinitions } from '../../../../../../core/blitzkit/modelDefinitions'; import { modelDefinitions } from '../../../../../../core/blitzkit/modelDefinitions';
import { modelTransformEvent } from '../../../../../../core/blitzkit/modelTransform'; import { modelTransformEvent } from '../../../../../../core/blitzkit/modelTransform';
@@ -143,7 +142,6 @@ export function TankSandbox() {
<Lighting /> <Lighting />
<TankModel /> <TankModel />
<Armor /> <Armor />
<ShotDisplay />
</Suspense> </Suspense>
</Canvas> </Canvas>
); );
@@ -13,6 +13,7 @@ import { useModelDefinitions } from '../../../hooks/useModelDefinitions';
import { useDuel } from '../../../stores/duel'; import { useDuel } from '../../../stores/duel';
import { useTankopediaPersistent } from '../../../stores/tankopedia'; import { useTankopediaPersistent } from '../../../stores/tankopedia';
import { CoreArmorSceneComponent } from './CoreArmorSceneComponent'; import { CoreArmorSceneComponent } from './CoreArmorSceneComponent';
import { ShotDisplay } from './ShotDisplay';
export const CoreArmorScene = memo(() => { export const CoreArmorScene = memo(() => {
const wrapper = useRef<Group>(null); const wrapper = useRef<Group>(null);
@@ -135,86 +136,94 @@ export const CoreArmorScene = memo(() => {
).applyAxisAngle(I_HAT, Math.PI / 2); ).applyAxisAngle(I_HAT, Math.PI / 2);
return ( return (
<group <>
ref={wrapper} <ShotDisplay />
rotation={[-Math.PI / 2, 0, 0]}
visible={initialTankopediaState.mode === 'armor'}
>
<group position={hullOrigin}>
{armorNodes.map((node) => {
const isHull = node.name.startsWith('hull_');
const isVisible = isHull;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
tankModelDefinition.armor,
armorId,
);
if (!isVisible || spaced || thickness === undefined) return null; <group
ref={wrapper}
return ( rotation={[-Math.PI / 2, 0, 0]}
<CoreArmorSceneComponent visible={initialTankopediaState.mode === 'armor'}
key={node.uuid} >
thickness={thickness}
node={node}
/>
);
})}
</group>
<group ref={turretContainer}>
<group position={hullOrigin}> <group position={hullOrigin}>
{armorNodes.map((node) => { {armorNodes.map((node) => {
const isCurrentTurret = node.name.startsWith( const isHull = node.name.startsWith('hull_');
`turret_${turretModelDefinition.model.toString().padStart(2, '0')}`, const isVisible = isHull;
);
const isVisible = isCurrentTurret;
const armorId = nameToArmorId(node.name); const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor( const { spaced, thickness } = resolveArmor(
turretModelDefinition.armor, tankModelDefinition.armor,
armorId, armorId,
); );
if (!isVisible || spaced || thickness === undefined) return null; if (!isVisible || spaced || thickness === undefined) return null;
return ( return (
<group key={node.uuid} position={turretOrigin}> <CoreArmorSceneComponent
<CoreArmorSceneComponent key={node.uuid}
key={node.uuid} thickness={thickness}
thickness={thickness} node={node}
node={node} />
/>
</group>
); );
})} })}
</group> </group>
<group ref={gunContainer}>
<group ref={turretContainer}>
<group position={hullOrigin}> <group position={hullOrigin}>
{armorNodes.map((node) => { {armorNodes.map((node) => {
const isCurrentGun = node.name.startsWith( const isCurrentTurret = node.name.startsWith(
`gun_${gunModelDefinition.model.toString().padStart(2, '0')}`, `turret_${turretModelDefinition.model.toString().padStart(2, '0')}`,
); );
const isVisible = isCurrentGun; const isVisible = isCurrentTurret;
const armorId = nameToArmorId(node.name); const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor( const { spaced, thickness } = resolveArmor(
gunModelDefinition.armor, turretModelDefinition.armor,
armorId, armorId,
); );
if (!isVisible || spaced || thickness === undefined) return null; if (!isVisible || spaced || thickness === undefined) return null;
return ( return (
<group <group key={node.uuid} position={turretOrigin}>
key={node.uuid} <CoreArmorSceneComponent
position={turretOrigin.clone().add(gunOrigin)} key={node.uuid}
> thickness={thickness}
<CoreArmorSceneComponent thickness={thickness} node={node} /> node={node}
/>
</group> </group>
); );
})} })}
</group> </group>
<group ref={gunContainer}>
<group position={hullOrigin}>
{armorNodes.map((node) => {
const isCurrentGun = node.name.startsWith(
`gun_${gunModelDefinition.model.toString().padStart(2, '0')}`,
);
const isVisible = isCurrentGun;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
gunModelDefinition.armor,
armorId,
);
if (!isVisible || spaced || thickness === undefined)
return null;
return (
<group
key={node.uuid}
position={turretOrigin.clone().add(gunOrigin)}
>
<CoreArmorSceneComponent
thickness={thickness}
node={node}
/>
</group>
);
})}
</group>
</group>
</group> </group>
</group> </group>
</group> </>
); );
}); });
+41 -11
View File
@@ -164,6 +164,10 @@ export function ShotDisplay() {
) )
: LENGTH_INFINITY; : LENGTH_INFINITY;
const inLast = shot.in.layers.findLast((layer) => layer.type !== null)!; const inLast = shot.in.layers.findLast((layer) => layer.type !== null)!;
const outTitleColor = shot.out
? shotStatusColors[shot.out.status]
: undefined;
const inTitleColor = shotStatusColors[shot.in.status];
return ( return (
<group> <group>
@@ -177,7 +181,7 @@ export function ShotDisplay() {
<Card ml="9" style={{ width: 300 }}> <Card ml="9" style={{ width: 300 }}>
<Flex direction="column" gap="2"> <Flex direction="column" gap="2">
<Flex direction="column" gap="1"> <Flex direction="column" gap="1">
<Text color={shotStatusColors[shot.in.status]} weight="bold"> <Text color={inTitleColor} weight="bold">
{shot.in.status !== 'blocked' && {shot.in.status !== 'blocked' &&
shot.in.status !== 'ricochet' && ( shot.in.status !== 'ricochet' && (
<> <>
@@ -224,10 +228,24 @@ export function ShotDisplay() {
{shot.out && shot.out.layers.length > 0 && ( {shot.out && shot.out.layers.length > 0 && (
<> <>
<Inset side="x"> <Inset side="x">
<Separator size="4" /> <Flex align="center" gap="2">
<Separator
style={{
flex: 1,
}}
/>
<Text size="1" color="gray">
ricochet (-25% penetration)
</Text>
<Separator
style={{
flex: 1,
}}
/>
</Flex>
</Inset> </Inset>
<Text color={shotStatusColors[shot.out.status]} weight="bold"> <Text color={outTitleColor} weight="bold">
{shot.out.status !== 'blocked' && {shot.out.status !== 'blocked' &&
shot.out.status !== 'ricochet' && ( shot.out.status !== 'ricochet' && (
<> <>
@@ -309,18 +327,22 @@ export function ShotDisplay() {
new Quaternion().setFromUnitVectors(J_HAT, shot.in.surfaceNormal), new Quaternion().setFromUnitVectors(J_HAT, shot.in.surfaceNormal),
)} )}
> >
<mesh position={[0, inLength / 2, 0]}> <mesh position={[0, inLength / 2, 0]} renderOrder={2}>
<cylinderGeometry <cylinderGeometry
args={[TRACER_THIN / 2, TRACER_THIN / 2, inLength]} args={[TRACER_THIN / 2, TRACER_THIN / 2, inLength]}
/> />
<meshBasicMaterial depthTest={false} /> <meshBasicMaterial depthTest={false} transparent />
</mesh> </mesh>
<mesh ref={inTracer} position={[0, inLength / 2, 0]}> <mesh ref={inTracer} position={[0, inLength / 2, 0]} renderOrder={3}>
<cylinderGeometry <cylinderGeometry
args={[TRACER_THICK / 2, TRACER_THICK / 2, inLength]} args={[TRACER_THICK / 2, TRACER_THICK / 2, inLength]}
/> />
<meshBasicMaterial color="red" /> <meshBasicMaterial
color={inTitleColor}
depthTest={false}
transparent
/>
</mesh> </mesh>
</group> </group>
@@ -334,18 +356,26 @@ export function ShotDisplay() {
), ),
)} )}
> >
<mesh position={[0, outLength / 2, 0]}> <mesh position={[0, outLength / 2, 0]} renderOrder={2}>
<cylinderGeometry <cylinderGeometry
args={[TRACER_THIN / 2, TRACER_THIN / 2, outLength]} args={[TRACER_THIN / 2, TRACER_THIN / 2, outLength]}
/> />
<meshBasicMaterial depthTest={false} /> <meshBasicMaterial depthTest={false} transparent />
</mesh> </mesh>
<mesh ref={outTracer} position={[0, outLength / 2, 0]}> <mesh
ref={outTracer}
position={[0, outLength / 2, 0]}
renderOrder={3}
>
<cylinderGeometry <cylinderGeometry
args={[TRACER_THICK / 2, TRACER_THICK / 2, outLength]} args={[TRACER_THICK / 2, TRACER_THICK / 2, outLength]}
/> />
<meshBasicMaterial color="yellow" /> <meshBasicMaterial
color={outTitleColor}
depthTest={false}
transparent
/>
</mesh> </mesh>
</group> </group>
)} )}