From 4cec4b1bb48da27e46766288670d38114a2fdb5d Mon Sep 17 00:00:00 2001 From: Mark Kalsbeek Date: Sun, 25 Jan 2026 10:57:29 +0100 Subject: [PATCH] fix rendering issues on the sandbox --- ui/src/components/ShadingSandbox.vue | 57 +++++++++++++++++++--------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/ui/src/components/ShadingSandbox.vue b/ui/src/components/ShadingSandbox.vue index 47ae5a1..b55545d 100644 --- a/ui/src/components/ShadingSandbox.vue +++ b/ui/src/components/ShadingSandbox.vue @@ -222,7 +222,7 @@ const initThreeJS = () => { }); const width = canvasRef.value.clientWidth || 800; - const height = canvasRef.value.clientHeight || 600; + const height = canvasRef.value.clientHeight || 800; renderer.setSize(width, height); renderer.setPixelRatio(window.devicePixelRatio); @@ -240,6 +240,7 @@ const initThreeJS = () => { // Animation loop control const startAnimation = () => { + console.log('starting animation') if (animationId) return; // Already running const animate = () => { @@ -257,6 +258,7 @@ const startAnimation = () => { }; const pauseAnimation = () => { + console.log('pausing animation') animationPaused = true; if (animationId) { cancelAnimationFrame(animationId); @@ -265,12 +267,14 @@ const pauseAnimation = () => { }; const resumeAnimation = () => { + console.log('resuming animation') animationPaused = false; startAnimation(); }; // Render a single frame (for when animation is paused but we need to update the view) const renderSingleFrame = () => { + console.log('Rendering single frame') if (renderer && scene && camera) { renderer.render(scene, camera); } @@ -281,7 +285,7 @@ const handleResize = () => { if (!canvasRef.value || !renderer || !camera) return; const width = canvasRef.value.clientWidth || 800; - const height = canvasRef.value.clientHeight || 600; + const height = canvasRef.value.clientHeight || 800; renderer.setSize(width, height); renderer.setPixelRatio(window.devicePixelRatio); @@ -341,15 +345,6 @@ const loadTileData = (tileData, newTileId) => { // Z scaling: make Z variation visible but proportional const zScale = normalizeScale * (maxSpan * 0.1) / spanZ; - console.log('Tile scaling:', { - spanX: spanX.toFixed(2), - spanY: spanY.toFixed(2), - spanZ: spanZ.toFixed(2), - tileAspect: tileAspect.toFixed(3), - normalizeScale: normalizeScale.toFixed(4), - zScale: zScale.toFixed(4) - }); - // Transform positions const transformedPositions = new Float32Array(tileData.positions.length); for (let i = 0; i < tileData.positions.length; i += 3) { @@ -672,18 +667,45 @@ const downloadLastRender = () => { // Cleanup const cleanup = () => { + // Stop animation pauseAnimation(); + + // Dispose resize observer if (resizeObserver) { resizeObserver.disconnect(); resizeObserver = null; } - if (renderer) { - renderer.dispose(); - } + + // Dispose mesh if (mesh) { + scene?.remove(mesh); if (mesh.geometry) mesh.geometry.dispose(); if (mesh.material) mesh.material.dispose(); + mesh = null; } + + // Dispose renderer + if (renderer) { + renderer.dispose(); + renderer = null; + } + + // Clear scene + if (scene) { + scene.clear(); + scene = null; + } + + // Clear other Three.js objects + camera = null; + directionalLight = null; + ambientLight = null; + + // Clear geometry cache + geometryCache = null; + + // Reset tile state + tileLoaded.value = false; }; // Lifecycle @@ -711,6 +733,7 @@ onMounted(() => { // Watch for visibility changes watch(() => props.visible, (newVal) => { if (newVal && !renderer) { + // Coming visible and no renderer exists → initialize nextTick(() => { initThreeJS(); @@ -728,11 +751,11 @@ watch(() => props.visible, (newVal) => { } }); } else if (newVal && !props.offscreen) { - // Component already initialized, just resume animation + // Component already initialized, becoming on-screen → just resume animation resumeAnimation(); } else if (!newVal) { - // Hidden - pause animation - pauseAnimation(); + // Becoming invisible → full cleanup + cleanup(); } });