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