fix: don't update armor highlighting on protagonist shell switch

This commit is contained in:
TrèsAbhi committed 2024-02-22 13:07:13 -06:00
1 parent d81eddba44
commit da767213cb
3 files changed
+39 -30

No files matched your search

+1
View File
@@ -16,3 +16,4 @@ servers.csv
tsconfig.tsbuildinfo tsconfig.tsbuildinfo
temp/ temp/
/.yarn /.yarn
/.VSCodeCounter
@@ -80,16 +80,6 @@ export function ArmorHighlighting() {
turretContainer.current?.position.copy(turretPosition); turretContainer.current?.position.copy(turretPosition);
turretContainer.current?.rotation.copy(turretRotation); turretContainer.current?.rotation.copy(turretRotation);
} }
handleModelTransform(useTankopediaTemporary.getState().model.pose);
modelTransformEvent.on(handleModelTransform);
return () => {
modelTransformEvent.off(handleModelTransform);
};
});
useEffect(() => {
const unsubscribe = useTankopediaTemporary.subscribe( const unsubscribe = useTankopediaTemporary.subscribe(
(state) => state.mode, (state) => state.mode,
(mode) => { (mode) => {
@@ -97,8 +87,14 @@ export function ArmorHighlighting() {
}, },
); );
return unsubscribe; handleModelTransform(useTankopediaTemporary.getState().model.pose);
}); modelTransformEvent.on(handleModelTransform);
return () => {
modelTransformEvent.off(handleModelTransform);
unsubscribe();
};
}, []);
const armorGltf = useArmor(protagonist.tank.id); const armorGltf = useArmor(protagonist.tank.id);
const armorNodes = Object.values(armorGltf.nodes); const armorNodes = Object.values(armorGltf.nodes);
@@ -1,5 +1,5 @@
import { MeshProps, useFrame, useThree } from '@react-three/fiber'; import { MeshProps, useFrame, useThree } from '@react-three/fiber';
import { useEffect, useRef } from 'react'; import { memo, useEffect, useRef } from 'react';
import { import {
IUniform, IUniform,
Mesh, Mesh,
@@ -39,11 +39,8 @@ export type ArmorMeshUserData = {
thickness: number; thickness: number;
}; };
export function ArmorMesh({ export const ArmorMesh = memo<ArmorMeshProps>(
thickness, ({ thickness, maxThickness, ...props }) => {
maxThickness,
...props
}: ArmorMeshProps) {
const camera = useThree((state) => state.camera); const camera = useThree((state) => state.camera);
const initialShell = useDuel.getState().antagonist!.shell; const initialShell = useDuel.getState().antagonist!.shell;
const initialTankopedia = useTankopediaPersistent.getState(); const initialTankopedia = useTankopediaPersistent.getState();
@@ -77,6 +74,7 @@ export function ArmorMesh({
function updateShellProperties() { function updateShellProperties() {
const shell = useDuel.getState().antagonist!.shell; const shell = useDuel.getState().antagonist!.shell;
if (material.current) { if (material.current) {
material.current.uniforms.canRicochet.value = canRicochet(shell.type); material.current.uniforms.canRicochet.value = canRicochet(shell.type);
material.current.uniforms.isExplosive.value = isExplosive(shell.type); material.current.uniforms.isExplosive.value = isExplosive(shell.type);
@@ -106,7 +104,8 @@ export function ArmorMesh({
(state) => state.model.visual.greenPenetration, (state) => state.model.visual.greenPenetration,
(greenPenetration) => { (greenPenetration) => {
if (material.current) { if (material.current) {
material.current.uniforms.greenPenetration.value = greenPenetration; material.current.uniforms.greenPenetration.value =
greenPenetration;
} }
}, },
), ),
@@ -124,7 +123,7 @@ export function ArmorMesh({
return () => { return () => {
unsubscribes.forEach((unsubscribe) => unsubscribe()); unsubscribes.forEach((unsubscribe) => unsubscribe());
}; };
}); }, []);
useFrame(({ gl, camera }) => { useFrame(({ gl, camera }) => {
if (material.current) { if (material.current) {
@@ -169,13 +168,19 @@ export function ArmorMesh({
); );
surfaceNormal surfaceNormal
.copy(event.normal!) .copy(event.normal!)
.applyQuaternion(event.object.getWorldQuaternion(new Quaternion())); .applyQuaternion(
event.object.getWorldQuaternion(new Quaternion()),
);
const angle = Math.acos(surfaceNormal.dot(shellNormal)); const angle = Math.acos(surfaceNormal.dot(shellNormal));
const shell = useDuel.getState().antagonist!.shell; const shell = useDuel.getState().antagonist!.shell;
const hasCalibratedShells = await hasEquipment(103); const hasCalibratedShells = await hasEquipment(103);
const resolvedPenetration = const resolvedPenetration =
resolveNearPenetration(shell.penetration) * resolveNearPenetration(shell.penetration) *
(hasCalibratedShells ? (isExplosive(shell.type) ? 1.1 : 1.05) : 1); (hasCalibratedShells
? isExplosive(shell.type)
? 1.1
: 1.05
: 1);
const indexedObjects = new Set<ArmorMeshUserData['type']>(); const indexedObjects = new Set<ArmorMeshUserData['type']>();
const intersections = event.intersections const intersections = event.intersections
.filter(({ object }) => Boolean(object.userData.type)) .filter(({ object }) => Boolean(object.userData.type))
@@ -199,7 +204,8 @@ export function ArmorMesh({
({ object }) => object.userData.type === 'coreArmor', ({ object }) => object.userData.type === 'coreArmor',
) + 1, ) + 1,
); );
const coreArmorMesh = intersectionsTillFirstCoreArmor.at(-1)!.object; const coreArmorMesh =
intersectionsTillFirstCoreArmor.at(-1)!.object;
const hasEnhancedArmor = await hasEquipment(110); const hasEnhancedArmor = await hasEquipment(110);
const thicknessCoefficient = hasEnhancedArmor ? 1.04 : 1; const thicknessCoefficient = hasEnhancedArmor ? 1.04 : 1;
@@ -228,7 +234,8 @@ export function ArmorMesh({
const threeCalibersRule = const threeCalibersRule =
shell.caliber > shell.caliber >
3 * 3 *
(event.object.userData.thickness * thicknessCoefficient); (event.object.userData.thickness *
thicknessCoefficient);
if ( if (
index === 0 && index === 0 &&
@@ -242,7 +249,8 @@ export function ArmorMesh({
const twoCalibersRule = const twoCalibersRule =
shell.caliber > shell.caliber >
2 * 2 *
(event.object.userData.thickness * thicknessCoefficient); (event.object.userData.thickness *
thicknessCoefficient);
const normalization = const normalization =
twoCalibersRule && event.object.userData.thickness > 0 twoCalibersRule && event.object.userData.thickness > 0
? ((shell.normalization ?? 0) * 1.4 * shell.caliber) / ? ((shell.normalization ?? 0) * 1.4 * shell.caliber) /
@@ -318,7 +326,9 @@ export function ArmorMesh({
.clone() .clone()
.multiplyScalar( .multiplyScalar(
2 * 2 *
surfaceNormal.dot(shellNormal.clone().multiplyScalar(-1)), surfaceNormal.dot(
shellNormal.clone().multiplyScalar(-1),
),
), ),
); );
raycaster.set(event.point, bounceNormal); raycaster.set(event.point, bounceNormal);
@@ -372,7 +382,9 @@ export function ArmorMesh({
}); });
ricochet = { ricochet = {
point: intersectionsTillFirstCoreArmor.at(-1)!.point.toArray(), point: intersectionsTillFirstCoreArmor
.at(-1)!
.point.toArray(),
distance: intersectionsTillFirstCoreArmor.at(-1)!.distance, distance: intersectionsTillFirstCoreArmor.at(-1)!.distance,
penetration: remainingPenetration > 0, penetration: remainingPenetration > 0,
}; };
@@ -396,7 +408,6 @@ export function ArmorMesh({
}); });
}} }}
> >
{true && (
<shaderMaterial <shaderMaterial
wireframe={wireframe} wireframe={wireframe}
ref={material} ref={material}
@@ -437,8 +448,9 @@ export function ArmorMesh({
wireframe: { value: wireframe }, wireframe: { value: wireframe },
}} }}
/> />
)}
</mesh> </mesh>
</> </>
); );
} },
() => true,
);