matrix4.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package math32
  5. import ()
  6. type Matrix4 [16]float32
  7. func NewMatrix4() *Matrix4 {
  8. var mat Matrix4
  9. mat.Identity()
  10. return &mat
  11. }
  12. func (m *Matrix4) Set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 float32) *Matrix4 {
  13. m[0] = n11
  14. m[4] = n12
  15. m[8] = n13
  16. m[12] = n14
  17. m[1] = n21
  18. m[5] = n22
  19. m[9] = n23
  20. m[13] = n24
  21. m[2] = n31
  22. m[6] = n32
  23. m[10] = n33
  24. m[14] = n34
  25. m[3] = n41
  26. m[7] = n42
  27. m[11] = n43
  28. m[15] = n44
  29. return m
  30. }
  31. func (m *Matrix4) Identity() *Matrix4 {
  32. *m = Matrix4{
  33. 1, 0, 0, 0,
  34. 0, 1, 0, 0,
  35. 0, 0, 1, 0,
  36. 0, 0, 0, 1,
  37. }
  38. return m
  39. }
  40. // Copy copies the specified matrix into this one
  41. func (m *Matrix4) Copy(src *Matrix4) *Matrix4 {
  42. *m = *src
  43. return m
  44. }
  45. // Copy position copies the position elements of the specified matrix
  46. // into this one.
  47. func (m *Matrix4) CopyPosition(src *Matrix4) *Matrix4 {
  48. m[12] = src[12]
  49. m[13] = src[13]
  50. m[14] = src[14]
  51. return m
  52. }
  53. func (m *Matrix4) ExtractBasis(xAxis, yAxis, zAxis *Vector3) *Matrix4 {
  54. xAxis.Set(m[0], m[1], m[2])
  55. yAxis.Set(m[4], m[5], m[6])
  56. zAxis.Set(m[8], m[9], m[10])
  57. return m
  58. }
  59. func (m *Matrix4) MakeBasis(xAxis, yAxis, zAxis *Vector3) *Matrix4 {
  60. m.Set(
  61. xAxis.X, yAxis.X, zAxis.X, 0,
  62. xAxis.Y, yAxis.Y, zAxis.Y, 0,
  63. xAxis.Z, yAxis.Z, zAxis.Z, 0,
  64. 0, 0, 0, 1,
  65. )
  66. return m
  67. }
  68. func (m *Matrix4) ExtractRotation(src *Matrix4) *Matrix4 {
  69. var v1 Vector3
  70. scaleX := 1 / v1.Set(src[0], src[1], src[2]).Length()
  71. scaleY := 1 / v1.Set(src[4], src[5], src[6]).Length()
  72. scaleZ := 1 / v1.Set(src[8], src[9], src[10]).Length()
  73. m[0] = src[0] * scaleX
  74. m[1] = src[1] * scaleX
  75. m[2] = src[2] * scaleX
  76. m[4] = src[4] * scaleY
  77. m[5] = src[5] * scaleY
  78. m[6] = src[6] * scaleY
  79. m[8] = src[8] * scaleZ
  80. m[9] = src[9] * scaleZ
  81. m[10] = src[10] * scaleZ
  82. return m
  83. }
  84. func (m *Matrix4) MakeRotationFromEuler(euler *Vector3) *Matrix4 {
  85. x := euler.X
  86. y := euler.Y
  87. z := euler.Z
  88. a := Cos(x)
  89. b := Sin(x)
  90. c := Cos(y)
  91. d := Sin(y)
  92. e := Cos(z)
  93. f := Sin(z)
  94. ae := a * e
  95. af := a * f
  96. be := b * e
  97. bf := b * f
  98. m[0] = c * e
  99. m[4] = -c * f
  100. m[8] = d
  101. m[1] = af + be*d
  102. m[5] = ae - bf*d
  103. m[9] = -b * c
  104. m[2] = bf - ae*d
  105. m[6] = be + af*d
  106. m[10] = a * c
  107. // Last column
  108. m[3] = 0
  109. m[7] = 0
  110. m[11] = 0
  111. // Bottom row
  112. m[12] = 0
  113. m[13] = 0
  114. m[14] = 0
  115. m[15] = 1
  116. return m
  117. }
  118. func (m *Matrix4) MakeRotationFromQuaternion(q *Quaternion) *Matrix4 {
  119. x := q.x
  120. y := q.y
  121. z := q.z
  122. w := q.w
  123. x2 := x + x
  124. y2 := y + y
  125. z2 := z + z
  126. xx := x * x2
  127. xy := x * y2
  128. xz := x * z2
  129. yy := y * y2
  130. yz := y * z2
  131. zz := z * z2
  132. wx := w * x2
  133. wy := w * y2
  134. wz := w * z2
  135. m[0] = 1 - (yy + zz)
  136. m[4] = xy - wz
  137. m[8] = xz + wy
  138. m[1] = xy + wz
  139. m[5] = 1 - (xx + zz)
  140. m[9] = yz - wx
  141. m[2] = xz - wy
  142. m[6] = yz + wx
  143. m[10] = 1 - (xx + yy)
  144. // last column
  145. m[3] = 0
  146. m[7] = 0
  147. m[11] = 0
  148. // bottom row
  149. m[12] = 0
  150. m[13] = 0
  151. m[14] = 0
  152. m[15] = 1
  153. return m
  154. }
  155. func (m *Matrix4) LookAt(eye, target, up *Vector3) *Matrix4 {
  156. var f Vector3
  157. var s Vector3
  158. var u Vector3
  159. f.SubVectors(target, eye).Normalize()
  160. s.CrossVectors(&f, up).Normalize()
  161. u.CrossVectors(&s, &f)
  162. m[0] = s.X
  163. m[1] = u.X
  164. m[2] = -f.X
  165. m[3] = 0.0
  166. m[4] = s.Y
  167. m[5] = u.Y
  168. m[6] = -f.Y
  169. m[7] = 0.0
  170. m[8] = s.Z
  171. m[9] = u.Z
  172. m[10] = -f.Z
  173. m[11] = 0.0
  174. m[12] = -s.Dot(eye)
  175. m[13] = -u.Dot(eye)
  176. m[14] = f.Dot(eye)
  177. m[15] = 1.0
  178. return m
  179. }
  180. // Multiply multiply this matrix by the specified matrix
  181. func (m *Matrix4) Multiply(src *Matrix4) *Matrix4 {
  182. return m.MultiplyMatrices(m, src)
  183. }
  184. // MultiplyMatrices multiply matrix 'a' by 'b' storing the result
  185. // in this matrix.
  186. func (m *Matrix4) MultiplyMatrices(a, b *Matrix4) *Matrix4 {
  187. a11 := a[0]
  188. a12 := a[4]
  189. a13 := a[8]
  190. a14 := a[12]
  191. a21 := a[1]
  192. a22 := a[5]
  193. a23 := a[9]
  194. a24 := a[13]
  195. a31 := a[2]
  196. a32 := a[6]
  197. a33 := a[10]
  198. a34 := a[14]
  199. a41 := a[3]
  200. a42 := a[7]
  201. a43 := a[11]
  202. a44 := a[15]
  203. b11 := b[0]
  204. b12 := b[4]
  205. b13 := b[8]
  206. b14 := b[12]
  207. b21 := b[1]
  208. b22 := b[5]
  209. b23 := b[9]
  210. b24 := b[13]
  211. b31 := b[2]
  212. b32 := b[6]
  213. b33 := b[10]
  214. b34 := b[14]
  215. b41 := b[3]
  216. b42 := b[7]
  217. b43 := b[11]
  218. b44 := b[15]
  219. m[0] = a11*b11 + a12*b21 + a13*b31 + a14*b41
  220. m[4] = a11*b12 + a12*b22 + a13*b32 + a14*b42
  221. m[8] = a11*b13 + a12*b23 + a13*b33 + a14*b43
  222. m[12] = a11*b14 + a12*b24 + a13*b34 + a14*b44
  223. m[1] = a21*b11 + a22*b21 + a23*b31 + a24*b41
  224. m[5] = a21*b12 + a22*b22 + a23*b32 + a24*b42
  225. m[9] = a21*b13 + a22*b23 + a23*b33 + a24*b43
  226. m[13] = a21*b14 + a22*b24 + a23*b34 + a24*b44
  227. m[2] = a31*b11 + a32*b21 + a33*b31 + a34*b41
  228. m[6] = a31*b12 + a32*b22 + a33*b32 + a34*b42
  229. m[10] = a31*b13 + a32*b23 + a33*b33 + a34*b43
  230. m[14] = a31*b14 + a32*b24 + a33*b34 + a34*b44
  231. m[3] = a41*b11 + a42*b21 + a43*b31 + a44*b41
  232. m[7] = a41*b12 + a42*b22 + a43*b32 + a44*b42
  233. m[11] = a41*b13 + a42*b23 + a43*b33 + a44*b43
  234. m[15] = a41*b14 + a42*b24 + a43*b34 + a44*b44
  235. return m
  236. }
  237. func (m *Matrix4) MultiplyToArray(a, b *Matrix4, r []float32) *Matrix4 {
  238. m.MultiplyMatrices(a, b)
  239. copy(r, m[:])
  240. return m
  241. }
  242. // MultiplyScalar multiplies each element of this matrix by
  243. // the specified scalar.
  244. func (m *Matrix4) MultiplyScalar(s float32) *Matrix4 {
  245. m[0] *= s
  246. m[4] *= s
  247. m[8] *= s
  248. m[12] *= s
  249. m[1] *= s
  250. m[5] *= s
  251. m[9] *= s
  252. m[13] *= s
  253. m[2] *= s
  254. m[6] *= s
  255. m[10] *= s
  256. m[14] *= s
  257. m[3] *= s
  258. m[7] *= s
  259. m[11] *= s
  260. m[15] *= s
  261. return m
  262. }
  263. func (m *Matrix4) ApplyToVector3Array(array []float32, offset int, length int) []float32 {
  264. var v1 Vector3
  265. j := offset
  266. for i := 0; i < length; i += 3 {
  267. v1.X = array[j]
  268. v1.Y = array[j+1]
  269. v1.Z = array[j+2]
  270. v1.ApplyMatrix4(m)
  271. array[j] = v1.X
  272. array[j+1] = v1.Y
  273. array[j+2] = v1.Z
  274. j += 3
  275. }
  276. return array
  277. }
  278. // Determinant calculates and returns the determinat of this matrix.
  279. func (m *Matrix4) Determinant() float32 {
  280. n11 := m[0]
  281. n12 := m[4]
  282. n13 := m[8]
  283. n14 := m[12]
  284. n21 := m[1]
  285. n22 := m[5]
  286. n23 := m[9]
  287. n24 := m[13]
  288. n31 := m[2]
  289. n32 := m[6]
  290. n33 := m[10]
  291. n34 := m[14]
  292. n41 := m[3]
  293. n42 := m[7]
  294. n43 := m[11]
  295. n44 := m[15]
  296. return n41*(+n14*n23*n32-n13*n24*n32-n14*n22*n33+n12*n24*n33+n13*n22*n34-n12*n23*n34) +
  297. n42*(+n11*n23*n34-n11*n24*n33+n14*n21*n33-n13*n21*n34+n13*n24*n31-n14*n23*n31) +
  298. n43*(+n11*n24*n32-n11*n22*n34-n14*n21*n32+n12*n21*n34+n14*n22*n31-n12*n24*n31) +
  299. n44*(-n13*n22*n31-n11*n23*n32+n11*n22*n33+n13*n21*n32-n12*n21*n33+n12*n23*n31)
  300. }
  301. func (m *Matrix4) Transpose() *Matrix4 {
  302. var tmp float32
  303. tmp = m[1]
  304. m[1] = m[4]
  305. m[4] = tmp
  306. tmp = m[2]
  307. m[2] = m[8]
  308. m[8] = tmp
  309. tmp = m[6]
  310. m[6] = m[9]
  311. m[9] = tmp
  312. tmp = m[3]
  313. m[3] = m[12]
  314. m[12] = tmp
  315. tmp = m[7]
  316. m[7] = m[13]
  317. m[13] = tmp
  318. tmp = m[11]
  319. m[11] = m[14]
  320. m[14] = tmp
  321. return m
  322. }
  323. func (m *Matrix4) FlattenToArrayOffset(array []float32, offset int) []float32 {
  324. copy(array[offset:], m[:])
  325. return array
  326. }
  327. func (m *Matrix4) SetPosition(v *Vector3) *Matrix4 {
  328. m[12] = v.X
  329. m[13] = v.Y
  330. m[14] = v.Z
  331. return m
  332. }
  333. // GetInverse set this matrix to the inverse of the specified matrix "src".
  334. func (m *Matrix4) GetInverse(src *Matrix4, throwOnInvertible bool) *Matrix4 {
  335. n11 := src[0]
  336. n12 := src[4]
  337. n13 := src[8]
  338. n14 := src[12]
  339. n21 := src[1]
  340. n22 := src[5]
  341. n23 := src[9]
  342. n24 := src[13]
  343. n31 := src[2]
  344. n32 := src[6]
  345. n33 := src[10]
  346. n34 := src[14]
  347. n41 := src[3]
  348. n42 := src[7]
  349. n43 := src[11]
  350. n44 := src[15]
  351. m[0] = n23*n34*n42 - n24*n33*n42 + n24*n32*n43 - n22*n34*n43 - n23*n32*n44 + n22*n33*n44
  352. m[4] = n14*n33*n42 - n13*n34*n42 - n14*n32*n43 + n12*n34*n43 + n13*n32*n44 - n12*n33*n44
  353. m[8] = n13*n24*n42 - n14*n23*n42 + n14*n22*n43 - n12*n24*n43 - n13*n22*n44 + n12*n23*n44
  354. m[12] = n14*n23*n32 - n13*n24*n32 - n14*n22*n33 + n12*n24*n33 + n13*n22*n34 - n12*n23*n34
  355. m[1] = n24*n33*n41 - n23*n34*n41 - n24*n31*n43 + n21*n34*n43 + n23*n31*n44 - n21*n33*n44
  356. m[5] = n13*n34*n41 - n14*n33*n41 + n14*n31*n43 - n11*n34*n43 - n13*n31*n44 + n11*n33*n44
  357. m[9] = n14*n23*n41 - n13*n24*n41 - n14*n21*n43 + n11*n24*n43 + n13*n21*n44 - n11*n23*n44
  358. m[13] = n13*n24*n31 - n14*n23*n31 + n14*n21*n33 - n11*n24*n33 - n13*n21*n34 + n11*n23*n34
  359. m[2] = n22*n34*n41 - n24*n32*n41 + n24*n31*n42 - n21*n34*n42 - n22*n31*n44 + n21*n32*n44
  360. m[6] = n14*n32*n41 - n12*n34*n41 - n14*n31*n42 + n11*n34*n42 + n12*n31*n44 - n11*n32*n44
  361. m[10] = n12*n24*n41 - n14*n22*n41 + n14*n21*n42 - n11*n24*n42 - n12*n21*n44 + n11*n22*n44
  362. m[14] = n14*n22*n31 - n12*n24*n31 - n14*n21*n32 + n11*n24*n32 + n12*n21*n34 - n11*n22*n34
  363. m[3] = n23*n32*n41 - n22*n33*n41 - n23*n31*n42 + n21*n33*n42 + n22*n31*n43 - n21*n32*n43
  364. m[7] = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43
  365. m[11] = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43
  366. m[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33
  367. det := n11*m[0] + n21*m[4] + n31*m[8] + n41*m[12]
  368. if det == 0 {
  369. if throwOnInvertible {
  370. panic("Matrix4.getInverse(): can't invert matrix, determinant is 0")
  371. }
  372. m.Identity()
  373. return m
  374. }
  375. m.MultiplyScalar(1.0 / det)
  376. return m
  377. }
  378. // Scale multiply the first column of this matrix by the vector X component,
  379. // the second column by the vector Y component and the third column by
  380. // the vector Z component. The matrix fourth column is unchanged.
  381. func (m *Matrix4) Scale(v *Vector3) *Matrix4 {
  382. m[0] *= v.X
  383. m[4] *= v.Y
  384. m[8] *= v.Z
  385. m[1] *= v.X
  386. m[5] *= v.Y
  387. m[9] *= v.Z
  388. m[2] *= v.X
  389. m[6] *= v.Y
  390. m[10] *= v.Z
  391. m[3] *= v.X
  392. m[7] *= v.Y
  393. m[11] *= v.Z
  394. return m
  395. }
  396. func (m *Matrix4) GetMaxScaleOnAxis() float32 {
  397. scaleXSq := m[0]*m[0] + m[1]*m[1] + m[2]*m[2]
  398. scaleYSq := m[4]*m[4] + m[5]*m[5] + m[6]*m[6]
  399. scaleZSq := m[8]*m[8] + m[9]*m[9] + m[10]*m[10]
  400. return Sqrt(Max(scaleXSq, Max(scaleYSq, scaleZSq)))
  401. }
  402. func (m *Matrix4) MakeTranslation(x, y, z float32) *Matrix4 {
  403. m.Set(
  404. 1, 0, 0, x,
  405. 0, 1, 0, y,
  406. 0, 0, 1, z,
  407. 0, 0, 0, 1,
  408. )
  409. return m
  410. }
  411. func (m *Matrix4) MakeRotationX(theta float32) *Matrix4 {
  412. c := Cos(theta)
  413. s := Sin(theta)
  414. m.Set(
  415. 1, 0, 0, 0,
  416. 0, c, -s, 0,
  417. 0, s, c, 0,
  418. 0, 0, 0, 1,
  419. )
  420. return m
  421. }
  422. func (m *Matrix4) MakeRotationY(theta float32) *Matrix4 {
  423. c := Cos(theta)
  424. s := Sin(theta)
  425. m.Set(
  426. c, 0, s, 0,
  427. 0, 1, 0, 0,
  428. -s, 0, c, 0,
  429. 0, 0, 0, 1,
  430. )
  431. return m
  432. }
  433. func (m *Matrix4) MakeRotationZ(theta float32) *Matrix4 {
  434. c := Cos(theta)
  435. s := Sin(theta)
  436. m.Set(
  437. c, -s, 0, 0,
  438. s, c, 0, 0,
  439. 0, 0, 1, 0,
  440. 0, 0, 0, 1,
  441. )
  442. return m
  443. }
  444. func (m *Matrix4) MakeRotationAxis(axis *Vector3, angle float32) *Matrix4 {
  445. c := Cos(angle)
  446. s := Sin(angle)
  447. t := 1 - c
  448. x := axis.X
  449. y := axis.Y
  450. z := axis.Z
  451. tx := t * x
  452. ty := t * y
  453. m.Set(
  454. tx*x+c, tx*y-s*z, tx*z+s*y, 0,
  455. tx*y+s*z, ty*y+c, ty*z-s*x, 0,
  456. tx*z-s*y, ty*z+s*x, t*z*z+c, 0,
  457. 0, 0, 0, 1,
  458. )
  459. return m
  460. }
  461. func (m *Matrix4) MakeScale(x, y, z float32) *Matrix4 {
  462. m.Set(
  463. x, 0, 0, 0,
  464. 0, y, 0, 0,
  465. 0, 0, z, 0,
  466. 0, 0, 0, 1,
  467. )
  468. return m
  469. }
  470. func (m *Matrix4) Compose(position *Vector3, quaternion *Quaternion, scale *Vector3) *Matrix4 {
  471. m.MakeRotationFromQuaternion(quaternion)
  472. m.Scale(scale)
  473. m.SetPosition(position)
  474. return m
  475. }
  476. func (m *Matrix4) Decompose(position *Vector3, quaternion *Quaternion, scale *Vector3) *Matrix4 {
  477. var vector Vector3
  478. var matrix Matrix4 = *m
  479. sx := vector.Set(m[0], m[1], m[2]).Length()
  480. sy := vector.Set(m[4], m[5], m[6]).Length()
  481. sz := vector.Set(m[8], m[9], m[10]).Length()
  482. // If determinant is negative, we need to invert one scale
  483. det := m.Determinant()
  484. if det < 0 {
  485. sx = -sx
  486. }
  487. position.X = m[12]
  488. position.Y = m[13]
  489. position.Z = m[14]
  490. // Scale the rotation part
  491. invSX := 1 / sx
  492. invSY := 1 / sy
  493. invSZ := 1 / sz
  494. matrix[0] *= invSX
  495. matrix[1] *= invSX
  496. matrix[2] *= invSX
  497. matrix[4] *= invSY
  498. matrix[5] *= invSY
  499. matrix[6] *= invSY
  500. matrix[8] *= invSZ
  501. matrix[9] *= invSZ
  502. matrix[10] *= invSZ
  503. quaternion.SetFromRotationMatrix(&matrix)
  504. scale.X = sx
  505. scale.Y = sy
  506. scale.Z = sz
  507. return m
  508. }
  509. func (m *Matrix4) MakeFrustum(left, right, bottom, top, near, far float32) *Matrix4 {
  510. m[0] = 2 * near / (right - left)
  511. m[1] = 0
  512. m[2] = 0
  513. m[3] = 0
  514. m[4] = 0
  515. m[5] = 2 * near / (top - bottom)
  516. m[6] = 0
  517. m[7] = 0
  518. m[8] = (right + left) / (right - left)
  519. m[9] = (top + bottom) / (top - bottom)
  520. m[10] = -(far + near) / (far - near)
  521. m[11] = -1
  522. m[12] = 0
  523. m[13] = 0
  524. m[14] = -(2 * far * near) / (far - near)
  525. m[15] = 0
  526. return m
  527. }
  528. func (m *Matrix4) MakePerspective(fov, aspect, near, far float32) *Matrix4 {
  529. ymax := near * Tan(DegToRad(fov*0.5))
  530. ymin := -ymax
  531. xmin := ymin * aspect
  532. xmax := ymax * aspect
  533. return m.MakeFrustum(xmin, xmax, ymin, ymax, near, far)
  534. }
  535. func (m *Matrix4) MakeOrthographic(left, right, top, bottom, near, far float32) *Matrix4 {
  536. w := right - left
  537. h := top - bottom
  538. p := far - near
  539. x := (right + left) / w
  540. y := (top + bottom) / h
  541. z := (far + near) / p
  542. m[0] = 2 / w
  543. m[4] = 0
  544. m[8] = 0
  545. m[12] = -x
  546. m[1] = 0
  547. m[5] = 2 / h
  548. m[9] = 0
  549. m[13] = -y
  550. m[2] = 0
  551. m[6] = 0
  552. m[10] = -2 / p
  553. m[14] = -z
  554. m[3] = 0
  555. m[7] = 0
  556. m[11] = 0
  557. m[15] = 1
  558. return m
  559. }
  560. func (m *Matrix4) FromArray(array [16]float32) *Matrix4 {
  561. copy(m[:], array[:16])
  562. return m
  563. }
  564. func (m *Matrix4) ToArray() []float32 {
  565. array := make([]float32, 4*4)
  566. copy(array, m[:])
  567. return array
  568. }
  569. func (m *Matrix4) Clone() *Matrix4 {
  570. var cloned Matrix4
  571. cloned = *m
  572. return &cloned
  573. }