matrix3.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  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 "errors"
  6. // Matrix3 is 3x3 matrix organized internally as column matrix
  7. type Matrix3 [9]float32
  8. // NewMatrix3 creates and returns a pointer to a new Matrix3
  9. // initialized as the identity matrix.
  10. func NewMatrix3() *Matrix3 {
  11. var m Matrix3
  12. m.Identity()
  13. return &m
  14. }
  15. // Set sets all the elements of the matrix row by row starting at row1, column1,
  16. // row1, column2, row1, column3 and so forth.
  17. // Returns the pointer to this updated Matrix.
  18. func (m *Matrix3) Set(n11, n12, n13, n21, n22, n23, n31, n32, n33 float32) *Matrix3 {
  19. m[0] = n11
  20. m[3] = n12
  21. m[6] = n13
  22. m[1] = n21
  23. m[4] = n22
  24. m[7] = n23
  25. m[2] = n31
  26. m[5] = n32
  27. m[8] = n33
  28. return m
  29. }
  30. // SetFromMatrix4 sets the matrix elements based on a Matrix4.
  31. func (m *Matrix3) SetFromMatrix4(src *Matrix4) *Matrix3 {
  32. m.Set(
  33. src[0], src[4], src[8],
  34. src[1], src[5], src[9],
  35. src[2], src[6], src[10],
  36. )
  37. return m
  38. }
  39. // Identity sets this matrix as the identity matrix.
  40. // Returns the pointer to this updated matrix.
  41. func (m *Matrix3) Identity() *Matrix3 {
  42. m.Set(
  43. 1, 0, 0,
  44. 0, 1, 0,
  45. 0, 0, 1,
  46. )
  47. return m
  48. }
  49. // Zero sets this matrix as the zero matrix.
  50. // Returns the pointer to this updated matrix.
  51. func (m *Matrix3) Zero() *Matrix3 {
  52. m.Set(
  53. 0, 0, 0,
  54. 0, 0, 0,
  55. 0, 0, 0,
  56. )
  57. return m
  58. }
  59. // Copy copies src matrix into this one.
  60. // Returns the pointer to this updated matrix.
  61. func (m *Matrix3) Copy(src *Matrix3) *Matrix3 {
  62. *m = *src
  63. return m
  64. }
  65. // MakeRotationFromQuaternion sets this matrix as a rotation matrix from the specified quaternion.
  66. // Returns pointer to this updated matrix.
  67. func (m *Matrix3) MakeRotationFromQuaternion(q *Quaternion) *Matrix3 {
  68. x := q.X
  69. y := q.Y
  70. z := q.Z
  71. w := q.W
  72. x2 := x + x
  73. y2 := y + y
  74. z2 := z + z
  75. xx := x * x2
  76. xy := x * y2
  77. xz := x * z2
  78. yy := y * y2
  79. yz := y * z2
  80. zz := z * z2
  81. wx := w * x2
  82. wy := w * y2
  83. wz := w * z2
  84. m[0] = 1 - (yy + zz)
  85. m[3] = xy - wz
  86. m[6] = xz + wy
  87. m[1] = xy + wz
  88. m[4] = 1 - (xx + zz)
  89. m[7] = yz - wx
  90. m[2] = xz - wy
  91. m[5] = yz + wx
  92. m[8] = 1 - (xx + yy)
  93. return m
  94. }
  95. // ApplyToVector3Array multiplies length vectors in the array starting at offset by this matrix.
  96. // Returns pointer to the updated array.
  97. // This matrix is unchanged.
  98. func (m *Matrix3) ApplyToVector3Array(array []float32, offset int, length int) []float32 {
  99. var v1 Vector3
  100. j := offset
  101. for i := 0; i < length; i += 3 {
  102. v1.X = array[j]
  103. v1.Y = array[j+1]
  104. v1.Z = array[j+2]
  105. v1.ApplyMatrix3(m)
  106. array[j] = v1.X
  107. array[j+1] = v1.Y
  108. array[j+2] = v1.Z
  109. }
  110. return array
  111. }
  112. // Multiply multiply this matrix by the other matrix
  113. // Returns pointer to this updated matrix.
  114. func (m *Matrix3) Multiply(other *Matrix3) *Matrix3 {
  115. return m.MultiplyMatrices(m, other)
  116. }
  117. // MultiplyMatrices multiply matrix a by b storing the result in this matrix.
  118. // Returns pointer to this updated matrix.
  119. func (m *Matrix3) MultiplyMatrices(a, b *Matrix3) *Matrix3 {
  120. a11 := a[0]
  121. a12 := a[3]
  122. a13 := a[6]
  123. a21 := a[1]
  124. a22 := a[4]
  125. a23 := a[7]
  126. a31 := a[2]
  127. a32 := a[5]
  128. a33 := a[8]
  129. b11 := b[0]
  130. b12 := b[3]
  131. b13 := b[6]
  132. b21 := b[1]
  133. b22 := b[4]
  134. b23 := b[7]
  135. b31 := b[2]
  136. b32 := b[5]
  137. b33 := b[8]
  138. m[0] = a11*b11 + a12*b21 + a13*b31
  139. m[3] = a11*b12 + a12*b22 + a13*b32
  140. m[6] = a11*b13 + a12*b23 + a13*b33
  141. m[1] = a21*b11 + a22*b21 + a23*b31
  142. m[4] = a21*b12 + a22*b22 + a23*b32
  143. m[7] = a21*b13 + a22*b23 + a23*b33
  144. m[2] = a31*b11 + a32*b21 + a33*b31
  145. m[5] = a31*b12 + a32*b22 + a33*b32
  146. m[8] = a31*b13 + a32*b23 + a33*b33
  147. return m
  148. }
  149. // MultiplyScalar multiplies each of this matrix's components by the specified scalar.
  150. // Returns pointer to this updated matrix.
  151. func (m *Matrix3) MultiplyScalar(s float32) *Matrix3 {
  152. m[0] *= s
  153. m[3] *= s
  154. m[6] *= s
  155. m[1] *= s
  156. m[4] *= s
  157. m[7] *= s
  158. m[2] *= s
  159. m[5] *= s
  160. m[8] *= s
  161. return m
  162. }
  163. // ScaleColumns multiplies the matrix columns by the vector components.
  164. // This can be used when multiplying this matrix by a diagonal matrix if we store the diagonal components as a vector.
  165. // Returns pointer to this updated matrix.
  166. func (m *Matrix3) ScaleColumns(v *Vector3) *Matrix3 {
  167. m[0] *= v.X
  168. m[1] *= v.X
  169. m[2] *= v.X
  170. m[3] *= v.Y
  171. m[4] *= v.Y
  172. m[5] *= v.Y
  173. m[6] *= v.Z
  174. m[7] *= v.Z
  175. m[8] *= v.Z
  176. return m
  177. }
  178. // Determinant calculates and returns the determinant of this matrix.
  179. func (m *Matrix3) Determinant() float32 {
  180. return m[0]*m[4]*m[8] -
  181. m[0]*m[5]*m[7] -
  182. m[1]*m[3]*m[8] +
  183. m[1]*m[5]*m[6] +
  184. m[2]*m[3]*m[7] -
  185. m[2]*m[4]*m[6]
  186. }
  187. // GetInverse sets this matrix to the inverse of the src matrix.
  188. // If the src matrix cannot be inverted returns error and
  189. // sets this matrix to the identity matrix.
  190. func (m *Matrix3) GetInverse(src *Matrix3) error {
  191. n11 := src[0]
  192. n21 := src[1]
  193. n31 := src[2]
  194. n12 := src[3]
  195. n22 := src[4]
  196. n32 := src[5]
  197. n13 := src[6]
  198. n23 := src[7]
  199. n33 := src[8]
  200. t11 := n33*n22 - n32*n23
  201. t12 := n32*n13 - n33*n12
  202. t13 := n23*n12 - n22*n13
  203. det := n11*t11 + n21*t12 + n31*t13
  204. // no inverse
  205. if det == 0 {
  206. m.Identity()
  207. return errors.New("cannot invert matrix")
  208. }
  209. detInv := 1 / det
  210. m[0] = t11 * detInv
  211. m[1] = ( n31 * n23 - n33 * n21 ) * detInv
  212. m[2] = ( n32 * n21 - n31 * n22 ) * detInv
  213. m[3] = t12 * detInv
  214. m[4] = ( n33 * n11 - n31 * n13 ) * detInv
  215. m[5] = ( n31 * n12 - n32 * n11 ) * detInv
  216. m[6] = t13 * detInv
  217. m[7] = ( n21 * n13 - n23 * n11 ) * detInv
  218. m[8] = ( n22 * n11 - n21 * n12 ) * detInv
  219. return nil
  220. }
  221. // Transpose transposes this matrix.
  222. // Returns pointer to this updated matrix.
  223. func (m *Matrix3) Transpose() *Matrix3 {
  224. var tmp float32
  225. tmp = m[1]
  226. m[1] = m[3]
  227. m[3] = tmp
  228. tmp = m[2]
  229. m[2] = m[6]
  230. m[6] = tmp
  231. tmp = m[5]
  232. m[5] = m[7]
  233. m[7] = tmp
  234. return m
  235. }
  236. // GetNormalMatrix set this matrix to the matrix to transform the normal vectors
  237. // from the src matrix to transform the vertices.
  238. // If the src matrix cannot be inverted returns error.
  239. func (m *Matrix3) GetNormalMatrix(src *Matrix4) error {
  240. m.SetFromMatrix4(src)
  241. err := m.GetInverse(m)
  242. m.Transpose()
  243. return err
  244. }
  245. // FromArray set this matrix array starting at offset.
  246. // Returns pointer to this updated matrix.
  247. func (m *Matrix3) FromArray(array []float32, offset int) *Matrix3 {
  248. copy(m[:], array[offset:offset+9])
  249. return m
  250. }
  251. // ToArray copies this matrix to array starting at offset.
  252. // Returns pointer to the updated array.
  253. func (m *Matrix3) ToArray(array []float32, offset int) []float32 {
  254. copy(array[offset:], m[:])
  255. return array
  256. }
  257. // Clone creates and returns a pointer to a copy of this matrix.
  258. func (m *Matrix3) Clone() *Matrix3 {
  259. var cloned Matrix3
  260. cloned = *m
  261. return &cloned
  262. }