add basic rotation operations to matrices
This commit is contained in:
parent
9501462e51
commit
63cafc0bda
@ -254,10 +254,76 @@ local abs = math.abs
|
||||
-- @function set_rot_luanti_entity
|
||||
mat4.set_rot_luanti_entity = mat4.set_rot_zxy
|
||||
|
||||
--- rotates a matrix on the ZX matrix (otherwise known as yaw in coordinate systems where Y is up)
|
||||
function mat4.rotate_Y(m, r, use_identity)
|
||||
local cy = cos(r)
|
||||
local sy = sin(r)
|
||||
tm4[1] = m[3]*sy + m[1]*cy
|
||||
tm4[2] = m[2]
|
||||
tm4[3] = m[3]*cy - m[1]*sy
|
||||
tm4[4] = m[4]
|
||||
|
||||
tm4[5] = m[7]*sy + m[5]*cy
|
||||
tm4[6] = m[6]
|
||||
tm4[7] = m[7]*cy - m[5]*sy
|
||||
tm4[8] = m[8]
|
||||
|
||||
tm4[9] = m[11]*sy + m[9]*cy
|
||||
tm4[10] = m[10]
|
||||
tm4[11] = m[11]*cy - m[9]*sy
|
||||
tm4[12] = m[12]
|
||||
|
||||
for i = 1, 12 do
|
||||
m[i] = tm4[i]
|
||||
end
|
||||
return m
|
||||
end
|
||||
function mat4.rotate_Z(m, r, use_identity)
|
||||
local cz = cos(r)
|
||||
local sz = sin(r)
|
||||
tm4[1] = m[1]*cz - m[2]*sz
|
||||
tm4[2] = m[1]*sz + m[2]*cz
|
||||
tm4[3] = m[3]
|
||||
tm4[4] = m[4]
|
||||
|
||||
tm4[5] = m[5]*cz - m[6]*sz
|
||||
tm4[6] = m[5]*sz + m[6]*cz
|
||||
tm4[7] = m[7]
|
||||
tm4[8] = m[8]
|
||||
|
||||
tm4[9] = m[9]*cz - m[10]*sz
|
||||
tm4[10] = m[9]*sz + m[10]*cz
|
||||
tm4[11] = m[11]
|
||||
tm4[12] = m[12]
|
||||
|
||||
for i = 1, 12 do
|
||||
m[i] = tm4[i]
|
||||
end
|
||||
return m
|
||||
end
|
||||
function mat4.rotate_X(m, r, use_identity)
|
||||
local cz = cos(r)
|
||||
local sz = sin(r)
|
||||
tm4[1] = m[1]
|
||||
tm4[2] = m[2]*cz - m[3]*sz
|
||||
tm4[3] = m[2]*sz + m[3]*cz
|
||||
tm4[4] = m[4]
|
||||
|
||||
tm4[5] = m[5]
|
||||
tm4[6] = m[6]*cz - m[7]*sz
|
||||
tm4[7] = m[6]*sz + m[7]*cz
|
||||
tm4[8] = m[8]
|
||||
|
||||
tm4[9] = m[9]
|
||||
tm4[10] = m[10]*cz - m[11]*sz
|
||||
tm4[11] = m[10]*sz + m[11]*cz
|
||||
tm4[12] = m[12]
|
||||
|
||||
for i = 1, 12 do
|
||||
m[i] = tm4[i]
|
||||
end
|
||||
return m
|
||||
end
|
||||
|
||||
--- get the ZXY euler rotation of the given matrix. This is the order that minetest entities are rotated in.
|
||||
-- @tparam matrix the matrix to get the rotation of
|
||||
@ -287,9 +353,6 @@ end
|
||||
mat4.get_rot_luanti_entity = mat4.get_rot_zxy
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- set the rotation of a given matrix in euler in the XYZ application order. This is the rotation order irrlicht uses (i.e. for bones in Luanti)
|
||||
-- @tparam float pitch the clockwise pitch in radians
|
||||
-- @tparam float yaw the clockwise yaw in radians
|
||||
@ -522,6 +585,8 @@ function mul_internal(out, a, b)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local mul_tm4 = mat4.new()
|
||||
--- Multiply N matrices.
|
||||
-- @tparam mat4 out Matrix to store the result
|
||||
-- @tparam table a a mat4 or a list of mat4s
|
||||
@ -535,16 +600,23 @@ function mat4.mul(out, a, b)
|
||||
if #a == 0 then
|
||||
error("incorrect operand, expected two mat4s or list of mat4s but recieved empty table.")
|
||||
else
|
||||
local new_mat = a[#a]
|
||||
for i = #a-1, 1, -1 do
|
||||
new_mat = a[i]*new_mat
|
||||
mul_internal(mul_tm4, a[#a-1], a[#a])
|
||||
for i = #a-2, 1, -1 do
|
||||
mul_internal(mul_tm4, a[i], mul_tm4)
|
||||
end
|
||||
for i=1,16 do
|
||||
out[i] = new_mat[i]
|
||||
out[i] = mul_tm4[i]
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
--- Multiply N matrices.
|
||||
-- @tparam mat4 out Matrix to store the result
|
||||
-- @tparam table a a mat4 or a list of mat4s
|
||||
-- @tparam mat4 b right operand used if param a is a mat4
|
||||
-- @treturn mat4 out multiplied matrix result
|
||||
-- @function multiply
|
||||
mat4.multiply = mat4.mul
|
||||
|
||||
--- Multiply a matrix and a vec3, with perspective division.
|
||||
-- This function uses an implicit 1 for the fourth component.
|
||||
|
@ -1,10 +1,9 @@
|
||||
local cos = math.cos
|
||||
local sin = math.sin
|
||||
local m = leef.math
|
||||
local mat4 = leef.math.mat4
|
||||
|
||||
local pitch_ZY = function(a)
|
||||
local temp = mat4.new()
|
||||
local temp = mat4.identity()
|
||||
temp[6] = cos(a)
|
||||
temp[7] = sin(a)
|
||||
temp[10] = -sin(a)
|
||||
@ -12,7 +11,7 @@ local pitch_ZY = function(a)
|
||||
return temp
|
||||
end
|
||||
local pitch_ZY2 = function(a)
|
||||
local temp = mat4.new()
|
||||
local temp = mat4.identity()
|
||||
temp[6] = cos(a)
|
||||
temp[7] = -sin(a)
|
||||
temp[10] = sin(a)
|
||||
@ -21,7 +20,7 @@ local pitch_ZY2 = function(a)
|
||||
end
|
||||
|
||||
local roll_XY = function(a)
|
||||
local temp = mat4.new()
|
||||
local temp = mat4.identity()
|
||||
temp[1] = cos(a)
|
||||
temp[2] = sin(a)
|
||||
temp[5] = -sin(a)
|
||||
@ -29,7 +28,7 @@ local roll_XY = function(a)
|
||||
return temp
|
||||
end
|
||||
local roll_XY2 = function(a)
|
||||
local temp = mat4.new()
|
||||
local temp = mat4.identity()
|
||||
temp[1] = cos(a)
|
||||
temp[2] = -sin(a)
|
||||
temp[5] = sin(a)
|
||||
@ -37,7 +36,7 @@ local roll_XY2 = function(a)
|
||||
return temp
|
||||
end
|
||||
local yaw_ZX = function(a)
|
||||
local temp = mat4.new()
|
||||
local temp = mat4.identity()
|
||||
temp[1] = cos(a)
|
||||
temp[3] = -sin(a)
|
||||
temp[9] = sin(a)
|
||||
@ -45,7 +44,7 @@ local yaw_ZX = function(a)
|
||||
return temp
|
||||
end
|
||||
local yaw_ZX2 = function(a)
|
||||
local temp = mat4.new()
|
||||
local temp = mat4.identity()
|
||||
temp[1] = cos(a)
|
||||
temp[3] = sin(a)
|
||||
temp[9] = -sin(a)
|
||||
@ -100,7 +99,7 @@ end
|
||||
function leef.math.find_matrix_rotation_order(check_func)
|
||||
--x,y,z
|
||||
local euler = {(math.random()-.5)*math.pi*4, (math.random()-.5)*math.pi*4, (math.random()-.5)*math.pi*4}
|
||||
local output = check_func(mat4.new(), euler[1],euler[2],euler[3])
|
||||
local output = check_func(mat4.identity(), euler[1],euler[2],euler[3])
|
||||
local iter = 0
|
||||
local running_order
|
||||
for _, p_tf in pairs(pitch_transforms) do
|
||||
@ -111,7 +110,7 @@ function leef.math.find_matrix_rotation_order(check_func)
|
||||
iter = iter + 1
|
||||
--intrinsic order is pitch yaw roll for this check, meaning that 1 is assigned to pitch and so fourth.
|
||||
local matrices = {p_tf, y_tf, r_tf}
|
||||
local active_mat = mat4.new()
|
||||
local active_mat = mat4.identity()
|
||||
running_order = nil
|
||||
for i=1,3 do
|
||||
local func = matrices[order[i]]
|
||||
@ -134,14 +133,23 @@ print("================== BEGINNING LUANTI AND IRRLICHT UNIT TESTs =============
|
||||
local find_rot_order = leef.math.find_matrix_rotation_order
|
||||
print("\n checking sanity of tests:")
|
||||
local _tempeuler = {(math.random()-.5)*math.pi*4, (math.random()-.5)*math.pi*4, (math.random()-.5)*math.pi*4}
|
||||
local _testmatrix = leef.math.mat4.set_rot_zxy(mat4.new(), _tempeuler[1],_tempeuler[2],_tempeuler[3])
|
||||
local _testmatrix = leef.math.mat4.set_rot_zxy(mat4.identity(), _tempeuler[1],_tempeuler[2],_tempeuler[3])
|
||||
print("matrix equality check func is sane:", check_matrix_equality(_testmatrix,_testmatrix))
|
||||
print("matrix equality check func tolerance:", matrix_tolerance)
|
||||
|
||||
print("\n Checking rotation orders. Rotation application order is in reverse, these are the literal matrix multiplication order. ")
|
||||
--[[print("\n Checking rotation orders. Rotation application order is in reverse, these are the literal matrix multiplication order. ")
|
||||
print("checking rotation matrix `set_rot_luanti_entity`")
|
||||
find_rot_order(leef.math.mat4.set_rot_luanti_entity)
|
||||
print("checking `set_rot_irrlicht_bone`")
|
||||
find_rot_order(leef.math.mat4.set_rot_irrlicht_bone)
|
||||
find_rot_order(leef.math.mat4.set_rot_irrlicht_bone)]]
|
||||
|
||||
print("checking rotation axis functions `rotate_X` `rotate_Y` and `rotate_Z`")
|
||||
find_rot_order(function(m, x,y,z)
|
||||
return m:rotate_X(x):rotate_Y(y):rotate_Z(z)
|
||||
end)
|
||||
local t = (math.random()-.5)*math.pi*4
|
||||
print("checking `rotate_X`", check_matrix_equality(pitch_ZY(t), mat4.identity():rotate_X(t)))
|
||||
print("checking `rotate_Y`", check_matrix_equality(yaw_ZX(t), mat4.identity():rotate_Y(t)))
|
||||
print("checking `rotate_Z`", check_matrix_equality(roll_XY(t), mat4.identity():rotate_Z(t)))
|
||||
|
||||
print("================== ENDING LUANTI AND IRRLICHT UNIT TESTs =======================")
|
||||
|
@ -51,6 +51,8 @@ print("checking rotation matrix `set_rot_luanti_entity`")
|
||||
find_rot_order(leef.math.mat4.set_rot_luanti_entity)
|
||||
print("checking `set_rot_irrlicht_bone`")
|
||||
find_rot_order(leef.math.mat4.set_rot_irrlicht_bone)
|
||||
print("checking that mul(out, {mat, mat, mat}) performs in correct order. Inputting `XYZ`")
|
||||
find_rot_order(function(m,x,y,z) return mat4.multiply(mat4.identity(), {mat4.identity():rotate_X(x), mat4.identity():rotate_Y(y), mat4.identity():rotate_Z(z)}) end)
|
||||
|
||||
--[[print("check in euler out euler for minetest entitiy matrix rotations")
|
||||
local x,y,z =(math.random()-.5)*math.pi*4,(math.random()-.5)*math.pi*4,(math.random()-.5)*math.pi*4
|
||||
|
Loading…
x
Reference in New Issue
Block a user