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