From caea7f0f6f93fdcd58936830e815fc5dbaa43f03 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 20:48:59 +0000 Subject: [PATCH] Changes Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com> --- src/lib/modelTransforms.ts | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/lib/modelTransforms.ts diff --git a/src/lib/modelTransforms.ts b/src/lib/modelTransforms.ts new file mode 100644 index 0000000..58d8807 --- /dev/null +++ b/src/lib/modelTransforms.ts @@ -0,0 +1,35 @@ +import * as THREE from 'three'; + +/** + * Registry of the innermost local-frame group of each model in the scene. + * Measurements are stored in this local frame so they follow the model + * when the user repositions/rotates it via the "Posicionar" tool. + */ +const localGroups = new Map(); + +export function registerModelLocalGroup(modelId: string, obj: THREE.Object3D) { + localGroups.set(modelId, obj); +} + +export function unregisterModelLocalGroup(modelId: string, obj?: THREE.Object3D) { + // Only delete if the registered object matches (avoid race between unmount/mount of the same id) + const current = localGroups.get(modelId); + if (!obj || current === obj) localGroups.delete(modelId); +} + +export function getModelLocalGroup(modelId: string | null | undefined): THREE.Object3D | undefined { + if (!modelId) return undefined; + return localGroups.get(modelId); +} + +export function worldToModelLocal( + modelId: string | null | undefined, + p: { x: number; y: number; z: number }, +): { x: number; y: number; z: number } | null { + const g = getModelLocalGroup(modelId); + if (!g) return null; + g.updateWorldMatrix(true, false); + const v = new THREE.Vector3(p.x, p.y, p.z); + g.worldToLocal(v); + return { x: v.x, y: v.y, z: v.z }; +}