diff --git a/res/modules/internal/maths_inline.lua b/res/modules/internal/maths_inline.lua index ecb77df97..12b3243ea 100644 --- a/res/modules/internal/maths_inline.lua +++ b/res/modules/internal/maths_inline.lua @@ -1,3 +1,8 @@ +local sin = math.sin +local cos = math.cos +local sqrt = math.sqrt +local rad = math.rad + -- =================================================== -- -- ====================== vec3 ======================= -- -- =================================================== -- @@ -252,3 +257,75 @@ function mat4.idt(dst) 0, 0, 0, 1 } end + +function mat4.rotate(...) + local argc = select("#", ...) + + local matrix, axis, angle, dst + + if argc == 2 then + axis, angle = ... + matrix = mat4.idt() + elseif argc == 3 then + matrix, axis, angle = ... + elseif argc == 4 then + matrix, axis, angle, dst = ... + else + error("invalid arguments number (2, 3 or 4 expected)") + end + + angle = rad(angle) + + local x = axis[1] + local y = axis[2] + local z = axis[3] + + local len = sqrt(x*x + y*y + z*z) + if len == 0 then + error("rotation axis has zero length") + end + + x = x / len + y = y / len + z = z / len + + local c = cos(angle) + local s = sin(angle) + local t = 1 - c + + local r00 = t*x*x + c + local r01 = t*x*y - s*z + local r02 = t*x*z + s*y + + local r10 = t*x*y + s*z + local r11 = t*y*y + c + local r12 = t*y*z - s*x + + local r20 = t*x*z - s*y + local r21 = t*y*z + s*x + local r22 = t*z*z + c + + local out = dst or {} + + out[1] = matrix[1]*r00 + matrix[5]*r10 + matrix[9]*r20 + out[2] = matrix[2]*r00 + matrix[6]*r10 + matrix[10]*r20 + out[3] = matrix[3]*r00 + matrix[7]*r10 + matrix[11]*r20 + out[4] = matrix[4]*r00 + matrix[8]*r10 + matrix[12]*r20 + + out[5] = matrix[1]*r01 + matrix[5]*r11 + matrix[9]*r21 + out[6] = matrix[2]*r01 + matrix[6]*r11 + matrix[10]*r21 + out[7] = matrix[3]*r01 + matrix[7]*r11 + matrix[11]*r21 + out[8] = matrix[4]*r01 + matrix[8]*r11 + matrix[12]*r21 + + out[9] = matrix[1]*r02 + matrix[5]*r12 + matrix[9]*r22 + out[10] = matrix[2]*r02 + matrix[6]*r12 + matrix[10]*r22 + out[11] = matrix[3]*r02 + matrix[7]*r12 + matrix[11]*r22 + out[12] = matrix[4]*r02 + matrix[8]*r12 + matrix[12]*r22 + + out[13] = matrix[13] + out[14] = matrix[14] + out[15] = matrix[15] + out[16] = matrix[16] + + return out +end