more control over model parts

This commit is contained in:
tresabhi committed 2026-06-12 20:22:02 -05:00
1 parent 8a9b02e584
commit 91ac93670f
7 files changed
+76 -28

No files matched your search

+3 -1
View File
@@ -12,7 +12,9 @@
"Lods", "Lods",
"Skia", "Skia",
"RMAO", "RMAO",
"Verts" "Verts",
"drei",
"frameloop"
], ],
"userWords": [ "userWords": [
"WOTB", "WOTB",
@@ -6,8 +6,9 @@ import { OrbitControls } from "@react-three/drei";
import { Canvas } from "@react-three/fiber"; import { Canvas } from "@react-three/fiber";
import { useProtagonist } from "../../hooks/useProtagonist"; import { useProtagonist } from "../../hooks/useProtagonist";
import { useTankChassisModel } from "../../hooks/useTankChassisModel"; import { useTankChassisModel } from "../../hooks/useTankChassisModel";
import { useTankGunModel } from "../../hooks/useTankGunModel";
import { useTankHullModel } from "../../hooks/useTankHullModel"; import { useTankHullModel } from "../../hooks/useTankHullModel";
import { useTankModel } from "../../hooks/useTankModel"; import { useTankTurretModel } from "../../hooks/useTankTurretModel";
import styles from "./index.module.css"; import styles from "./index.module.css";
interface TankopediaSandboxProps { interface TankopediaSandboxProps {
@@ -45,8 +46,8 @@ function Content({ parameters }: TankopediaSandboxProps) {
const hull = useTankHullModel(); const hull = useTankHullModel();
const chassis = useTankChassisModel(); const chassis = useTankChassisModel();
const turret = useTankModel(`/models/tanks/${tank.id}/${selectedTurret}.glb`); const turret = useTankTurretModel(parameters);
const gun = useTankModel(`/models/tanks/${tank.id}/${selectedGun}.glb`); const gun = useTankGunModel(parameters);
return ( return (
<> <>
@@ -1,25 +1,17 @@
import { Tankopedia } from "../stores/tankopedia";
import { useProtagonist } from "./useProtagonist"; import { useProtagonist } from "./useProtagonist";
import { useTankModel } from "./useTankModel"; import { useTankModel } from "./useTankModel";
export function useTankChassisModel() { export function useTankChassisModel() {
const tank = useProtagonist(); const tank = useProtagonist();
const scene = useTankModel(`/models/tanks/${tank.id}/chassis.glb`);
const isChassisDamaged = Tankopedia.use(
(state) => state.protagonist.status.chassis_damaged,
);
// for (const child of scene.children) { const map = {
// if (child.name.endsWith("TrackCrashed")) { Wheels: true,
// child.visible = isChassisDamaged; LeftTracks: true,
// } RightTracks: true,
LeftTrackCrashed: false,
RightTrackCrashed: false,
CollisionMesh: false,
};
// if (child.name.startsWith("Track")) { return useTankModel(`/models/tanks/${tank.id}/chassis.glb`, map);
// child.visible = !isChassisDamaged;
// }
// }
console.log(scene);
return scene;
} }
@@ -0,0 +1,21 @@
import {
VisualChanges_TankPart,
type StageParameters,
} from "@protos/blitz_static_tank_upgrade_single_stage";
import { useProtagonist } from "./useProtagonist";
import { useTankModel } from "./useTankModel";
export function useTankGunModel(parameters: StageParameters) {
const tank = useProtagonist();
const selected = parameters.visual_changes.find(
({ tank_part }) => tank_part === VisualChanges_TankPart.TANK_PART_GUN,
);
const map = {
GunMesh: true,
MaskMesh: true,
CollisionMesh: false,
};
return useTankModel(`/models/tanks/${tank.id}/${selected!.name}.glb`, map);
}
@@ -3,5 +3,11 @@ import { useTankModel } from "./useTankModel";
export function useTankHullModel() { export function useTankHullModel() {
const tank = useProtagonist(); const tank = useProtagonist();
return useTankModel(`/models/tanks/${tank.id}/hull.glb`);
const map = {
Mesh: true,
CollisionMesh: false,
};
return useTankModel(`/models/tanks/${tank.id}/hull.glb`, map);
} }
+12 -6
View File
@@ -2,11 +2,11 @@ import { useLoader } from "@react-three/fiber";
import { Mesh, MeshStandardMaterial } from "three"; import { Mesh, MeshStandardMaterial } from "three";
import { GLTFLoader } from "three-stdlib"; import { GLTFLoader } from "three-stdlib";
export function useTankModel(url: string) { export function useTankModel(url: string, map: Record<string, boolean>) {
const collision = false;
const gltf = useLoader(GLTFLoader, url); const gltf = useLoader(GLTFLoader, url);
const [root] = gltf.scene.children;
gltf.scene.traverse((child) => { root.traverse((child) => {
if ( if (
child instanceof Mesh && child instanceof Mesh &&
child.material instanceof MeshStandardMaterial child.material instanceof MeshStandardMaterial
@@ -19,9 +19,15 @@ export function useTankModel(url: string) {
child.receiveShadow = true; child.receiveShadow = true;
}); });
for (const child of gltf.scene.children) { for (const child of root.children) {
child.visible = (child.name === "CollisionMesh") === collision; if (child.name in map) {
child.visible = map[child.name];
continue;
}
child.visible = false;
console.warn(`Root child ${child.name} isn't recognized`);
} }
return gltf.scene; return root;
} }
@@ -0,0 +1,20 @@
import {
VisualChanges_TankPart,
type StageParameters,
} from "@protos/blitz_static_tank_upgrade_single_stage";
import { useProtagonist } from "./useProtagonist";
import { useTankModel } from "./useTankModel";
export function useTankTurretModel(parameters: StageParameters) {
const tank = useProtagonist();
const selected = parameters.visual_changes.find(
({ tank_part }) => tank_part === VisualChanges_TankPart.TANK_PART_TURRET,
);
const map = {
Mesh: true,
CollisionMesh: false,
};
return useTankModel(`/models/tanks/${tank.id}/${selected!.name}.glb`, map);
}