math.go (2649B)
1 package tofu 2 3 import "math" 4 5 type Vec2 [2]float32 6 type Vec3 [3]float32 7 8 func (v Vec3) Normalize() Vec3 { 9 r := float32(math.Sqrt(float64(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]))) 10 return Vec3{v[0] / r, v[1] / r, v[2] / r} 11 } 12 13 func (v Vec3) Add(w Vec3) Vec3 { 14 return Vec3{v[0] + w[0], v[1] + w[1], v[2] + w[2]} 15 } 16 17 func (v Vec3) Sub(w Vec3) Vec3 { 18 return Vec3{v[0] - w[0], v[1] - w[1], v[2] - w[2]} 19 } 20 21 func (v Vec3) Inverse() Vec3 { 22 return Vec3{-v[0], -v[1], -v[2]} 23 } 24 25 func (v Vec3) Cross(w Vec3) Vec3 { 26 return Vec3{ 27 v[1]*w[2] - v[2]*w[1], 28 v[2]*w[0] - v[0]*w[2], 29 v[0]*w[1] - v[1]*w[0], 30 } 31 } 32 33 func (v Vec3) MulF(x float32) Vec3 { 34 return Vec3{v[0] * x, v[1] * x, v[2] * x} 35 } 36 37 type Vec4 [4]float32 38 39 func (v Vec4) Vec3() Vec3 { 40 return Vec3{v[0], v[1], v[2]} 41 } 42 43 type Mat3 [9]float32 44 45 func Rotate3(rad float32, axis Vec3) Mat3 { 46 x, y, z := axis[0], axis[1], axis[2] 47 c := float32(math.Cos(float64(rad))) 48 d := 1 - c 49 s := float32(math.Sin(float64(rad))) 50 return Mat3{c + x*x*d, y*x*d + z*s, z*x*d - y*s, 51 x*y*d - z*s, c + y*y*d, z*y*d + x*s, 52 x*z*d + y*s, y*z*d - x*s, c + z*z*d} 53 } 54 55 func (m Mat3) MulV(v Vec3) Vec3 { 56 return Vec3{ 57 m[0]*v[0] + m[3]*v[1] + m[6]*v[2], 58 m[1]*v[0] + m[4]*v[1] + m[7]*v[2], 59 m[2]*v[0] + m[5]*v[1] + m[8]*v[2]} 60 } 61 62 // column major 63 type Mat4 [16]float32 64 65 // Mul multiplies m by n and returns newly allocated result. 66 func (m Mat4) Mul(n Mat4) Mat4 { 67 var dst Mat4 68 for i := 0; i < 4; i++ { 69 for j := 0; j < 4; j++ { 70 for k := 0; k < 4; k++ { 71 dst[i+4*j] += m[i+4*k] * n[k+4*j] 72 } 73 } 74 } 75 return dst 76 } 77 78 func (m Mat4) MulVec(v Vec4) Vec4 { 79 return Vec4{ 80 m[0]*v[0] + m[4]*v[1] + m[8]*v[2] + m[12]*v[3], 81 m[1]*v[0] + m[5]*v[1] + m[9]*v[2] + m[13]*v[3], 82 m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14]*v[3], 83 m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15]*v[3], 84 } 85 } 86 87 func Scale(r float32) Mat4 { 88 return Mat4{ 89 r, 0, 0, 0, 90 0, r, 0, 0, 91 0, 0, r, 0, 92 0, 0, 0, 1, 93 } 94 } 95 96 func Translate(v Vec3) Mat4 { 97 var n Mat4 98 n[0] = 1 99 n[5] = 1 100 n[10] = 1 101 n[12] = v[0] 102 n[13] = v[1] 103 n[14] = v[2] 104 n[15] = 1 105 return n 106 } 107 108 func Rotate(rad float32, axis Vec3) Mat4 { 109 x, y, z := axis[0], axis[1], axis[2] 110 c := float32(math.Cos(float64(rad))) 111 d := 1 - c 112 s := float32(math.Sin(float64(rad))) 113 return Mat4{c + x*x*d, y*x*d + z*s, z*x*d - y*s, 0, 114 x*y*d - z*s, c + y*y*d, z*y*d + x*s, 0, 115 x*z*d + y*s, y*z*d - x*s, c + z*z*d, 0, 116 0, 0, 0, 1} 117 } 118 119 func Perspective(fov, asp, min, max float32) Mat4 { 120 tan := float32(math.Tan(float64(fov / 2))) 121 w := min * tan 122 h := w / asp 123 124 var mat Mat4 125 mat[0] = min / w 126 mat[5] = min / h 127 mat[10] = -(max + min) / (max - min) 128 mat[11] = -1 129 mat[14] = -(2 * min * max) / (max - min) 130 return mat 131 }