From dd75aaf6e82799ce88d8e66b01a3d53ba05301c9 Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Mon, 21 Sep 2026 02:03:45 +0800 Subject: feat(viewer): fit camera to loaded model and add checked-in browser acceptance driver - add three.js Box3/Camera bindings and bbox-driven camera framing (fov-fit with margin, recenters the model so group rotation orbits in place); refit on canvas resize instead of reverting to replay placeholder geometry - expose window.SOMHAIRLES_VIEWER debug handle for numeric verification - add tools/acceptance/e2e_acceptance.py: self-provisioning playwright driver (isolated port/artifact root, unique run ids) asserting framing, frozen-screenshot determinism, GLB hash equality, failure surfacing - gitignore scratch/ and tools/acceptance/deps/; document the clean-checkout verification sequence (fable before build) --- src/SomhairlesDream.Frontend/Bindings.fs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'src/SomhairlesDream.Frontend/Bindings.fs') diff --git a/src/SomhairlesDream.Frontend/Bindings.fs b/src/SomhairlesDream.Frontend/Bindings.fs index 9dbfa00..a0276cc 100644 --- a/src/SomhairlesDream.Frontend/Bindings.fs +++ b/src/SomhairlesDream.Frontend/Bindings.fs @@ -8,6 +8,7 @@ type ThreeVector = abstract x: float with get, set abstract y: float with get, set abstract z: float with get, set + abstract length: unit -> float [] type ThreeNode = @@ -18,6 +19,22 @@ type ThreeNode = abstract rotation: ThreeVector with get abstract background: obj with get, set +[] +type ThreeBox3 = + abstract setFromObject: node: ThreeNode -> ThreeBox3 + abstract isEmpty: unit -> bool + abstract getCenter: target: ThreeVector -> ThreeVector + abstract getSize: target: ThreeVector -> ThreeVector + +[] +type ThreeCamera = + inherit ThreeNode + abstract fov: float with get, set + abstract aspect: float with get, set + abstract near: float with get, set + abstract far: float with get, set + abstract updateProjectionMatrix: unit -> unit + [] type ThreeRenderer = abstract setPixelRatio: ratio: float -> unit @@ -71,7 +88,16 @@ let createScene () : ThreeNode = jsNative let createGroup () : ThreeNode = jsNative [] -let createPerspectiveCamera (fieldOfView: float, aspect: float, nearPlane: float, farPlane: float) : ThreeNode = jsNative +let createPerspectiveCamera (fieldOfView: float, aspect: float, nearPlane: float, farPlane: float) : ThreeCamera = jsNative + +[] +let createBox3 () : ThreeBox3 = jsNative + +[] +let createVector3 () : ThreeVector = jsNative + +[] +let exposeViewerDebug (camera: ThreeCamera) (scene: ThreeNode) (group: ThreeNode) (canvas: obj) : unit = jsNative [] let createRenderer (options: obj) : ThreeRenderer = jsNative -- cgit v1.2.3