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