Fix invisible model on load by populating meshCache synchronously with useMemo
Build and Deploy / build-and-push (push) Successful in 1m3s
Build and Deploy / build-and-push (push) Successful in 1m3s
This commit is contained in:
@@ -203,8 +203,22 @@ export const ModelViewer = forwardRef<THREE.Group, ModelViewerProps>(({ object,
|
|||||||
const internalRef = useRef<THREE.Group>(null);
|
const internalRef = useRef<THREE.Group>(null);
|
||||||
const groupRef = (ref as any) || internalRef;
|
const groupRef = (ref as any) || internalRef;
|
||||||
const textureCache = useRef<Map<string, THREE.Texture>>(new Map());
|
const textureCache = useRef<Map<string, THREE.Texture>>(new Map());
|
||||||
const meshCache = useRef<Map<string, THREE.Mesh>>(new Map());
|
|
||||||
|
|
||||||
|
const meshCache = useMemo(() => {
|
||||||
|
const cache = new Map<string, THREE.Mesh>();
|
||||||
|
if (object) {
|
||||||
|
let mIdx = 0;
|
||||||
|
object.traverse((child) => {
|
||||||
|
if (child instanceof THREE.Mesh) {
|
||||||
|
const stableId = `mesh-${mIdx}`;
|
||||||
|
cache.set(stableId, child);
|
||||||
|
mIdx++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return cache;
|
||||||
|
}, [object]);
|
||||||
|
|
||||||
useTexturePipeline(object);
|
useTexturePipeline(object);
|
||||||
|
|
||||||
// Cleanup textures on unmount
|
// Cleanup textures on unmount
|
||||||
@@ -212,25 +226,9 @@ export const ModelViewer = forwardRef<THREE.Group, ModelViewerProps>(({ object,
|
|||||||
return () => {
|
return () => {
|
||||||
textureCache.current.forEach(tex => tex.dispose());
|
textureCache.current.forEach(tex => tex.dispose());
|
||||||
textureCache.current.clear();
|
textureCache.current.clear();
|
||||||
meshCache.current.clear();
|
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Build mesh cache when object changes
|
|
||||||
useEffect(() => {
|
|
||||||
meshCache.current.clear();
|
|
||||||
if (object) {
|
|
||||||
let mIdx = 0;
|
|
||||||
object.traverse((child) => {
|
|
||||||
if (child instanceof THREE.Mesh) {
|
|
||||||
const stableId = `mesh-${mIdx}`;
|
|
||||||
meshCache.current.set(stableId, child);
|
|
||||||
mIdx++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [object]);
|
|
||||||
|
|
||||||
// Main transform update for the core model
|
// Main transform update for the core model
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (object && sceneObjects) {
|
if (object && sceneObjects) {
|
||||||
@@ -254,13 +252,13 @@ export const ModelViewer = forwardRef<THREE.Group, ModelViewerProps>(({ object,
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (object && sceneObjects) {
|
if (object && sceneObjects) {
|
||||||
const activeIds = new Set(sceneObjects.map(obj => obj.id));
|
const activeIds = new Set(sceneObjects.map(obj => obj.id));
|
||||||
meshCache.current.forEach((mesh, id) => {
|
meshCache.forEach((mesh, id) => {
|
||||||
if (!activeIds.has(id)) {
|
if (!activeIds.has(id)) {
|
||||||
mesh.visible = false;
|
mesh.visible = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [object, sceneObjects]);
|
}, [object, sceneObjects, meshCache]);
|
||||||
|
|
||||||
if (!object) return null;
|
if (!object) return null;
|
||||||
|
|
||||||
@@ -270,7 +268,7 @@ export const ModelViewer = forwardRef<THREE.Group, ModelViewerProps>(({ object,
|
|||||||
<group ref={groupRef}>
|
<group ref={groupRef}>
|
||||||
<primitive object={object} />
|
<primitive object={object} />
|
||||||
{meshObjects.map(obj => {
|
{meshObjects.map(obj => {
|
||||||
const mesh = meshCache.current.get(obj.id);
|
const mesh = meshCache.get(obj.id);
|
||||||
if (!mesh) return null;
|
if (!mesh) return null;
|
||||||
return (
|
return (
|
||||||
<group key={obj.id}>
|
<group key={obj.id}>
|
||||||
|
|||||||
Reference in New Issue
Block a user