feat(sdk): 新增focusObjectByDistance工具方法

This commit is contained in:
ErSan 2026-03-05 11:11:31 +08:00
parent 218f4f31f0
commit ada597137f

View File

@ -1,12 +1,49 @@
import {Object3D,Box3,Vector3} from "three"; import {Object3D,Box3,Sphere,Vector3} from "three";
import CameraControls from "camera-controls"; import CameraControls from "camera-controls";
export function focusObject(object:Object3D,controls:CameraControls,enableTransition: boolean = true){ function getObjectBox3(object:Object3D){
const box3 = new Box3(); const box3 = new Box3();
box3.setFromObject(object); box3.setFromObject(object);
if(box3.isEmpty()){ 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)); 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); return controls.fitToBox(box3,enableTransition);
} }
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
);
}