Add [] to matrixes. Fix 3x3 matrix to match same order as 4x4 matrix.
This commit is contained in:
parent
47a9acad51
commit
7991cea91e
142
src/vmath.nim
142
src/vmath.nim
|
@ -519,6 +519,9 @@ func vec4*(a: Vec2, z = 0.0, w = 0.0): Vec4 =
|
|||
|
||||
type Mat3* = array[9, float32] ## 3x3 Matrix
|
||||
|
||||
template `[]`*(a: Mat3, i, j: int): float32 = a[i * 3 + j ]
|
||||
template `[]=`*(a: Mat3, i, j: int, v: float32) = a[i * 3 + j] = v
|
||||
|
||||
func mat3*(a, b, c, d, e, f, g, h, i: float32): Mat3 =
|
||||
result[0] = a
|
||||
result[1] = b
|
||||
|
@ -564,43 +567,15 @@ func `$`*(a: Mat3): string =
|
|||
{a[6]:.4f}, {a[7]:.4f}, {a[8]:.4f}]"""
|
||||
|
||||
func `*`*(a: Mat3, b: Mat3): Mat3 =
|
||||
let
|
||||
a00 = a[0]
|
||||
a01 = a[1]
|
||||
a02 = a[2]
|
||||
a10 = a[3]
|
||||
a11 = a[4]
|
||||
a12 = a[5]
|
||||
a20 = a[6]
|
||||
a21 = a[7]
|
||||
a22 = a[8]
|
||||
|
||||
b00 = b[0]
|
||||
b01 = b[1]
|
||||
b02 = b[2]
|
||||
b10 = b[3]
|
||||
b11 = b[4]
|
||||
b12 = b[5]
|
||||
b20 = b[6]
|
||||
b21 = b[7]
|
||||
b22 = b[8]
|
||||
|
||||
result[0] = b00 * a00 + b01 * a10 + b02 * a20
|
||||
result[1] = b00 * a01 + b01 * a11 + b02 * a21
|
||||
result[2] = b00 * a02 + b01 * a12 + b02 * a22
|
||||
|
||||
result[3] = b10 * a00 + b11 * a10 + b12 * a20
|
||||
result[4] = b10 * a01 + b11 * a11 + b12 * a21
|
||||
result[5] = b10 * a02 + b11 * a12 + b12 * a22
|
||||
|
||||
result[6] = b20 * a00 + b21 * a10 + b22 * a20
|
||||
result[7] = b20 * a01 + b21 * a11 + b22 * a21
|
||||
result[8] = b20 * a02 + b21 * a12 + b22 * a22
|
||||
|
||||
func `*`*(m: Mat3, v: Vec3): Vec3 =
|
||||
result.x = m[0]*v.x + m[1]*v.y + m[2]*v.z
|
||||
result.y = m[3]*v.x + m[4]*v.y + m[5]*v.z
|
||||
result.z = m[6]*v.x + m[7]*v.y + m[8]*v.z
|
||||
result[0, 0] += b[0, 0] * a[0, 0] + b[0, 1] * a[1, 0] + b[0, 2] * a[2, 0]
|
||||
result[0, 1] += b[0, 0] * a[0, 1] + b[0, 1] * a[1, 1] + b[0, 2] * a[2, 1]
|
||||
result[0, 2] += b[0, 0] * a[0, 2] + b[0, 1] * a[1, 2] + b[0, 2] * a[2, 2]
|
||||
result[1, 0] += b[1, 0] * a[0, 0] + b[1, 1] * a[1, 0] + b[1, 2] * a[2, 0]
|
||||
result[1, 1] += b[1, 0] * a[0, 1] + b[1, 1] * a[1, 1] + b[1, 2] * a[2, 1]
|
||||
result[1, 2] += b[1, 0] * a[0, 2] + b[1, 1] * a[1, 2] + b[1, 2] * a[2, 2]
|
||||
result[2, 0] += b[2, 0] * a[0, 0] + b[2, 1] * a[1, 0] + b[2, 2] * a[2, 0]
|
||||
result[2, 1] += b[2, 0] * a[0, 1] + b[2, 1] * a[1, 1] + b[2, 2] * a[2, 1]
|
||||
result[2, 2] += b[2, 0] * a[0, 2] + b[2, 1] * a[1, 2] + b[2, 2] * a[2, 2]
|
||||
|
||||
func scale*(a: Mat3, v: Vec2): Mat3 =
|
||||
result[0] = v.x * a[0]
|
||||
|
@ -630,10 +605,10 @@ func rotationMat3*(angle: float32): Mat3 =
|
|||
sin = sin(angle)
|
||||
cos = cos(angle)
|
||||
result[0] = cos
|
||||
result[1] = -sin
|
||||
result[1] = sin
|
||||
result[2] = 0
|
||||
|
||||
result[3] = sin
|
||||
result[3] = -sin
|
||||
result[4] = cos
|
||||
result[5] = 0
|
||||
|
||||
|
@ -646,11 +621,36 @@ func rotate*(a: Mat3, angle: float32): Mat3 =
|
|||
a * rotationMat3(angle)
|
||||
|
||||
func `*`*(a: Mat3, b: Vec2): Vec2 =
|
||||
result.x = a[0]*b.x + a[1]*b.y + a[6]
|
||||
result.y = a[3]*b.x + a[4]*b.y + a[7]
|
||||
result.x = a[0, 0]*b.x + a[1, 0]*b.y + a[2, 0]
|
||||
result.y = a[0, 1]*b.x + a[1, 1]*b.y + a[2, 1]
|
||||
|
||||
func `*`*(a: Mat3, b: Vec3): Vec3 =
|
||||
result.x = a[0, 0]*b.x + a[1, 0]*b.y + a[2, 0]*b.z
|
||||
result.y = a[0, 1]*b.x + a[1, 1]*b.y + a[2, 1]*b.z
|
||||
result.z = a[0, 2]*b.x + a[1, 2]*b.y + a[2, 2]*b.z
|
||||
|
||||
func inverse*(a: Mat3): Mat3 =
|
||||
let determinant = (
|
||||
a[0, 0] * (a[1, 1] * a[2, 2] - a[2, 1] * a[1, 2]) -
|
||||
a[0, 1] * (a[1, 0] * a[2, 2] - a[1, 2] * a[2, 0]) +
|
||||
a[0, 2] * (a[1, 0] * a[2, 1] - a[1, 1] * a[2, 0])
|
||||
)
|
||||
let invDet = 1 / determinant
|
||||
result[0, 0] = (a[1, 1] * a[2, 2] - a[2, 1] * a[1, 2]) * invDet
|
||||
result[1, 0] = -(a[0, 1] * a[2, 2] - a[0, 2] * a[2, 1]) * invDet
|
||||
result[2, 0] = (a[0, 1] * a[1, 2] - a[0, 2] * a[1, 1]) * invDet
|
||||
result[0, 1] = -(a[1, 0] * a[2, 2] - a[1, 2] * a[2, 0]) * invDet
|
||||
result[1, 1] = (a[0, 0] * a[2, 2] - a[0, 2] * a[2, 0]) * invDet
|
||||
result[2, 1] = -(a[0, 0] * a[1, 2] - a[1, 0] * a[0, 2]) * invDet
|
||||
result[0, 2] = (a[1, 0] * a[2, 1] - a[2, 0] * a[1, 1]) * invDet
|
||||
result[1, 2] = -(a[0, 0] * a[2, 1] - a[2, 0] * a[0, 1]) * invDet
|
||||
result[2, 2] = (a[0, 0] * a[1, 1] - a[1, 0] * a[0, 1]) * invDet
|
||||
|
||||
type Mat4* = array[16, float32] ## 4x4 Matrix - OpenGL row order
|
||||
|
||||
template `[]`*(a: Mat4, i, j: int): float32 = a[i * 4 + j ]
|
||||
template `[]=`*(a: Mat4, i, j: int, v: float32) = a[i * 4 + j] = v
|
||||
|
||||
func mat4*(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
|
||||
v14, v15: float32): Mat4 =
|
||||
result[0] = v0
|
||||
|
@ -776,7 +776,7 @@ func inverse*(a: Mat4): Mat4 =
|
|||
b10 = a21*a33 - a23*a31
|
||||
b11 = a22*a33 - a23*a32
|
||||
|
||||
# Calculate the invese determinant
|
||||
# Calculate the inverse determinant.
|
||||
var invDet = 1.0/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06)
|
||||
|
||||
result[00] = (+a11*b11 - a12*b10 + a13*b09)*invDet
|
||||
|
@ -1113,6 +1113,64 @@ func lookAt*(eye, center, up: Vec3): Mat4 =
|
|||
result[14] = -(z0*eyex + z1*eyey + z2*eyez)
|
||||
result[15] = 1
|
||||
|
||||
func mat3*(m: Mat4): Mat3 =
|
||||
## Gets rotation and translation, ignoring z coordinates.
|
||||
result[0, 0] = m[0, 0]
|
||||
result[0, 1] = m[0, 1]
|
||||
result[0, 2] = 0
|
||||
result[1, 0] = m[1, 0]
|
||||
result[1, 1] = m[1, 1]
|
||||
result[1, 2] = 0
|
||||
result[2, 0] = m[3, 0]
|
||||
result[2, 1] = m[3, 1]
|
||||
result[2, 2] = 0
|
||||
|
||||
func mat3Rotation*(m: Mat4): Mat3 =
|
||||
## Gets the rotational part of the 4x4 matrix.
|
||||
result[0, 0] = m[0, 0]
|
||||
result[0, 1] = m[0, 1]
|
||||
result[0, 2] = m[0, 2]
|
||||
result[1, 0] = m[1, 0]
|
||||
result[1, 1] = m[1, 1]
|
||||
result[1, 2] = m[1, 2]
|
||||
result[2, 0] = m[2, 0]
|
||||
result[2, 1] = m[2, 1]
|
||||
result[2, 2] = m[2, 2]
|
||||
|
||||
func mat4*(m: Mat3): Mat4 =
|
||||
## Takes a 2d Mat3 with position and converts to a 3d matrix.
|
||||
result[0, 0] = m[0, 0]
|
||||
result[0, 1] = m[0, 1]
|
||||
result[0, 2] = 0
|
||||
result[0, 3] = 0
|
||||
|
||||
result[1, 0] = m[1, 0]
|
||||
result[1, 1] = m[1, 1]
|
||||
result[1, 2] = 0
|
||||
result[1, 3] = 0
|
||||
|
||||
result[2, 0] = 0
|
||||
result[2, 1] = 0
|
||||
result[2, 2] = 1
|
||||
result[2, 3] = 0
|
||||
|
||||
result[3, 0] = m[2, 0]
|
||||
result[3, 1] = m[2, 1]
|
||||
result[3, 2] = 0
|
||||
result[3, 3] = 1
|
||||
|
||||
func mat4Rotation*(m: Mat3): Mat4 =
|
||||
## Gets the rotational part of the 3x3 matrix into a 4x4 matrix.
|
||||
result[0, 0] = m[0, 0]
|
||||
result[0, 1] = m[0, 1]
|
||||
result[0, 2] = m[0, 2]
|
||||
result[1, 0] = m[1, 0]
|
||||
result[1, 1] = m[1, 1]
|
||||
result[1, 2] = m[1, 2]
|
||||
result[2, 0] = m[2, 0]
|
||||
result[2, 1] = m[2, 1]
|
||||
result[2, 2] = m[2, 2]
|
||||
|
||||
func `$`*(a: Mat4): string =
|
||||
&"""[{a[0]:.5f}, {a[1]:.5f}, {a[2]:.5f}, {a[3]:.5f},
|
||||
{a[4]:.5f}, {a[5]:.5f}, {a[6]:.5f}, {a[7]:.5f},
|
||||
|
|
16
tests/testm3.nim
Normal file
16
tests/testm3.nim
Normal file
|
@ -0,0 +1,16 @@
|
|||
import vmath
|
||||
|
||||
var a3 = mat3(0.9659258723258972, -0.258819043636322, 0.0, 0.258819043636322, 0.9659258723258972, 0.0, -25.00000953674316, 70.09619140625, 1.0)
|
||||
var b3 = mat3(0.9659258127212524, 0.258819043636322, 0.0, -0.258819043636322, 0.9659258127212524, 0.0, 77.64571380615234, 0.0, 1.0)
|
||||
|
||||
echo "Test Mat3 * Mat3:"
|
||||
echo (a3.mat4 * b3.mat4).mat3
|
||||
echo a3 * b3
|
||||
|
||||
echo (mat3(1,2,3,4,5,6,7,8,9).mat4Rotation * mat3(10,20,30,40,50,60,70,80,90).mat4Rotation).mat3Rotation
|
||||
echo mat3(1,2,3,4,5,6,7,8,9) * mat3(10,20,30,40,50,60,70,80,90)
|
||||
|
||||
echo "Test Mat3 * Vec2 and Vec3:"
|
||||
echo a3.mat4 * vec3(77.64571380615234, 0, 1)
|
||||
echo a3 * vec2(77.64571380615234, 0)
|
||||
echo a3 * vec3(77.64571380615234, 0, 1.0)
|
Loading…
Reference in a new issue