Home Reference Source Repository

js/base/Vector4.js

  1. 'use strict'
  2.  
  3. /**
  4. * Vector4 class
  5. * @access public
  6. */
  7. export default class Vector4 {
  8. /**
  9. * constructor
  10. * @access public
  11. * @param {float} x -
  12. * @param {float} y -
  13. * @param {float} z -
  14. * @param {float} w -
  15. * @constructor
  16. */
  17. constructor(x = 0.0, y = 0.0, z = 0.0, w = 0.0) {
  18. this.setValue(x, y, z, w)
  19. }
  20.  
  21. clone() {
  22. return new Vector4(this.x, this.y, this.z, this.w)
  23. }
  24.  
  25. setValue(x, y = 0.0, z = 0.0, w = 0.0) {
  26. if((x instanceof Vector4) || (x instanceof Object && x.w !== null)){
  27. this.x = x.x
  28. this.y = x.y
  29. this.z = x.z
  30. this.w = x.w
  31. }else{
  32. this.x = x || 0.0
  33. this.y = y || 0.0
  34. this.z = z || 0.0
  35. this.w = w || 0.0
  36. }
  37. }
  38.  
  39. lerp(src1, src2, rate) {
  40. this.x = src1.x + rate * (src2.x - src1.x)
  41. this.y = src1.y + rate * (src2.y - src1.y)
  42. this.z = src1.z + rate * (src2.z - src1.z)
  43. this.w = src1.w + rate * (src2.w - src1.w)
  44. }
  45.  
  46. slerp(src1, src2, rate) {
  47. const qr = src1.x * src2.x + src1.y * src2.y + src1.z * src2.z + src1.w * src2.w
  48.  
  49. if(qr < 0){
  50. this.x = src1.x - (src1.x + src2.x) * rate
  51. this.y = src1.y - (src1.y + src2.y) * rate
  52. this.z = src1.z - (src1.z + src2.z) * rate
  53. this.w = src1.w - (src1.w + src2.w) * rate
  54. }else{
  55. this.x = src1.x + (src2.x - src1.x) * rate
  56. this.y = src1.y + (src2.y - src1.y) * rate
  57. this.z = src1.z + (src2.z - src1.z) * rate
  58. this.w = src1.w + (src2.w - src1.w) * rate
  59. }
  60. this.normalize()
  61. }
  62.  
  63. ln(src) {
  64. const v = new Vector4()
  65. v.normalize(src)
  66.  
  67. const n = Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z)
  68. if(n === 0){
  69. this.x = 0
  70. this.y = 0
  71. this.z = 0
  72. this.w = 0
  73. return
  74. }
  75. const theta = Math.atan2(n, v.w) / n
  76.  
  77. this.x = theta * v.x
  78. this.y = theta * v.y
  79. this.z = theta * v.z
  80. this.w = 0
  81. }
  82.  
  83. exp(src) {
  84. const n = Math.sqrt(src.x * src.x + src.y * src.y + src.z * src.z)
  85. if(n > 0.0){
  86. const sinn = Math.sin(n)
  87. this.x = sinn * src.x / n
  88. this.y = sinn * src.y / n
  89. this.z = sinn * src.z / n
  90. this.w = Math.cos(n)
  91. }else{
  92. this.x = 0.0
  93. this.y = 0.0
  94. this.z = 0.0
  95. this.w = 1.0
  96. }
  97. }
  98.  
  99. normalize(src = this) {
  100. const square = 1.0 / Math.sqrt(src.x * src.x + src.y * src.y + src.z * src.z + src.w * src.w)
  101.  
  102. this.x = src.x * square
  103. this.y = src.y * square
  104. this.z = src.z * square
  105. this.w = src.w * square
  106. }
  107.  
  108. createAxis(axis, rotAngle) {
  109. if(Math.abs(rotAngle) < 0.0001){
  110. this.x = 0.0
  111. this.y = 0.0
  112. this.z = 0.0
  113. this.w = 1.0
  114. }else{
  115. const angle = rotAngle * 0.5
  116. const temp = Math.sin(angle)
  117.  
  118. this.x = axis.x * temp
  119. this.y = axis.y * temp
  120. this.z = axis.z * temp
  121. this.w = Math.cos(angle)
  122. }
  123. }
  124.  
  125. cross(src1, src2) {
  126. const x = src1.w * src2.x + src1.x * src2.w + src1.y * src2.z - src1.z * src2.y
  127. const y = src1.w * src2.y - src1.x * src2.z + src1.y * src2.w + src1.z * src2.x
  128. const z = src1.w * src2.z + src1.x * src2.y - src1.y * src2.x + src1.z * src2.w
  129. const w = src1.w * src2.w - src1.x * src2.x - src1.y * src2.y - src1.z * src2.z
  130.  
  131. this.x = x
  132. this.y = y
  133. this.z = z
  134. this.w = w
  135. }
  136.  
  137. eulerToQuaternion(eulerAngle) {
  138. const xRadian = eulerAngle.x * 0.5
  139. const yRadian = eulerAngle.y * 0.5
  140. const zRadian = eulerAngle.z * 0.5
  141. const sinX = Math.sin(xRadian)
  142. const cosX = Math.cos(xRadian)
  143. const sinY = Math.sin(yRadian)
  144. const cosY = Math.cos(yRadian)
  145. const sinZ = Math.sin(zRadian)
  146. const cosZ = Math.cos(zRadian)
  147.  
  148. this.x = sinX * cosY * cosZ - cosX * sinY * sinZ
  149. this.y = cosX * sinY * cosZ + sinX * cosY * sinZ
  150. this.z = cosX * cosY * sinZ - sinX * sinY * cosZ
  151. this.w = cosX * cosY * cosZ + sinX * sinY * sinZ
  152. }
  153.  
  154. transform(vec, matrix){
  155. const rx = vec.x * matrix.m11 + vec.y * matrix.m21 + vec.z * matrix.m31 + vec.w * matrix.m41
  156. const ry = vec.x * matrix.m12 + vec.y * matrix.m22 + vec.z * matrix.m32 + vec.w * matrix.m42
  157. const rz = vec.x * matrix.m13 + vec.y * matrix.m23 + vec.z * matrix.m33 + vec.w * matrix.m43
  158. const rw = vec.x * matrix.m14 + vec.y * matrix.m24 + vec.z * matrix.m34 + vec.w * matrix.m44
  159.  
  160. this.x = rx
  161. this.y = ry
  162. this.z = rz
  163. this.w = rw
  164. }
  165.  
  166. quaternionFromMatrix(mat) {
  167. const mx = mat.m11 - mat.m22 - mat.m33
  168. const my = mat.m22 - mat.m11 - mat.m33
  169. const mz = mat.m33 - mat.m11 - mat.m22
  170. const mw = mat.m11 + mat.m22 + mat.m33
  171.  
  172. let biggestIndex = 0
  173. let mval = mw
  174. if(mx > mval) {
  175. mval = mx
  176. biggestIndex = 1
  177. }
  178. if(my > mval) {
  179. mval = my
  180. biggestIndex = 2
  181. }
  182. if(mz > mval) {
  183. mval = mz
  184. biggestIndex = 3
  185. }
  186.  
  187. const biggestVal = Math.sqrt(mval + 1.0) * 0.5
  188. const mult = 0.25 / biggestVal
  189.  
  190. switch(biggestIndex) {
  191. case 0:
  192. this.x = (mat.m23 - mat.m32) * mult
  193. this.y = (mat.m31 - mat.m13) * mult
  194. this.z = (mat.m12 - mat.m21) * mult
  195. this.w = biggestVal
  196. break
  197. case 1:
  198. this.x = biggestVal
  199. this.y = (mat.m12 + mat.m21) * mult
  200. this.z = (mat.m31 + mat.m13) * mult
  201. this.w = (mat.m23 - mat.m32) * mult
  202. break
  203. case 2:
  204. this.x = (mat.m12 + mat.m21) * mult
  205. this.y = biggestVal
  206. this.z = (mat.m23 + mat.m32) * mult
  207. this.w = (mat.m31 - mat.m13) * mult
  208. break
  209. case 3:
  210. this.x = (mat.m31 * mat.m13) * mult
  211. this.y = (mat.m23 * mat.m32) * mult
  212. this.z = biggestVal
  213. this.w = (mat.m12 - mat.m21) * mult
  214. break
  215. default:
  216. break
  217. }
  218. }
  219.  
  220. getWebGLFloatArray() {
  221. return new Float32Array([
  222. this.x, this.y, this.z, this.w
  223. ])
  224. }
  225. }
  226.