chore(world): add temporary diagnostics for porte strip, octree, ctx loss

This commit is contained in:
Tom Boullay
2026-06-01 22:19:27 +02:00
parent a1798aecb3
commit f6db7d74e2
3 changed files with 61 additions and 1 deletions
+30 -1
View File
@@ -1,9 +1,29 @@
import { useEffect, useRef } from "react";
import type { RefObject } from "react";
import type { Object3D } from "three";
import { Mesh, type Object3D } from "three";
import { Octree } from "three-stdlib";
import type { OctreeReadyHandler } from "@/types/three/three";
// [diag] temporary — count meshes/triangles captured in the octree graph node
function snapshotGraphNode(node: Object3D): {
meshCount: number;
triCount: number;
} {
let meshCount = 0;
let triCount = 0;
node.traverse((obj) => {
if (obj instanceof Mesh) {
meshCount += 1;
const geom = obj.geometry;
const idx = geom.index;
triCount += idx
? idx.count / 3
: (geom.attributes.position?.count ?? 0) / 3;
}
});
return { meshCount, triCount };
}
export function useOctreeGraphNode(
graphNodeRef: RefObject<Object3D | null>,
onOctreeReady: OctreeReadyHandler,
@@ -28,6 +48,15 @@ export function useOctreeGraphNode(
const octree = new Octree();
octree.fromGraphNode(graphNode);
// [diag] temporary — log octree contents to detect partial builds
const snapshot = snapshotGraphNode(graphNode);
console.log("[octree:build]", {
rebuildKey,
meshCount: snapshot.meshCount,
triCount: Math.round(snapshot.triCount),
timestamp: performance.now().toFixed(0),
});
onOctreeReady(octree);
}, [enabled, graphNodeRef, onOctreeReady, rebuildKey]);
}
+10
View File
@@ -277,12 +277,22 @@ function CollisionModelInstance({
// by MergedStaticMapModel and is unaffected.
if (node.name !== "lafabrik") return;
// [diag] temporary — collect all door-like candidate names to debug stripping
const candidates: string[] = [];
const removed: THREE.Object3D[] = [];
sceneInstance.traverse((child) => {
if (/porte/i.test(child.name)) {
candidates.push(child.name);
}
if (child.name === "porte") {
removed.push(child);
}
});
console.log("[lafabrik:porte-strip]", {
candidates,
strippedCount: removed.length,
strippedNames: removed.map((c) => c.name),
});
for (const child of removed) {
child.removeFromParent();
}
+21
View File
@@ -98,6 +98,27 @@ export function Lighting(): React.JSX.Element {
hasShadowMap: !!sun.current.shadow.map,
...counts,
});
// [diag] temporary — track WebGL context loss/restore to correlate with shadow drops
const canvas = gl.domElement;
const handleContextLost = (event: Event) => {
event.preventDefault();
console.log("[ctx:lost]", { timestamp: performance.now().toFixed(0) });
};
const handleContextRestored = () => {
console.log("[ctx:restored]", {
timestamp: performance.now().toFixed(0),
});
if (sun.current) {
sun.current.shadow.needsUpdate = true;
}
};
canvas.addEventListener("webglcontextlost", handleContextLost);
canvas.addEventListener("webglcontextrestored", handleContextRestored);
return () => {
canvas.removeEventListener("webglcontextlost", handleContextLost);
canvas.removeEventListener("webglcontextrestored", handleContextRestored);
};
}, [gl, scene]);
useDebugFolder("Lighting", (folder) => {