fix5
This commit is contained in:
1 parent
8bb36ef84f
commit
36fe6cc7b3
1 file changed
+25
-10
@@ -29,22 +29,22 @@ export function SystemModel({
|
||||
}: Props) {
|
||||
const { scene } = useGLTF(modelUrl(modelFile));
|
||||
const clonedRef = useRef<THREE.Group>();
|
||||
// Nome original do nó (como veio do .glb), capturado uma única vez no
|
||||
// clone — necessário porque o efeito abaixo reescreve mesh.name para o
|
||||
// slug da estrutura, e precisa continuar encontrando a estrutura certa
|
||||
// em execuções seguintes (toggle de camadas, seleção, corte etc.).
|
||||
// Nome original de CADA objeto (não só malhas) como veio do .glb,
|
||||
// capturado uma única vez no clone. Precisamos disso porque quando um
|
||||
// nó do glTF tem mais de um material, o GLTFLoader do three.js cria um
|
||||
// Group com o nome do nó e sub-malhas (children) com nomes DIFERENTES
|
||||
// (gerados pelo loader) — sem isso, a maioria das estruturas com mais
|
||||
// de um material nunca batia com o manifesto e ficava sempre oculta.
|
||||
const originalNames = useRef<WeakMap<THREE.Object3D, string>>(new WeakMap());
|
||||
|
||||
if (!clonedRef.current) {
|
||||
const clone = scene.clone(true);
|
||||
clone.traverse((obj) => {
|
||||
originalNames.current.set(obj, obj.name);
|
||||
const mesh = obj as THREE.Mesh;
|
||||
if (mesh.isMesh) {
|
||||
originalNames.current.set(mesh, mesh.name);
|
||||
if (mesh.material) {
|
||||
if (mesh.isMesh && mesh.material) {
|
||||
mesh.material = (mesh.material as THREE.MeshStandardMaterial).clone();
|
||||
}
|
||||
}
|
||||
});
|
||||
clonedRef.current = clone;
|
||||
}
|
||||
@@ -55,12 +55,26 @@ export function SystemModel({
|
||||
[structuresInFile],
|
||||
);
|
||||
|
||||
// Sobe pelos pais até achar um nome (do próprio objeto ou de um
|
||||
// ancestral) que bata com alguma estrutura do manifesto.
|
||||
function resolveStructure(obj: THREE.Object3D): Structure | undefined {
|
||||
let node: THREE.Object3D | null = obj;
|
||||
while (node) {
|
||||
const name = originalNames.current.get(node);
|
||||
if (name) {
|
||||
const structure = byMeshName.get(name);
|
||||
if (structure) return structure;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
root.traverse((obj) => {
|
||||
const mesh = obj as THREE.Mesh;
|
||||
if (!mesh.isMesh) return;
|
||||
const originalName = originalNames.current.get(mesh) ?? mesh.name;
|
||||
const structure = byMeshName.get(originalName);
|
||||
const structure = resolveStructure(mesh);
|
||||
if (!structure) {
|
||||
// Malha sem correspondência no manifesto (não catalogada) — oculta.
|
||||
mesh.visible = false;
|
||||
@@ -77,6 +91,7 @@ export function SystemModel({
|
||||
mat.emissive = isSelected ? HIGHLIGHT : BLACK;
|
||||
mat.emissiveIntensity = isSelected ? 0.6 : 0;
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [root, byMeshName, visibleSystems, selectedSlug, clippingPlanes]);
|
||||
|
||||
const handleClick = (e: ThreeEvent<MouseEvent>) => {
|
||||
|
||||
Reference in new issue
Block a user