View.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import * as THREE from "../../libs/three.js/build/three.module.js";
  2. export class View{//base
  3. constructor () {
  4. this.position = new THREE.Vector3(0, 0, 0);
  5. this.yaw = Math.PI / 4;
  6. this._pitch = -Math.PI / 4;
  7. this.radius = 1;
  8. this.maxPitch = Math.PI / 2;
  9. this.minPitch = -Math.PI / 2;
  10. }
  11. clone () {
  12. let c = new View();
  13. c.yaw = this.yaw;
  14. c._pitch = this.pitch;
  15. c.radius = this.radius;
  16. c.maxPitch = this.maxPitch;
  17. c.minPitch = this.minPitch;
  18. return c;
  19. }
  20. get pitch () {
  21. return this._pitch;
  22. }
  23. set pitch (angle) {
  24. this._pitch = Math.max(Math.min(angle, this.maxPitch), this.minPitch);
  25. }
  26. get direction () {
  27. let dir = new THREE.Vector3(0, 1, 0);
  28. dir.applyAxisAngle(new THREE.Vector3(1, 0, 0), this.pitch);
  29. dir.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  30. return dir;
  31. }
  32. set direction (dir) {
  33. dir = dir.clone().normalize()//add
  34. if(dir.x === 0 && dir.y === 0){
  35. this.pitch = Math.PI / 2 * Math.sign(dir.z);
  36. this.yaw = 0 //add:还是要指定一下, 否则不统一
  37. }else{
  38. let yaw = Math.atan2(dir.y, dir.x) - Math.PI / 2;
  39. let pitch = Math.atan2(dir.z, Math.sqrt(dir.x * dir.x + dir.y * dir.y));
  40. this.yaw = yaw;
  41. this.pitch = pitch;
  42. }
  43. }
  44. lookAt(t){//setPivot
  45. let V;
  46. if(arguments.length === 1){
  47. V = new THREE.Vector3().subVectors(t, this.position);
  48. }else if(arguments.length === 3){
  49. V = new THREE.Vector3().subVectors(new THREE.Vector3(...arguments), this.position);
  50. }
  51. let radius = V.length();
  52. let dir = V.normalize();
  53. this.radius = radius;
  54. this.direction = dir;
  55. }
  56. getPivot () {
  57. return new THREE.Vector3().addVectors(this.position, this.direction.multiplyScalar(this.radius));
  58. }
  59. getSide () {
  60. let side = new THREE.Vector3(1, 0, 0);
  61. side.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  62. return side;
  63. }
  64. pan (x, y) {
  65. let dir = new THREE.Vector3(0, 1, 0);
  66. dir.applyAxisAngle(new THREE.Vector3(1, 0, 0), this.pitch);
  67. dir.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  68. // let side = new THREE.Vector3(1, 0, 0);
  69. // side.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  70. let side = this.getSide();
  71. let up = side.clone().cross(dir);
  72. let pan = side.multiplyScalar(x).add(up.multiplyScalar(y));
  73. this.position = this.position.add(pan);
  74. // this.target = this.target.add(pan);
  75. }
  76. translate (x, y, z) {
  77. let dir = new THREE.Vector3(0, 1, 0);
  78. dir.applyAxisAngle(new THREE.Vector3(1, 0, 0), this.pitch);
  79. dir.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  80. let side = new THREE.Vector3(1, 0, 0);
  81. side.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  82. let up = side.clone().cross(dir);
  83. let t = side.multiplyScalar(x)
  84. .add(dir.multiplyScalar(y))
  85. .add(up.multiplyScalar(z));
  86. this.position = this.position.add(t);
  87. }
  88. translateWorld (x, y, z) {
  89. this.position.x += x;
  90. this.position.y += y;
  91. this.position.z += z;
  92. }
  93. setView(position, target, duration = 0, callback = null){
  94. let endPosition = null;
  95. if(position instanceof Array){
  96. endPosition = new THREE.Vector3(...position);
  97. }else if(position.x != null){
  98. endPosition = position.clone();
  99. }
  100. let endTarget = null;
  101. if(target instanceof Array){
  102. endTarget = new THREE.Vector3(...target);
  103. }else if(target.x != null){
  104. endTarget = target.clone();
  105. }
  106. const startPosition = this.position.clone();
  107. const startTarget = this.getPivot();
  108. //const endPosition = position.clone();
  109. //const endTarget = target.clone();
  110. let easing = TWEEN.Easing.Quartic.Out;
  111. if(duration === 0){
  112. this.position.copy(endPosition);
  113. this.lookAt(endTarget);
  114. }else{
  115. let value = {x: 0};
  116. let tween = new TWEEN.Tween(value).to({x: 1}, duration);
  117. tween.easing(easing);
  118. //this.tweens.push(tween);
  119. tween.onUpdate(() => {
  120. let t = value.x;
  121. //console.log(t);
  122. const pos = new THREE.Vector3(
  123. (1 - t) * startPosition.x + t * endPosition.x,
  124. (1 - t) * startPosition.y + t * endPosition.y,
  125. (1 - t) * startPosition.z + t * endPosition.z,
  126. );
  127. const target = new THREE.Vector3(
  128. (1 - t) * startTarget.x + t * endTarget.x,
  129. (1 - t) * startTarget.y + t * endTarget.y,
  130. (1 - t) * startTarget.z + t * endTarget.z,
  131. );
  132. this.position.copy(pos);
  133. this.lookAt(target);
  134. });
  135. tween.start();
  136. tween.onComplete(() => {
  137. if(callback){
  138. callback();
  139. }
  140. });
  141. }
  142. }
  143. };