import { Object3D, Vector3 } from 'three'; import { ReeGame } from './index'; export class KeyPoint { point: Vector3 | Object3D = new Vector3(); lookAt?: Vector3 | Object3D; constructor(p: Vector3 | Object3D, look?: Vector3 | Object3D) { this.point = p; this.lookAt = look; } } export class OrbitNavigator { private speed: number; private loop: boolean; private translateDelta: number; private target: Object3D; private points: KeyPoint[]; private idxMax: number; private idxP0 = 0; // 当前下一个位置索引 private p0: Vector3 = new Vector3(); //上一个关键点 private p1: Vector3 = new Vector3(); //下一个关键点 private lookAt: Vector3 | undefined; private direction: Vector3 = new Vector3(); //当前前进方向 private vec: Vector3 = new Vector3(); constructor(target: Object3D, points: KeyPoint[], speed: number, loop: boolean = true) { this.target = target; this.points = points || []; this.idxMax = points.length - 2; this.speed = speed; this.translateDelta = speed * 0.001; this.loop = loop; } start() { this.idxP0 = 0; this.calcDirection(); this.target.position.set(this.p0.x, this.p0.y, this.p0.z); ReeGame.setUpdate(this.target, (obj: Object3D) => { this.update(obj); }); console.log("start"); } restart() { this.idxP0 = 0; this.calcDirection(); this.target.position.set(this.p0.x, this.p0.y, this.p0.z); } private update(obj: Object3D) { if (obj.position.distanceTo(this.p1) <= 0.1) { this.idxP0++; this.calcDirection(); } if(this.lookAt){ obj.lookAt(this.lookAt); } obj.position.addScaledVector(this.direction, this.translateDelta); } private calcDirection() { if (this.idxP0 > this.idxMax) { if (this.loop) { this.restart(); } else { this.direction = new Vector3(0, 0, 0); return; } } let p0 = this.points[this.idxP0].point; let p1 = this.points[this.idxP0 + 1].point; let lookAt = this.points[this.idxP0].lookAt; this.lookAt = lookAt && lookAt instanceof Vector3 ? lookAt : lookAt?.position; this.p0 = p0 instanceof Vector3 ? p0 : p0.position; this.p1 = p1 instanceof Vector3 ? p1 : p1.position; this.vec = this.vec.subVectors(this.p1, this.p0); this.direction = this.vec.normalize(); } }