mat4.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright 2014 The Go 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 f32
  5. import "fmt"
  6. // A Mat4 is a 4x4 matrix of float32 values.
  7. // Elements are indexed first by row then column, i.e. m[row][column].
  8. type Mat4 [4]Vec4
  9. func (m Mat4) String() string {
  10. return fmt.Sprintf(`Mat4[% 0.3f, % 0.3f, % 0.3f, % 0.3f,
  11. % 0.3f, % 0.3f, % 0.3f, % 0.3f,
  12. % 0.3f, % 0.3f, % 0.3f, % 0.3f,
  13. % 0.3f, % 0.3f, % 0.3f, % 0.3f]`,
  14. m[0][0], m[0][1], m[0][2], m[0][3],
  15. m[1][0], m[1][1], m[1][2], m[1][3],
  16. m[2][0], m[2][1], m[2][2], m[2][3],
  17. m[3][0], m[3][1], m[3][2], m[3][3])
  18. }
  19. func (m *Mat4) Identity() {
  20. *m = Mat4{
  21. {1, 0, 0, 0},
  22. {0, 1, 0, 0},
  23. {0, 0, 1, 0},
  24. {0, 0, 0, 1},
  25. }
  26. }
  27. func (m *Mat4) Eq(n *Mat4, epsilon float32) bool {
  28. for i := range m {
  29. for j := range m[i] {
  30. diff := m[i][j] - n[i][j]
  31. if diff < -epsilon || +epsilon < diff {
  32. return false
  33. }
  34. }
  35. }
  36. return true
  37. }
  38. // Mul stores a × b in m.
  39. func (m *Mat4) Mul(a, b *Mat4) {
  40. // Store the result in local variables, in case m == a || m == b.
  41. m00 := a[0][0]*b[0][0] + a[0][1]*b[1][0] + a[0][2]*b[2][0] + a[0][3]*b[3][0]
  42. m01 := a[0][0]*b[0][1] + a[0][1]*b[1][1] + a[0][2]*b[2][1] + a[0][3]*b[3][1]
  43. m02 := a[0][0]*b[0][2] + a[0][1]*b[1][2] + a[0][2]*b[2][2] + a[0][3]*b[3][2]
  44. m03 := a[0][0]*b[0][3] + a[0][1]*b[1][3] + a[0][2]*b[2][3] + a[0][3]*b[3][3]
  45. m10 := a[1][0]*b[0][0] + a[1][1]*b[1][0] + a[1][2]*b[2][0] + a[1][3]*b[3][0]
  46. m11 := a[1][0]*b[0][1] + a[1][1]*b[1][1] + a[1][2]*b[2][1] + a[1][3]*b[3][1]
  47. m12 := a[1][0]*b[0][2] + a[1][1]*b[1][2] + a[1][2]*b[2][2] + a[1][3]*b[3][2]
  48. m13 := a[1][0]*b[0][3] + a[1][1]*b[1][3] + a[1][2]*b[2][3] + a[1][3]*b[3][3]
  49. m20 := a[2][0]*b[0][0] + a[2][1]*b[1][0] + a[2][2]*b[2][0] + a[2][3]*b[3][0]
  50. m21 := a[2][0]*b[0][1] + a[2][1]*b[1][1] + a[2][2]*b[2][1] + a[2][3]*b[3][1]
  51. m22 := a[2][0]*b[0][2] + a[2][1]*b[1][2] + a[2][2]*b[2][2] + a[2][3]*b[3][2]
  52. m23 := a[2][0]*b[0][3] + a[2][1]*b[1][3] + a[2][2]*b[2][3] + a[2][3]*b[3][3]
  53. m30 := a[3][0]*b[0][0] + a[3][1]*b[1][0] + a[3][2]*b[2][0] + a[3][3]*b[3][0]
  54. m31 := a[3][0]*b[0][1] + a[3][1]*b[1][1] + a[3][2]*b[2][1] + a[3][3]*b[3][1]
  55. m32 := a[3][0]*b[0][2] + a[3][1]*b[1][2] + a[3][2]*b[2][2] + a[3][3]*b[3][2]
  56. m33 := a[3][0]*b[0][3] + a[3][1]*b[1][3] + a[3][2]*b[2][3] + a[3][3]*b[3][3]
  57. m[0][0] = m00
  58. m[0][1] = m01
  59. m[0][2] = m02
  60. m[0][3] = m03
  61. m[1][0] = m10
  62. m[1][1] = m11
  63. m[1][2] = m12
  64. m[1][3] = m13
  65. m[2][0] = m20
  66. m[2][1] = m21
  67. m[2][2] = m22
  68. m[2][3] = m23
  69. m[3][0] = m30
  70. m[3][1] = m31
  71. m[3][2] = m32
  72. m[3][3] = m33
  73. }
  74. // Perspective sets m to be the GL perspective matrix.
  75. func (m *Mat4) Perspective(fov Radian, aspect, near, far float32) {
  76. t := Tan(float32(fov) / 2)
  77. m[0][0] = 1 / (aspect * t)
  78. m[1][1] = 1 / t
  79. m[2][2] = -(far + near) / (far - near)
  80. m[2][3] = -1
  81. m[3][2] = -2 * far * near / (far - near)
  82. }
  83. // Scale sets m to be a scale followed by p.
  84. // It is equivalent to
  85. //
  86. // m.Mul(p, &Mat4{
  87. // {x, 0, 0, 0},
  88. // {0, y, 0, 0},
  89. // {0, 0, z, 0},
  90. // {0, 0, 0, 1},
  91. // }).
  92. func (m *Mat4) Scale(p *Mat4, x, y, z float32) {
  93. m[0][0] = p[0][0] * x
  94. m[0][1] = p[0][1] * y
  95. m[0][2] = p[0][2] * z
  96. m[0][3] = p[0][3]
  97. m[1][0] = p[1][0] * x
  98. m[1][1] = p[1][1] * y
  99. m[1][2] = p[1][2] * z
  100. m[1][3] = p[1][3]
  101. m[2][0] = p[2][0] * x
  102. m[2][1] = p[2][1] * y
  103. m[2][2] = p[2][2] * z
  104. m[2][3] = p[2][3]
  105. m[3][0] = p[3][0] * x
  106. m[3][1] = p[3][1] * y
  107. m[3][2] = p[3][2] * z
  108. m[3][3] = p[3][3]
  109. }
  110. // Translate sets m to be a translation followed by p.
  111. // It is equivalent to
  112. //
  113. // m.Mul(p, &Mat4{
  114. // {1, 0, 0, x},
  115. // {0, 1, 0, y},
  116. // {0, 0, 1, z},
  117. // {0, 0, 0, 1},
  118. // }).
  119. func (m *Mat4) Translate(p *Mat4, x, y, z float32) {
  120. m[0][0] = p[0][0]
  121. m[0][1] = p[0][1]
  122. m[0][2] = p[0][2]
  123. m[0][3] = p[0][0]*x + p[0][1]*y + p[0][2]*z + p[0][3]
  124. m[1][0] = p[1][0]
  125. m[1][1] = p[1][1]
  126. m[1][2] = p[1][2]
  127. m[1][3] = p[1][0]*x + p[1][1]*y + p[1][2]*z + p[1][3]
  128. m[2][0] = p[2][0]
  129. m[2][1] = p[2][1]
  130. m[2][2] = p[2][2]
  131. m[2][3] = p[2][0]*x + p[2][1]*y + p[2][2]*z + p[2][3]
  132. m[3][0] = p[3][0]
  133. m[3][1] = p[3][1]
  134. m[3][2] = p[3][2]
  135. m[3][3] = p[3][0]*x + p[3][1]*y + p[3][2]*z + p[3][3]
  136. }
  137. // Rotate sets m to a rotation in radians around a specified axis, followed by p.
  138. // It is equivalent to m.Mul(p, affineRotation).
  139. func (m *Mat4) Rotate(p *Mat4, angle Radian, axis *Vec3) {
  140. a := *axis
  141. a.Normalize()
  142. c, s := Cos(float32(angle)), Sin(float32(angle))
  143. d := 1 - c
  144. m.Mul(p, &Mat4{{
  145. c + d*a[0]*a[1],
  146. 0 + d*a[0]*a[1] + s*a[2],
  147. 0 + d*a[0]*a[1] - s*a[1],
  148. 0,
  149. }, {
  150. 0 + d*a[1]*a[0] - s*a[2],
  151. c + d*a[1]*a[1],
  152. 0 + d*a[1]*a[2] + s*a[0],
  153. 0,
  154. }, {
  155. 0 + d*a[2]*a[0] + s*a[1],
  156. 0 + d*a[2]*a[1] - s*a[0],
  157. c + d*a[2]*a[2],
  158. 0,
  159. }, {
  160. 0, 0, 0, 1,
  161. }})
  162. }
  163. func (m *Mat4) LookAt(eye, center, up *Vec3) {
  164. f, s, u := new(Vec3), new(Vec3), new(Vec3)
  165. *f = *center
  166. f.Sub(f, eye)
  167. f.Normalize()
  168. s.Cross(f, up)
  169. s.Normalize()
  170. u.Cross(s, f)
  171. *m = Mat4{
  172. {s[0], u[0], -f[0], 0},
  173. {s[1], u[1], -f[1], 0},
  174. {s[2], u[2], -f[2], 0},
  175. {-s.Dot(eye), -u.Dot(eye), +f.Dot(eye), 1},
  176. }
  177. }