2026-06-14 14:37:52 -05:00
|
|
|
import { useGLTF } from "@react-three/drei";
|
2026-06-12 20:59:43 -05:00
|
|
|
import { useEffect } from "react";
|
2026-06-12 19:45:37 -05:00
|
|
|
import { Mesh, MeshStandardMaterial } from "three";
|
|
|
|
|
|
2026-06-14 14:37:52 -05:00
|
|
|
interface Props {
|
|
|
|
|
url: string;
|
|
|
|
|
map: Record<string, boolean>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function TankModelPart({ url, map }: Props) {
|
|
|
|
|
const gltf = useGLTF(url);
|
2026-06-12 20:22:02 -05:00
|
|
|
const [root] = gltf.scene.children;
|
2026-06-12 19:45:37 -05:00
|
|
|
|
2026-06-12 20:59:43 -05:00
|
|
|
useEffect(() => {
|
|
|
|
|
for (const material of Object.values(gltf.materials)) {
|
|
|
|
|
if (material instanceof MeshStandardMaterial) {
|
|
|
|
|
// TODO: remove this hack and fix the gltf
|
|
|
|
|
material.vertexColors = false;
|
|
|
|
|
material.needsUpdate = true;
|
|
|
|
|
}
|
2026-06-12 19:45:37 -05:00
|
|
|
}
|
|
|
|
|
|
2026-06-12 20:59:43 -05:00
|
|
|
for (const node of Object.values(gltf.nodes)) {
|
|
|
|
|
if (node instanceof Mesh) {
|
|
|
|
|
node.castShadow = true;
|
|
|
|
|
node.receiveShadow = true;
|
|
|
|
|
}
|
2026-06-12 20:22:02 -05:00
|
|
|
}
|
2026-06-12 20:59:43 -05:00
|
|
|
}, [url]);
|
2026-06-12 20:22:02 -05:00
|
|
|
|
2026-06-12 20:59:43 -05:00
|
|
|
useEffect(() => {
|
|
|
|
|
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`);
|
|
|
|
|
}
|
|
|
|
|
}, [url, map]);
|
2026-06-12 19:45:37 -05:00
|
|
|
|
2026-06-14 14:37:52 -05:00
|
|
|
return <primitive object={root} />;
|
2026-06-12 19:45:37 -05:00
|
|
|
}
|