Ingen beskrivning
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

navigator.ts 2.6KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import { Object3D, Vector3 } from 'three';
  2. import { ReeGame } from './index';
  3. export class KeyPoint {
  4. point: Vector3 | Object3D = new Vector3();
  5. lookAt?: Vector3 | Object3D;
  6. constructor(p: Vector3 | Object3D, look?: Vector3 | Object3D) {
  7. this.point = p;
  8. this.lookAt = look;
  9. }
  10. }
  11. export class OrbitNavigator {
  12. private speed: number;
  13. private loop: boolean;
  14. private translateDelta: number;
  15. private target: Object3D;
  16. private points: KeyPoint[];
  17. private idxMax: number;
  18. private idxP0 = 0; // 当前下一个位置索引
  19. private p0: Vector3 = new Vector3(); //上一个关键点
  20. private p1: Vector3 = new Vector3(); //下一个关键点
  21. private lookAt: Vector3 | undefined;
  22. private direction: Vector3 = new Vector3(); //当前前进方向
  23. private vec: Vector3 = new Vector3();
  24. constructor(target: Object3D, points: KeyPoint[], speed: number, loop: boolean = true) {
  25. this.target = target;
  26. this.points = points || [];
  27. this.idxMax = points.length - 2;
  28. this.speed = speed;
  29. this.translateDelta = speed * 0.001;
  30. this.loop = loop;
  31. }
  32. start() {
  33. this.idxP0 = 0;
  34. this.calcDirection();
  35. this.target.position.set(this.p0.x, this.p0.y, this.p0.z);
  36. ReeGame.setUpdate(this.target, (obj: Object3D) => {
  37. this.update(obj);
  38. });
  39. console.log("start");
  40. }
  41. restart() {
  42. this.idxP0 = 0;
  43. this.calcDirection();
  44. this.target.position.set(this.p0.x, this.p0.y, this.p0.z);
  45. }
  46. private update(obj: Object3D) {
  47. if (obj.position.distanceTo(this.p1) <= 0.1) {
  48. this.idxP0++;
  49. this.calcDirection();
  50. }
  51. if(this.lookAt){
  52. obj.lookAt(this.lookAt);
  53. }
  54. obj.position.addScaledVector(this.direction, this.translateDelta);
  55. }
  56. private calcDirection() {
  57. if (this.idxP0 > this.idxMax) {
  58. if (this.loop) {
  59. this.restart();
  60. }
  61. else {
  62. this.direction = new Vector3(0, 0, 0);
  63. return;
  64. }
  65. }
  66. let p0 = this.points[this.idxP0].point;
  67. let p1 = this.points[this.idxP0 + 1].point;
  68. let lookAt = this.points[this.idxP0].lookAt;
  69. this.lookAt = lookAt && lookAt instanceof Vector3 ? lookAt : lookAt?.position;
  70. this.p0 = p0 instanceof Vector3 ? p0 : p0.position;
  71. this.p1 = p1 instanceof Vector3 ? p1 : p1.position;
  72. this.vec = this.vec.subVectors(this.p1, this.p0);
  73. this.direction = this.vec.normalize();
  74. }
  75. }