feat: generalize wrapper

This commit is contained in:
TrèsAbhi committed 2024-07-24 20:46:42 -05:00
1 parent 85166a2614
commit e88fdd861f
4 files changed
+87 -101

No files matched your search

@@ -1,6 +1,7 @@
import { ThreeEvent, useThree } from '@react-three/fiber';
import { memo, useRef } from 'react';
import { Group, Mesh, MeshStandardMaterial, Vector2 } from 'three';
import { ModelTankWrapper } from '../../../../../../../components/Armor/components/ModelTankWrapper';
import { applyPitchYawLimits } from '../../../../../../../core/blitz/applyPitchYawLimits';
import { hasEquipment } from '../../../../../../../core/blitzkit/hasEquipment';
import { jsxTree } from '../../../../../../../core/blitzkit/jsxTree';
@@ -36,7 +37,7 @@ export const TankModel = memo(() => {
const nodes = Object.values(gltf.nodes);
return (
<group ref={hullContainer} rotation={[-Math.PI / 2, 0, 0]}>
<ModelTankWrapper ref={hullContainer}>
{nodes.map((node) => {
const isHull = node.name === 'hull';
const isWheel = node.name.startsWith('chassis_wheel_');
@@ -260,6 +261,6 @@ export const TankModel = memo(() => {
})}
</group>
</group>
</group>
</ModelTankWrapper>
);
});
@@ -9,6 +9,7 @@ import { useTankTransform } from '../../../hooks/useTankTransform';
import * as Duel from '../../../stores/duel';
import * as TankopediaPersistent from '../../../stores/tankopediaPersistent';
import { CoreArmorSceneComponent } from './CoreArmorSceneComponent';
import { ModelTankWrapper } from './ModelTankWrapper';
export const CoreArmorScene = memo(() => {
const wrapper = useRef<Group>(null);
@@ -47,9 +48,8 @@ export const CoreArmorScene = memo(() => {
const gunOrigin = correctZYTuple(turretModelDefinition.gunOrigin);
return (
<group
<ModelTankWrapper
ref={wrapper}
rotation={[-Math.PI / 2, 0, 0]}
visible={initialTankopediaState.mode === 'armor'}
>
<group position={hullOrigin}>
@@ -75,58 +75,55 @@ export const CoreArmorScene = memo(() => {
</group>
<group ref={turretContainer}>
<group position={hullOrigin}>
{armorNodes.map((node) => {
const isCurrentTurret = node.name.startsWith(
`turret_${turretModelDefinition.model.toString().padStart(2, '0')}`,
);
const isVisible = isCurrentTurret;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
turretModelDefinition.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>
);
})}
<group ref={gunContainer}>
{armorNodes.map((node) => {
const isCurrentTurret = node.name.startsWith(
`turret_${turretModelDefinition.model.toString().padStart(2, '0')}`,
const isCurrentGun = node.name.startsWith(
`gun_${gunModelDefinition.model.toString().padStart(2, '0')}`,
);
const isVisible = isCurrentTurret;
const isVisible = isCurrentGun;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
turretModelDefinition.armor,
gunModelDefinition.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
key={node.uuid}
position={turretOrigin.clone().add(gunOrigin)}
>
<CoreArmorSceneComponent 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>
</ModelTankWrapper>
);
});
@@ -0,0 +1,7 @@
import { GroupProps } from '@react-three/fiber';
import { forwardRef } from 'react';
import { Group } from 'three';
export const ModelTankWrapper = forwardRef<Group, GroupProps>((props, ref) => {
return <group rotation={[-Math.PI / 2, 0, 0]} ref={ref} {...props} />;
});
@@ -1,4 +1,4 @@
import { memo, useEffect, useRef } from 'react';
import { memo, useRef } from 'react';
import { Group, Plane, Scene, Vector3 } from 'three';
import { correctZYTuple } from '../../../core/blitz/correctZYTuple';
import { nameToArmorId } from '../../../core/blitzkit/nameToArmorId';
@@ -8,7 +8,7 @@ import { useModel } from '../../../hooks/useModel';
import { useModelDefinitions } from '../../../hooks/useModelDefinitions';
import { useTankTransform } from '../../../hooks/useTankTransform';
import * as Duel from '../../../stores/duel';
import * as TankopediaPersistent from '../../../stores/tankopediaPersistent';
import { ModelTankWrapper } from './ModelTankWrapper';
import { SpacedArmorSceneComponent } from './SpacedArmorSceneComponent';
export enum ArmorType {
@@ -26,8 +26,6 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
const modelDefinitions = useModelDefinitions();
const turretContainer = useRef<Group>(null);
const gunContainer = useRef<Group>(null);
const tankopediaPersistentStore = TankopediaPersistent.useStore();
const initialTankopediaState = tankopediaPersistentStore.getState();
const protagonist = Duel.use((draft) => draft.protagonist);
const tank = Duel.use((state) => state.protagonist.tank);
const track = Duel.use((state) => state.protagonist.track);
@@ -51,23 +49,8 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
useTankTransform(protagonist, turretContainer, gunContainer);
useEffect(() => {
const unsubscribe = tankopediaPersistentStore.subscribe(
(state) => state.mode,
(mode) => {
if (wrapper.current) wrapper.current.visible = mode === 'armor';
},
);
return unsubscribe;
});
return (
<group
ref={wrapper}
rotation={[-Math.PI / 2, 0, 0]}
visible={initialTankopediaState.mode === 'armor'}
>
<ModelTankWrapper ref={wrapper}>
<group position={hullOrigin}>
{armorNodes.map((node) => {
const isHull = node.name.startsWith('hull_');
@@ -91,6 +74,7 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
);
})}
</group>
{modelNodes.map((node) => {
const isWheel = node.name.startsWith('chassis_wheel_');
const isTrack = node.name.startsWith('chassis_track_');
@@ -111,25 +95,53 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
})}
<group ref={turretContainer}>
<group position={hullOrigin}>
{armorNodes.map((node) => {
const isCurrentTurret = node.name.startsWith(
`turret_${turretModelDefinition.model.toString().padStart(2, '0')}`,
);
const isVisible = isCurrentTurret;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
turretModelDefinition.armor,
armorId,
);
if (!isVisible || thickness === undefined) return null;
return (
<group key={node.uuid} position={turretOrigin}>
<SpacedArmorSceneComponent
scene={scene}
key={node.uuid}
type={spaced ? ArmorType.Spaced : ArmorType.Core}
thickness={thickness}
node={node}
/>
</group>
);
})}
<group ref={gunContainer}>
{armorNodes.map((node) => {
const isCurrentTurret = node.name.startsWith(
`turret_${turretModelDefinition.model.toString().padStart(2, '0')}`,
const isCurrentGun = node.name.startsWith(
`gun_${gunModelDefinition.model.toString().padStart(2, '0')}`,
);
const isVisible = isCurrentTurret;
const isVisible = isCurrentGun;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
turretModelDefinition.armor,
gunModelDefinition.armor,
armorId,
);
if (!isVisible || thickness === undefined) return null;
return (
<group key={node.uuid} position={turretOrigin}>
<group
key={node.uuid}
position={turretOrigin.clone().add(gunOrigin)}
>
<SpacedArmorSceneComponent
scene={scene}
key={node.uuid}
type={spaced ? ArmorType.Spaced : ArmorType.Core}
thickness={thickness}
node={node}
@@ -137,37 +149,6 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
</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 || thickness === undefined) return null;
return (
<group
key={node.uuid}
position={turretOrigin.clone().add(gunOrigin)}
>
<SpacedArmorSceneComponent
scene={scene}
type={spaced ? ArmorType.Spaced : ArmorType.Core}
thickness={thickness}
node={node}
/>
</group>
);
})}
</group>
{modelNodes.map((node) => {
const gunString = `gun_${gunModelDefinition.model.toString().padStart(2, '0')}`;
@@ -196,6 +177,6 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
})}
</group>
</group>
</group>
</ModelTankWrapper>
);
});