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",
"Skia",
"RMAO",
"Verts"
"Verts",
"drei",
"frameloop"
],
"userWords": [
"WOTB",
@@ -6,8 +6,9 @@ import { OrbitControls } from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
import { useProtagonist } from "../../hooks/useProtagonist";
import { useTankChassisModel } from "../../hooks/useTankChassisModel";
import { useTankGunModel } from "../../hooks/useTankGunModel";
import { useTankHullModel } from "../../hooks/useTankHullModel";
import { useTankModel } from "../../hooks/useTankModel";
import { useTankTurretModel } from "../../hooks/useTankTurretModel";
import styles from "./index.module.css";
interface TankopediaSandboxProps {
@@ -45,8 +46,8 @@ function Content({ parameters }: TankopediaSandboxProps) {
const hull = useTankHullModel();
const chassis = useTankChassisModel();
const turret = useTankModel(`/models/tanks/${tank.id}/${selectedTurret}.glb`);
const gun = useTankModel(`/models/tanks/${tank.id}/${selectedGun}.glb`);
const turret = useTankTurretModel(parameters);
const gun = useTankGunModel(parameters);
return (
<>
@@ -1,25 +1,17 @@
import { Tankopedia } from "../stores/tankopedia";
import { useProtagonist } from "./useProtagonist";
import { useTankModel } from "./useTankModel";
export function useTankChassisModel() {
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) {
// if (child.name.endsWith("TrackCrashed")) {
// child.visible = isChassisDamaged;
// }
const map = {
Wheels: true,
LeftTracks: true,
RightTracks: true,
LeftTrackCrashed: false,
RightTrackCrashed: false,
CollisionMesh: false,
};
// if (child.name.startsWith("Track")) {
// child.visible = !isChassisDamaged;
// }
// }
console.log(scene);
return scene;
return useTankModel(`/models/tanks/${tank.id}/chassis.glb`, map);
}
@@ -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() {
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 { GLTFLoader } from "three-stdlib";
export function useTankModel(url: string) {
const collision = false;
export function useTankModel(url: string, map: Record<string, boolean>) {
const gltf = useLoader(GLTFLoader, url);
const [root] = gltf.scene.children;
gltf.scene.traverse((child) => {
root.traverse((child) => {
if (
child instanceof Mesh &&
child.material instanceof MeshStandardMaterial
@@ -19,9 +19,15 @@ export function useTankModel(url: string) {
child.receiveShadow = true;
});
for (const child of gltf.scene.children) {
child.visible = (child.name === "CollisionMesh") === collision;
for (const child of root.children) {
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);
}