From 0629c7d3e375355c1dc1e170060c99d8c605d50d Mon Sep 17 00:00:00 2001 From: Wassim SAMAD Date: Tue, 23 Jun 2026 14:06:20 -0400 Subject: [PATCH] fix(export): snap levels to stacked positions before GLB export exportSceneToGlb now calls snapLevelsToTruePositions() (the same clean stacked presentation thumbnail capture uses) before snapshotting the scene, so the GLB always reflects the stacked building regardless of the live levelMode (exploded/solo) or an unsettled level lerp. Fixes baked GLBs where a level was captured at a stray offset (e.g. ~ -100k Y), which inflated the bounding box and made the model unframable / invisible in third-party glTF viewers. Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/editor/src/lib/glb-export.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/editor/src/lib/glb-export.ts b/packages/editor/src/lib/glb-export.ts index c8a8703c..055afe46 100644 --- a/packages/editor/src/lib/glb-export.ts +++ b/packages/editor/src/lib/glb-export.ts @@ -7,7 +7,7 @@ import { type WindowNode, type ZoneNode, } from '@pascal-app/core' -import { poseWindowMovingParts, SCENE_LAYER } from '@pascal-app/viewer' +import { poseWindowMovingParts, SCENE_LAYER, snapLevelsToTruePositions } from '@pascal-app/viewer' import type { Object3D } from 'three' import * as THREE from 'three' import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js' @@ -36,10 +36,16 @@ export async function exportSceneToGlb( nodes: Record, ): Promise { emitter.emit('thumbnail:before-capture', undefined) + // Snap levels to their true stacked positions (like thumbnail capture) so the + // export always reflects the clean stacked building, regardless of the live + // levelMode (exploded/solo) or an unsettled level lerp that could otherwise + // bake a level at a stray offset. + const restoreLevels = snapLevelsToTruePositions() let prepared: ReturnType try { prepared = prepareSceneForExport(sceneGroup, nodes) } finally { + restoreLevels() emitter.emit('thumbnail:after-capture', undefined) } const { scene: exportScene, animations } = prepared