View.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. //if(dir.x === dir.y){
  34. if(dir.x === 0 && dir.y === 0){
  35. this.pitch = Math.PI / 2 * Math.sign(dir.z);
  36. }else{
  37. let yaw = Math.atan2(dir.y, dir.x) - Math.PI / 2;
  38. let pitch = Math.atan2(dir.z, Math.sqrt(dir.x * dir.x + dir.y * dir.y));
  39. this.yaw = yaw;
  40. this.pitch = pitch;
  41. }
  42. }
  43. lookAt(t){
  44. let V;
  45. if(arguments.length === 1){
  46. V = new THREE.Vector3().subVectors(t, this.position);
  47. }else if(arguments.length === 3){
  48. V = new THREE.Vector3().subVectors(new THREE.Vector3(...arguments), this.position);
  49. }
  50. let radius = V.length();
  51. let dir = V.normalize();
  52. this.radius = radius;
  53. this.direction = dir;
  54. }
  55. getPivot () {
  56. return new THREE.Vector3().addVectors(this.position, this.direction.multiplyScalar(this.radius));
  57. }
  58. getSide () {
  59. let side = new THREE.Vector3(1, 0, 0);
  60. side.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  61. return side;
  62. }
  63. pan (x, y) {
  64. let dir = new THREE.Vector3(0, 1, 0);
  65. dir.applyAxisAngle(new THREE.Vector3(1, 0, 0), this.pitch);
  66. dir.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  67. // let side = new THREE.Vector3(1, 0, 0);
  68. // side.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  69. let side = this.getSide();
  70. let up = side.clone().cross(dir);
  71. let pan = side.multiplyScalar(x).add(up.multiplyScalar(y));
  72. this.position = this.position.add(pan);
  73. // this.target = this.target.add(pan);
  74. }
  75. translate (x, y, z) {
  76. let dir = new THREE.Vector3(0, 1, 0);
  77. dir.applyAxisAngle(new THREE.Vector3(1, 0, 0), this.pitch);
  78. dir.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  79. let side = new THREE.Vector3(1, 0, 0);
  80. side.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  81. let up = side.clone().cross(dir);
  82. let t = side.multiplyScalar(x)
  83. .add(dir.multiplyScalar(y))
  84. .add(up.multiplyScalar(z));
  85. this.position = this.position.add(t);
  86. }
  87. translateWorld (x, y, z) {
  88. this.position.x += x;
  89. this.position.y += y;
  90. this.position.z += z;
  91. }
  92. setView(position, target, duration = 0, callback = null){
  93. let endPosition = null;
  94. if(position instanceof Array){
  95. endPosition = new THREE.Vector3(...position);
  96. }else if(position.x != null){
  97. endPosition = position.clone();
  98. }
  99. let endTarget = null;
  100. if(target instanceof Array){
  101. endTarget = new THREE.Vector3(...target);
  102. }else if(target.x != null){
  103. endTarget = target.clone();
  104. }
  105. const startPosition = this.position.clone();
  106. const startTarget = this.getPivot();
  107. //const endPosition = position.clone();
  108. //const endTarget = target.clone();
  109. let easing = TWEEN.Easing.Quartic.Out;
  110. if(duration === 0){
  111. this.position.copy(endPosition);
  112. this.lookAt(endTarget);
  113. }else{
  114. let value = {x: 0};
  115. let tween = new TWEEN.Tween(value).to({x: 1}, duration);
  116. tween.easing(easing);
  117. //this.tweens.push(tween);
  118. tween.onUpdate(() => {
  119. let t = value.x;
  120. //console.log(t);
  121. const pos = new THREE.Vector3(
  122. (1 - t) * startPosition.x + t * endPosition.x,
  123. (1 - t) * startPosition.y + t * endPosition.y,
  124. (1 - t) * startPosition.z + t * endPosition.z,
  125. );
  126. const target = new THREE.Vector3(
  127. (1 - t) * startTarget.x + t * endTarget.x,
  128. (1 - t) * startTarget.y + t * endTarget.y,
  129. (1 - t) * startTarget.z + t * endTarget.z,
  130. );
  131. this.position.copy(pos);
  132. this.lookAt(target);
  133. });
  134. tween.start();
  135. tween.onComplete(() => {
  136. if(callback){
  137. callback();
  138. }
  139. });
  140. }
  141. }
  142. };