From ada597137f3475e8452a2cff11b8b339039d1ee0 Mon Sep 17 00:00:00 2001 From: ErSan Date: Thu, 5 Mar 2026 11:11:31 +0800 Subject: [PATCH] =?UTF-8?q?feat(sdk):=20=E6=96=B0=E5=A2=9E`focusObjectByDi?= =?UTF-8?q?stance`=E5=B7=A5=E5=85=B7=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/sdk/lib/utils/scene/controls.ts | 43 ++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/packages/sdk/lib/utils/scene/controls.ts b/packages/sdk/lib/utils/scene/controls.ts index cc4aa3f..192f795 100644 --- a/packages/sdk/lib/utils/scene/controls.ts +++ b/packages/sdk/lib/utils/scene/controls.ts @@ -1,12 +1,49 @@ -import {Object3D,Box3,Vector3} from "three"; +import {Object3D,Box3,Sphere,Vector3} from "three"; import CameraControls from "camera-controls"; -export function focusObject(object:Object3D,controls:CameraControls,enableTransition: boolean = true){ +function getObjectBox3(object:Object3D){ const box3 = new Box3(); box3.setFromObject(object); if(box3.isEmpty()){ box3.set(new Vector3(object.position.x-1, object.position.y-1, object.position.z-1), new Vector3(object.position.x+1, object.position.y+1, object.position.z+1)); } + + return box3; +} + +export function focusObject(object:Object3D,controls:CameraControls,enableTransition: boolean = true){ + const box3 = getObjectBox3(object); + return controls.fitToBox(box3,enableTransition); -} \ No newline at end of file +} + +export function focusObjectByDistance(object:Object3D,controls:CameraControls,distance:number,enableTransition: boolean = true){ + const box3 = getObjectBox3(object); + const sphere = box3.getBoundingSphere(new Sphere()); + + const center = sphere.center.clone(); + const radius = Number.isFinite(sphere.radius) ? sphere.radius : 1; + const toSurfaceDistance = Math.max(distance, 0); + const toCenterDistance = Math.max(radius + toSurfaceDistance, 0.01); + + const currentPosition = controls.getPosition(new Vector3()); + const currentTarget = controls.getTarget(new Vector3()); + const direction = currentPosition.sub(currentTarget); + if(direction.lengthSq() < 1e-6){ + direction.set(0, 0, 1); + } + direction.normalize(); + + const nextPosition = center.clone().addScaledVector(direction, toCenterDistance); + + return controls.setLookAt( + nextPosition.x, + nextPosition.y, + nextPosition.z, + center.x, + center.y, + center.z, + enableTransition + ); +}