core/vector3.js

  1. import {Quaternion} from '../index.js';
  2. /**
  3. * Creates three-dimensional vectors.
  4. *
  5. * @example
  6. *
  7. * // without chaining
  8. * const vector = new Vector3(3, 2, 1);
  9. * vector.add(new Vector3(1, 0, -1));
  10. *
  11. * @example
  12. *
  13. * // with chaining
  14. * const vector = new Vector3(3, 2, 1).add(new Vector3(1, 0, -1));
  15. */
  16. class Vector3 {
  17. /**
  18. * Stores the x component.
  19. * @type {number}
  20. * @private
  21. */
  22. $x;
  23. /**
  24. * Stores the y component.
  25. * @type {number}
  26. * @private
  27. */
  28. $y;
  29. /**
  30. * Stores the z component.
  31. * @type {number}
  32. * @private
  33. */
  34. $z;
  35. /**
  36. * Gets the x component.
  37. * @type {number}
  38. * @public
  39. */
  40. get x() {
  41. return this.$x;
  42. }
  43. /**
  44. * Gets the y component.
  45. * @type {number}
  46. * @public
  47. */
  48. get y() {
  49. return this.$y;
  50. }
  51. /**
  52. * Gets the z component.
  53. * @type {number}
  54. * @public
  55. */
  56. get z() {
  57. return this.$z;
  58. }
  59. /**
  60. * Creates a new three-dimensional vector.
  61. * @param {number} $x The x component of the vector to create.
  62. * @param {number} $y The y component of the vector to create.
  63. * @param {number} $z The z component of the vector to create.
  64. */
  65. constructor($x, $y, $z) {
  66. this.$x = $x;
  67. this.$y = $y;
  68. this.$z = $z;
  69. }
  70. /**
  71. * Creates a new vector from the given vector.
  72. * @param {Vector3} $vector The given vector.
  73. * @returns {Vector3}
  74. * @public
  75. * @static
  76. */
  77. static from($vector) {
  78. return $vector.clone();
  79. }
  80. /**
  81. * Adds the given vector.
  82. * @param {Vector3} $vector The vector to add.
  83. * @returns {this}
  84. * @public
  85. */
  86. add($vector) {
  87. const x = this.$x;
  88. const y = this.$y;
  89. const z = this.$z;
  90. this.$x = x + $vector.x;
  91. this.$y = y + $vector.y;
  92. this.$z = z + $vector.z;
  93. return this;
  94. }
  95. /**
  96. * Clones the vector.
  97. * @returns {Vector3}
  98. * @public
  99. */
  100. clone() {
  101. const x = this.$x;
  102. const y = this.$y;
  103. const z = this.$z;
  104. return new Vector3(x, y, z);
  105. }
  106. /**
  107. * Checks the equality with the given vector.
  108. * @param {Vector3} $vector The vector to check with.
  109. * @returns {boolean}
  110. * @public
  111. */
  112. equal($vector) {
  113. return this.$x === $vector.x
  114. && this.$y === $vector.y
  115. && this.$z === $vector.z;
  116. }
  117. /**
  118. * Gets the length of the vector.
  119. * @returns {number}
  120. * @public
  121. */
  122. length() {
  123. const x = this.$x;
  124. const y = this.$y;
  125. const z = this.$z;
  126. return Math.sqrt(x * x + y * y + z * z);
  127. }
  128. /**
  129. * Multiplies with the given vector.
  130. * @param {Vector3} $vector The vector to multiply with.
  131. * @returns {this}
  132. * @public
  133. */
  134. multiply($vector) {
  135. const x = this.$x;
  136. const y = this.$y;
  137. const z = this.$z;
  138. this.$x = x * $vector.x;
  139. this.$y = y * $vector.y;
  140. this.$z = z * $vector.z;
  141. return this;
  142. }
  143. /**
  144. * Negates the vector.
  145. * @returns {this}
  146. * @public
  147. */
  148. negate() {
  149. const x = this.$x;
  150. const y = this.$y;
  151. const z = this.$z;
  152. this.$x = - x;
  153. this.$y = - y;
  154. this.$z = - z;
  155. return this;
  156. }
  157. /**
  158. * Normalizes the vector.
  159. * @returns {this}
  160. * @public
  161. */
  162. normalize() {
  163. const x = this.$x;
  164. const y = this.$y;
  165. const z = this.$z;
  166. let length = x * x + y * y + z * z;
  167. if (length > 0) {
  168. length = 1 / Math.sqrt(length);
  169. }
  170. this.$x = x * length;
  171. this.$y = y * length;
  172. this.$z = z * length;
  173. return this;
  174. }
  175. /**
  176. * Rotates the vector.
  177. * @param {Quaternion} $quaternion The rotation to apply.
  178. * @returns {this}
  179. * @public
  180. */
  181. rotate($quaternion) {
  182. const x = this.$x;
  183. const y = this.$y;
  184. const z = this.$z;
  185. const xq = $quaternion.x;
  186. const yq = $quaternion.y;
  187. const zq = $quaternion.z;
  188. const wq = $quaternion.w;
  189. let xu = yq * z - zq * y;
  190. let yu = zq * x - xq * z;
  191. let zu = xq * y - yq * x;
  192. let xv = yq * zu - zq * yu;
  193. let yv = zq * xu - xq * zu;
  194. let zv = xq * yu - yq * xu;
  195. const w = wq * 2;
  196. xu *= w;
  197. yu *= w;
  198. zu *= w;
  199. xv *= 2;
  200. yv *= 2;
  201. zv *= 2;
  202. this.$x = x + xu + xv;
  203. this.$y = y + yu + yv;
  204. this.$z = z + zu + zv;
  205. return this;
  206. }
  207. /**
  208. * Scales the vector by the given scalar factor.
  209. * @param {number} $factor The scalar factor to multiply with.
  210. * @returns {this}
  211. * @public
  212. */
  213. scale($factor) {
  214. const x = this.$x;
  215. const y = this.$y;
  216. const z = this.$z;
  217. this.$x = x * $factor;
  218. this.$y = y * $factor;
  219. this.$z = z * $factor;
  220. return this;
  221. }
  222. /**
  223. * Subtracts the given vector.
  224. * @param {Vector3} $vector The vector to subtract.
  225. * @returns {this}
  226. * @public
  227. */
  228. subtract($vector) {
  229. const x = this.$x;
  230. const y = this.$y;
  231. const z = this.$z;
  232. this.$x = x - $vector.x;
  233. this.$y = y - $vector.y;
  234. this.$z = z - $vector.z;
  235. return this;
  236. }
  237. }
  238. export {
  239. Vector3
  240. };
  241. export default Vector3;