Refactored mat4 (in progress)

Cleaned up vec2, vec3, quat
This commit is contained in:
karai17 2016-07-18 06:17:42 -03:00
parent 6ced5f397e
commit 46f8261ea0
4 changed files with 388 additions and 320 deletions

View File

@ -1,12 +1,16 @@
--- double 4x4, 1-based, column major matrices
-- @module mat4
local current_folder = (...):gsub('%.[^%.]+$', '') .. "."
local constants = require(current_folder .. "constants")
local vec2 = require(current_folder .. "vec2")
local vec3 = require(current_folder .. "vec3")
local quat = require(current_folder .. "quat")
local mat4 = {}
local modules = (...):gsub('%.[^%.]+$', '') .. "."
local constants = require(modules .. "constants")
local vec2 = require(modules .. "vec2")
local vec3 = require(modules .. "vec3")
local quat = require(modules .. "quat")
local sqrt = math.sqrt
local cos = math.cos
local sin = math.sin
local tan = math.tan
local rad = math.rad
local mat4 = {}
-- Private constructor.
local function new(m)
@ -17,7 +21,7 @@ local function new(m)
0, 0, 0, 0
}
m._m = m
return setmetatable(m, vec3_mt)
return setmetatable(m, mat4_mt)
end
-- Do the check to see if JIT is enabled. If so use the optimized FFI structs.
@ -30,30 +34,33 @@ if type(jit) == "table" and jit.status() then
end
end
function mat4.new(v)
-- Statically allocate a temporary variable used in some of our functions.
local tmp = new()
function mat4.new(a)
local o = new()
local m = o._m
if type(v) == "table" and #v == 16 then
if type(a) == "table" and #a == 16 then
for i=1,16 do
m[i] = tonumber(v[i])
m[i] = tonumber(a[i])
end
elseif type(v) == "table" and #v == 9 then
m[1], m[2], m[3] = v[1], v[2], v[3]
m[5], m[6], m[7] = v[4], v[5], v[6]
m[9], m[10], m[11] = v[7], v[8], v[9]
elseif type(a) == "table" and #a == 9 then
m[1], m[2], m[3] = a[1], a[2], a[3]
m[5], m[6], m[7] = a[4], a[5], a[6]
m[9], m[10], m[11] = a[7], a[8], a[9]
m[16] = 1
elseif type(v) == "table" and type(v[1]) == "table" then
elseif type(a) == "table" and type(a[1]) == "table" then
local idx = 1
for i=1, 4 do
for j=1, 4 do
m[idx] = v[i][j]
for i = 1, 4 do
for j = 1, 4 do
m[idx] = a[i][j]
idx = idx + 1
end
end
else
m[1] = 1
m[6] = 1
m[1] = 1
m[6] = 1
m[11] = 1
m[16] = 1
end
@ -61,87 +68,83 @@ function mat4.new(v)
return o
end
local temp = mat4.new()
function mat4:clone()
return new(self._m)
function mat4.identity()
return new {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
}
end
function mat4.from_axis_angle(angle, axis)
if type(angle) == "table" then
angle, axis = angle:to_axis_angle()
angle, axis = vec3.to_angle_axis(angle)
end
local l = axis:len()
local l = vec3.len(axis)
if l == 0 then
return self
return new()
end
local x, y, z = axis.x / l, axis.y / l, axis.z / l
local c = math.cos(angle)
local s = math.sin(angle)
local m = {
x*x*(1-c)+c, y*x*(1-c)+z*s, x*z*(1-c)-y*s, 0,
x*y*(1-c)-z*s, y*y*(1-c)+c, y*z*(1-c)+x*s, 0,
x*z*(1-c)+y*s, y*z*(1-c)-x*s, z*z*(1-c)+c, 0,
0, 0, 0, 1,
local c = cos(angle)
local s = sin(angle)
return new {
x*x*(1-c)+c, y*x*(1-c)+z*s, x*z*(1-c)-y*s, 0,
x*y*(1-c)-z*s, y*y*(1-c)+c, y*z*(1-c)+x*s, 0,
x*z*(1-c)+y*s, y*z*(1-c)-x*s, z*z*(1-c)+c, 0,
0, 0, 0, 1
}
return new(m)
end
function mat4.from_direction(direction, up)
local forward = direction:normalize()
local side = forward:cross(up):normalize()
local new_up = side:cross(forward):normalize()
local forward = vec3.normalize(vec3(), direction)
local side = vec3.normalize(vec3(), vec3.cross(vec3(), forward, up)
local new_up = vec3.normalize(vec3(), vec3.cross(vec3(), side, forward))
local view = mat4.new()
local m = view._m
m[1] = side.x
m[5] = side.y
m[9] = side.z
local out = new()
out[1] = side.x
out[5] = side.y
out[9] = side.z
out[2] = new_up.x
out[6] = new_up.y
out[10] = new_up.z
out[3] = forward.x
out[7] = forward.y
out[11] = forward.z
out[16] = 1
m[2] = new_up.x
m[6] = new_up.y
m[10] = new_up.z
m[3] = forward.x
m[7] = forward.y
m[11] = forward.z
m[16] = 1
return view
return out
end
function mat4.from_perspective(fovy, aspect, near, far)
assert(aspect ~= 0)
assert(near ~= far)
assert(near ~= far)
local t = math.tan(math.rad(fovy) / 2)
local result = {
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
}
local t = tan(rad(fovy) / 2)
local out = new()
out[1] = 1 / (t * aspect)
out[6] = 1 / t
out[11] = -(far + near) / (far - near)
out[12] = -1
out[15] = -(2 * far * near) / (far - near)
out[16] = 1
result[1] = 1 / (t * aspect)
result[6] = 1 / t
result[11] = -(far + near) / (far - near)
result[12] = -1
result[15] = -(2 * far * near) / (far - near)
result[16] = 1
return mat4.new(result)
return out
end
function mat4.from_ortho(left, right, top, bottom, near, far)
local out = mat4.new()
out[1] = 2 / (right - left)
out[6] = 2 / (top - bottom)
out[11] = -2 / (far - near)
out[13] = -((right + left) / (right - left))
out[14] = -((top + bottom) / (top - bottom))
out[15] = -((far + near) / (far - near))
out[16] = 1
local out = new()
out[1] = 2 / (right - left)
out[6] = 2 / (top - bottom)
out[11] = -2 / (far - near)
out[13] = -((right + left) / (right - left))
out[14] = -((top + bottom) / (top - bottom))
out[15] = -((far + near) / (far - near))
out[16] = 1
return out
end
@ -150,6 +153,7 @@ function mat4.from_hmd_perspective(tanHalfFov, zNear, zFar, flipZ, farAtInfinity
-- CPML is right-handed and intended for GL, so these don't need to be arguments.
local rightHanded = true
local isOpenGL = true
local function CreateNDCScaleAndOffsetFromFov(tanHalfFov)
x_scale = 2 / (tanHalfFov.LeftTan + tanHalfFov.RightTan)
x_offset = (tanHalfFov.LeftTan - tanHalfFov.RightTan) * x_scale * 0.5
@ -173,9 +177,9 @@ function mat4.from_hmd_perspective(tanHalfFov, zNear, zFar, flipZ, farAtInfinity
end
-- A projection matrix is very like a scaling from NDC, so we can start with that.
local scaleAndOffset = CreateNDCScaleAndOffsetFromFov(tanHalfFov)
local scaleAndOffset = CreateNDCScaleAndOffsetFromFov(tanHalfFov)
local handednessScale = rightHanded and -1.0 or 1.0
local projection = mat4.new()
local projection = new()
-- Produces X result, mapping clip edges to [-w,+w]
projection[1] = scaleAndOffset.Scale.x
@ -224,78 +228,146 @@ function mat4.from_hmd_perspective(tanHalfFov, zNear, zFar, flipZ, farAtInfinity
projection[15] = handednessScale
projection[16] = 0
return projection:transpose()
return mat4.transpose(projection)
end
function mat4.compose_world_matrix(t, rot, scale)
local angle, axis = rot:to_axis_angle()
local l = axis:len()
if l == 0 then
return self
end
local x, y, z = axis.x / l, axis.y / l, axis.z / l
local c = math.cos(angle)
local s = math.sin(angle)
local m = {
x*x*(1-c)+c, y*x*(1-c)+z*s, x*z*(1-c)-y*s, 0,
x*y*(1-c)-z*s, y*y*(1-c)+c, y*z*(1-c)+x*s, 0,
x*z*(1-c)+y*s, y*z*(1-c)-x*s, z*z*(1-c)+c, 0,
t.x, t.y, t.z, 1,
}
return new(m)
end
function mat4:to_quat()
local m = self:transpose():to_vec4s()
print(m[1][1], m[2][2], m[3][3])
local w = math.sqrt(1 + m[1][1] + m[2][2] + m[3][3]) / 2
local scale = w * 4
return quat.new(
m[3][2] - m[2][3] / scale,
m[1][3] - m[3][1] / scale,
m[2][1] - m[1][2] / scale,
w
):normalize()
function mat4.clone(a)
return new(a)
end
function mat4.mul(out, a, b)
out[1] = a[1]*b[1]+a[2]*b[5]+a[3]*b[9]+a[4]*b[13]
out[2] = a[1]*b[2]+a[2]*b[6]+a[3]*b[10]+a[4]*b[14]
out[3] = a[1]*b[3]+a[2]*b[7]+a[3]*b[11]+a[4]*b[15]
out[4] = a[1]*b[4]+a[2]*b[8]+a[3]*b[12]+a[4]*b[16]
out[1] = a[1] * b[1] + a[2] * b[5] + a [3] * b[9] + a[4] * b[13]
out[2] = a[1] * b[2] + a[2] * b[6] + a [3] * b[10] + a[4] * b[14]
out[3] = a[1] * b[3] + a[2] * b[7] + a [3] * b[11] + a[4] * b[15]
out[4] = a[1] * b[4] + a[2] * b[8] + a [3] * b[12] + a[4] * b[16]
out[5] = a[5] * b[1] + a[6] * b[5] + a [7] * b[9] + a[8] * b[13]
out[6] = a[5] * b[2] + a[6] * b[6] + a [7] * b[10] + a[8] * b[14]
out[7] = a[5] * b[3] + a[6] * b[7] + a [7] * b[11] + a[8] * b[15]
out[8] = a[5] * b[4] + a[6] * b[8] + a [7] * b[12] + a[8] * b[16]
out[9] = a[9] * b[1] + a[10] * b[5] + a[11] * b[9] + a[12] * b[13]
out[10] = a[9] * b[2] + a[10] * b[6] + a[11] * b[10] + a[12] * b[14]
out[11] = a[9] * b[3] + a[10] * b[7] + a[11] * b[11] + a[12] * b[15]
out[12] = a[9] * b[4] + a[10] * b[8] + a[11] * b[12] + a[12] * b[16]
out[13] = a[13] * b[1] + a[14] * b[5] + a[15] * b[9] + a[16] * b[13]
out[14] = a[13] * b[2] + a[14] * b[6] + a[15] * b[10] + a[16] * b[14]
out[15] = a[13] * b[3] + a[14] * b[7] + a[15] * b[11] + a[16] * b[15]
out[16] = a[13] * b[4] + a[14] * b[8] + a[15] * b[12] + a[16] * b[16]
out[5] = a[5]*b[1]+a[6]*b[5]+a[7]*b[9]+a[8]*b[13]
out[6] = a[5]*b[2]+a[6]*b[6]+a[7]*b[10]+a[8]*b[14]
out[7] = a[5]*b[3]+a[6]*b[7]+a[7]*b[11]+a[8]*b[15]
out[8] = a[5]*b[4]+a[6]*b[8]+a[7]*b[12]+a[8]*b[16]
out[9] = a[9]*b[1]+a[10]*b[5]+a[11]*b[9]+a[12]*b[13]
out[10] = a[9]*b[2]+a[10]*b[6]+a[11]*b[10]+a[12]*b[14]
out[11] = a[9]*b[3]+a[10]*b[7]+a[11]*b[11]+a[12]*b[15]
out[12] = a[9]*b[4]+a[10]*b[8]+a[11]*b[12]+a[12]*b[16]
out[13] = a[13]*b[1]+a[14]*b[5]+a[15]*b[9]+a[16]*b[13]
out[14] = a[13]*b[2]+a[14]*b[6]+a[15]*b[10]+a[16]*b[14]
out[15] = a[13]*b[3]+a[14]*b[7]+a[15]*b[11]+a[16]*b[15]
out[16] = a[13]*b[4]+a[14]*b[8]+a[15]*b[12]+a[16]*b[16]
return out
end
function mat4.translate(out, a, t)
local m = new {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
function mat4.invert(out, a)
out[1] = a[6] * a[11] * a[16] - a[6] *
a[12] * a[15] - a[10] * a[7] * a[16] +
a[10] * a[8] * a[15] + a[14] * a[7] *
a[12] - a[14] * a[8] * a[11]
out[5] = -a[5] * a[11] * a[16] + a[5] *
a[12] * a[15] + a[9] * a[7] * a[16] -
a[9] * a[8] * a[15] - a[13] * a[7] *
a[12] + a[13] * a[8] * a[11]
out[9] = a[5] * a[10] * a[16] - a[5] *
a[12] * a[14] - a[9] * a[6] * a[16] +
a[9] * a[8] * a[14] + a[13] * a[6] *
a[12] - a[13] * a[8] * a[10]
out[13] = -a[5] * a[10] * a[15] + a[5] *
a[11] * a[14] + a[9] * a[6] * a[15] -
a[9] * a[7] * a[14] - a[13] * a[6] *
a[11] + a[13] * a[7] * a[10]
out[2] = -a[2] * a[11] * a[16] + a[2] *
a[12] * a[15] + a[10] * a[3] * a[16] -
a[10] * a[4] * a[15] - a[14] * a[3] *
a[12] + a[14] * a[4] * a[11]
out[6] = a[1] * a[11] * a[16] - a[1] *
a[12] * a[15] - a[9] * a[3] * a[16] +
a[9] * a[4] * a[15] + a[13] * a[3] *
a[12] - a[13] * a[4] * a[11]
out[10] = -a[1] * a[10] * a[16] + a[1] *
a[12] * a[14] + a[9] * a[2] * a[16] -
a[9] * a[4] * a[14] - a[13] * a[2] *
a[12] + a[13] * a[4] * a[10]
out[14] = a[1] * a[10] * a[15] - a[1] *
a[11] * a[14] - a[9] * a[2] * a[15] +
a[9] * a[3] * a[14] + a[13] * a[2] *
a[11] - a[13] * a[3] * a[10]
out[3] = a[2] * a[7] * a[16] - a[2] *
a[8] * a[15] - a[6] * a[3] * a[16] +
a[6] * a[4] * a[15] + a[14] * a[3] *
a[8] - a[14] * a[4] * a[7]
out[7] = -a[1] * a[7] * a[16] + a[1] *
a[8] * a[15] + a[5] * a[3] * a[16] -
a[5] * a[4] * a[15] - a[13] * a[3] *
a[8] + a[13] * a[4] * a[7]
out[11] = a[1] * a[6] * a[16] - a[1] *
a[8] * a[14] - a[5] * a[2] * a[16] +
a[5] * a[4] * a[14] + a[13] * a[2] *
a[8] - a[13] * a[4] * a[6]
out[15] = -a[1] * a[6] * a[15] + a[1] *
a[7] * a[14] + a[5] * a[2] * a[15] -
a[5] * a[3] * a[14] - a[13] * a[2] *
a[7] + a[13] * a[3] * a[6]
out[4] = -a[2] * a[7] * a[12] + a[2] *
a[8] * a[11] + a[6] * a[3] * a[12] -
a[6] * a[4] * a[11] - a[10] * a[3] *
a[8] + a[10] * a[4] * a[7]
out[8] = a[1] * a[7] * a[12] - a[1] *
a[8] * a[11] - a[5] * a[3] * a[12] +
a[5] * a[4] * a[11] + a[9] * a[3] *
a[8] - a[9] * a[4] * a[7]
out[12] = -a[1] * a[6] * a[12] + a[1] *
a[8] * a[10] + a[5] * a[2] * a[12] -
a[5] * a[4] * a[10] - a[9] * a[2] *
a[8] + a[9] * a[4] * a[6]
out[16] = a[1] * a[6] * a[11] - a[1] *
a[7] * a[10] - a[5] * a[2] * a[11] +
a[5] * a[3] * a[10] + a[9] * a[2] *
a[7] - a[9] * a[3] * a[6]
local det = a[1] * out[1] + a[2] * out[5] + a[3] * out[9] + a[4] * out[13]
if det == 0 then return a end
det = 1 / det
for i = 1, 16 do
out[i] = out[i] * det
end
return out
end
function mat4.compose_world_matrix(t, rot, scale)
local angle, axis = vec3.to_angle_axis(rot)
local l = vec3.len(axis)
if l == 0 then
return new()
end
local x, y, z = axis.x / l, axis.y / l, axis.z / l
local c = cos(angle)
local s = sin(angle)
return new {
x*x*(1-c)+c, y*x*(1-c)+z*s, x*z*(1-c)-y*s, 0,
x*y*(1-c)-z*s, y*y*(1-c)+c, y*z*(1-c)+x*s, 0,
x*z*(1-c)+y*s, y*z*(1-c)-x*s, z*z*(1-c)+c, 0,
t.x, t.y, t.z, 1
}
return mat4.mul(out, a, m)
end
function mat4.scale(out, a, s)
@ -309,145 +381,106 @@ function mat4.scale(out, a, s)
return mat4.mul(out, a, m)
end
-- Inverse of matrix. Tested OK
function mat4:invert()
local out = mat4()
out[1] = self[6] * self[11] * self[16] - self[6] * self[12] * self[15] -
self[10] * self[7] * self[16] + self[10] * self[8] * self[15] + self[14]
* self[7] * self[12] - self[14] * self[8] * self[11]
out[5] = -self[5] * self[11] * self[16] + self[5] * self[12] * self[15] +
self[9] * self[7] * self[16] - self[9] * self[8] * self[15] - self[13] *
self[7] * self[12] + self[13] * self[8] * self[11]
out[9] = self[5] * self[10] * self[16] - self[5] * self[12] * self[14] -
self[9] * self[6] * self[16] + self[9] * self[8] * self[14] + self[13] *
self[6] * self[12] - self[13] * self[8] * self[10]
out[13] = -self[5] * self[10] * self[15] + self[5] * self[11] * self[14] +
self[9] * self[6] * self[15] - self[9] * self[7] * self[14] - self[13] *
self[6] * self[11] + self[13] * self[7] * self[10]
out[2] = -self[2] * self[11] * self[16] + self[2] * self[12] * self[15] +
self[10] * self[3] * self[16] - self[10] * self[4] * self[15] - self[14] *
self[3] * self[12] +self[14] * self[4] * self[11]
out[6] = self[1] * self[11] * self[16] - self[1] * self[12] * self[15] -
self[9] * self[3] * self[16] + self[9] * self[4] * self[15] + self[13] *
self[3] * self[12] - self[13] * self[4] * self[11]
out[10] = -self[1] * self[10] * self[16] + self[1] * self[12] * self[14] +
self[9] * self[2] * self[16] - self[9] * self[4] * self[14] - self[13] *
self[2] * self[12] + self[13] * self[4] * self[10]
out[14] = self[1] * self[10] * self[15] - self[1] * self[11] * self[14] -
self[9] * self[2] * self[15] + self[9] * self[3] * self[14] + self[13] *
self[2] * self[11] - self[13] * self[3] * self[10]
out[3] = self[2] * self[7] * self[16] - self[2] * self[8] * self[15] -
self[6] * self[3] * self[16] + self[6] * self[4] * self[15] + self[14] *
self[3] * self[8] - self[14] * self[4] * self[7]
out[7] = -self[1] * self[7] * self[16] + self[1] * self[8] * self[15] +
self[5] * self[3] * self[16] - self[5] * self[4] * self[15] - self[13] *
self[3] * self[8] + self[13] * self[4] * self[7]
out[11] = self[1] * self[6] * self[16] - self[1] * self[8] * self[14] -
self[5] * self[2] * self[16] + self[5] * self[4] * self[14] + self[13] *
self[2] * self[8] - self[13] * self[4] * self[6]
out[15] = -self[1] * self[6] * self[15] + self[1] * self[7] * self[14] +
self[5] * self[2] * self[15] - self[5] * self[3] * self[14] - self[13] *
self[2] * self[7] + self[13] * self[3] * self[6]
out[4] = -self[2] * self[7] * self[12] + self[2] * self[8] * self[11] +
self[6] * self[3] * self[12] - self[6] * self[4] * self[11] - self[10] *
self[3] * self[8] + self[10] * self[4] * self[7]
out[8] = self[1] * self[7] * self[12] - self[1] * self[8] * self[11] -
self[5] * self[3] * self[12] + self[5] * self[4] * self[11] +self[9] *
self[3] * self[8] - self[9] * self[4] * self[7]
out[12] = -self[1] * self[6] * self[12] + self[1] * self[8] * self[10] +
self[5] * self[2] * self[12] - self[5] * self[4] * self[10] - self[9] *
self[2] * self[8] + self[9] * self[4] * self[6]
out[16] = self[1] * self[6] * self[11] - self[1] * self[7] * self[10] -
self[5] * self[2] * self[11] + self[5] * self[3] * self[10] + self[9] *
self[2] * self[7] - self[9] * self[3] * self[6]
local det = self[1] * out[1] + self[2] * out[5] + self[3] * out[9] + self[4] * out[13]
if det == 0 then return self end
det = 1.0 / det
for i = 1, 16 do
out[i] = out[i] * det
function mat4.rotate(out, a, angle, axis)
if type(angle) == "table" then
angle, axis = vec3.to_angle_axis(angle)
end
local l = vec3.len(axis)
if l == 0 then
return a
end
local x, y, z = axis.x / l, axis.y / l, axis.z / l
local c = cos(angle)
local s = sin(angle)
local m = {
x*x*(1-c)+c, y*x*(1-c)+z*s, x*z*(1-c)-y*s, 0,
x*y*(1-c)-z*s, y*y*(1-c)+c, y*z*(1-c)+x*s, 0,
x*z*(1-c)+y*s, y*z*(1-c)-x*s, z*z*(1-c)+c, 0,
0, 0, 0, 1,
}
return mat4.mul(out, a, m)
end
function mat4.translate(out, a, t)
local m = new {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
t.x, t.y, t.z, 1
}
return mat4.mul(out, a, m)
end
function mat4.shear(out, a, yx, zx, xy, zy, xz, yz)
local yx = yx or 0
local zx = zx or 0
local xy = xy or 0
local zy = zy or 0
local xz = xz or 0
local yz = yz or 0
local m = {
1, yx, zx, 0,
xy, 1, zy, 0,
xz, yz, 1, 0,
0, 0, 0, 1
}
return mat4.mul(out, a, m)
end
function mat4.look_at(a, eye, center, up)
local forward = vec3.normalize(vec3(), center - eye)
local side = vec3.normalize(vec3(), vec3.cross(vec3(), forward, up)
local new_up = vec3.normalize(vec3(), vec3.cross(vec3(), side, forward))
local view = new()
view[1] = side.x
view[5] = side.y
view[9] = side.z
view[2] = new_up.x
view[6] = new_up.y
view[10] = new_up.z
view[3] = -forward.x
view[7] = -forward.y
view[11] = -forward.z
view[16] = 1
local out = mat4.mul(new(), mat4.translate(new(), -eye - forward), view)
return mat4.mul(out, out, a)
end
function mat4.transpose(out, a)
out[1] = a[1]
out[2] = a[5]
out[3] = a[9]
out[4] = a[13]
out[5] = a[2]
out[6] = a[6]
out[7] = a[10]
out[8] = a[14]
out[9] = a[3]
out[10] = a[7]
out[11] = a[11]
out[12] = a[15]
out[13] = a[4]
out[14] = a[8]
out[15] = a[12]
out[16] = a[16]
return out
end
function mat4:look_at(eye, center, up)
local forward = (center - eye):normalize()
local side = forward:cross(up):normalize()
local new_up = side:cross(forward):normalize()
local view = mat4()
view[1] = side.x
view[5] = side.y
view[9] = side.z
view[2] = new_up.x
view[6] = new_up.y
view[10] = new_up.z
view[3] = -forward.x
view[7] = -forward.y
view[11] = -forward.z
view[16] = 1
local out = mat4():translate(-eye - forward) * view
return out * self
end
function mat4.transpose(out, a)
do
return new {
self[1], self[5], self[9], self[13],
self[2], self[6], self[10], self[14],
self[3], self[7], self[11], self[15],
self[4], self[8], self[12], self[16]
}
end
out[1] = a[1]
out[2] = a[5]
out[3] = a[9]
return mat4(m)
end
function mat4:__eq(b)
do return false end
local abs = math.abs
for i=1, 16 do
if true then
return false
end
end
return true
end
function mat4:__tostring()
function mat4.tostring()
local str = "[ "
for i, v in ipairs(self) do
for i, v in ipairs(a) do
str = str .. string.format("%2.5f", v)
if i < #self then
if i < #a then
str = str .. ", "
end
end
@ -455,22 +488,58 @@ function mat4:__tostring()
return str
end
function mat4:__unm()
return self:invert()
function mat4.to_quat(a)
local m = mat4.to_vec4s(mat4.transpose(out, a))
local w = sqrt(1 + m[1][1] + m[2][2] + m[3][3]) / 2
local scale = w * 4
return quat.normalize(quat(), quat.new(
m[3][2] - m[2][3] / scale,
m[1][3] - m[3][1] / scale,
m[2][1] - m[1][2] / scale,
w
))
end
-- Multiply mat4 by a mat4. Tested OK
function mat4:__mul(m)
if #m == 4 then
local tmp = matrix_mult_nxn(self:transpose():to_vec4s(), { {m[1]}, {m[2]}, {m[3]}, {m[4]} })
local v = {}
for i=1, 4 do
v[i] = tmp[i][1]
local mat4_mt = {}
mat4_mt.__index = mat4
mat4_mt.__tostring = mat4.tostring
function mat4_mt.__call(a)
return mat4.new(a)
end
function mat4_mt.__tostring(a)
return mat4.tostring(a)
end
function mat4_mt.__unm(a)
return mat4.invert(new(), a)
end
function mat4_mt.__eq(a, b)
assert(mat4.ismat4(a), "__eq: Wrong argument type for left hand operant. (<cpml.mat4> expected)")
assert(mat4.ismat4(b), "__eq: Wrong argument type for right hand operant. (<cpml.mat4> expected)")
for i = 1, 16 do
if a[i] ~= b[i] then
return false
end
return v
end
return true
end
return mat4
function mat4_mt.__mul(a, b)
assert(mat4.ismat4(a), "__mul: Wrong argument type for left hand operant. (<cpml.mat4> expected)")
assert(mat4.ismat4(b), "__mul: Wrong argument type for right hand operant. (<cpml.mat4> expected)")
return mat4.mul(new(), a, b)
end
if status then
ffi.metatype(new, mat4_mt)
end
return setmetatable({}, mat4_mt)

View File

@ -342,7 +342,10 @@ end
-- @treturn boolean
function quat.isquat(q)
return
type(v) == "table" and
(
type(v) == "table" or
type(v) == "cdata"
) and
type(v.x) == "number" and
type(v.y) == "number" and
type(v.z) == "number" and

View File

@ -1,12 +1,16 @@
--- A 2 component vector.
-- @module vec2
local atan2, sqrt,cos, sin, pi = math.atan2, math.sqrt, math.cos, math,sin, math.pi
local vec2 = {}
local atan2 = math.atan2
local sqrt = math.sqrt
local cos = math.cos
local sin = math.sin
local pi = math.pi
local vec2 = {}
-- Private constructor.
local function new(x, y)
local v = {}
local v = {}
v.x, v.y = x, y
return setmetatable(v, vec2_mt)
end
@ -241,6 +245,10 @@ function vec2_mt.__call(self, x, y)
return vec2.new(x, y)
end
function vec2_mt.__tostring(a)
return vec2.tostring(a)
end
function vec2_mt.__unm(a)
return vec2.new(-a.x, -a.y)
end
@ -256,18 +264,14 @@ function vec2_mt.__add(a, b)
assert(vec2.isvec2(a), "__add: Wrong argument type for left hand operant. (<cpml.vec2> expected)")
assert(vec2.isvec2(b), "__add: Wrong argument type for right hand operant. (<cpml.vec2> expected)")
local temp = vec2.new()
vec2.add(temp, a, b)
return temp
return vec2.add(new(), a, b)
end
function vec2_mt.__sub(a, b)
assert(vec2.isvec2(a), "__add: Wrong argument type for left hand operant. (<cpml.vec2> expected)")
assert(vec2.isvec2(b), "__add: Wrong argument type for right hand operant. (<cpml.vec2> expected)")
local temp = vec2.new()
vec2.sub(temp, a, b)
return temp
return vec2.sub(new(), a, b)
end
function vec2_mt.__mul(a, b)
@ -277,9 +281,7 @@ function vec2_mt.__mul(a, b)
assert(vec2.isvec2(a), "__mul: Wrong argument type for left hand operant. (<cpml.vec2> expected)")
assert(type(b) == "number", "__mul: Wrong argument type for right hand operant. (<number> expected)")
local temp = vec2.new()
vec2.mul(temp, a, b)
return temp
return vec2.mul(new(), a, b)
end
function vec2_mt.__div(a, b)
@ -289,13 +291,11 @@ function vec2_mt.__div(a, b)
assert(vec2.isvec2(a), "__div: Wrong argument type for left hand operant. (<cpml.vec2> expected)")
assert(type(b) == "number", "__div: Wrong argument type for right hand operant. (<number> expected)")
local temp = vec2.new()
vec2.div(temp, a, b)
return temp
return vec2.div(new(), a, b)
end
vec2.unit_x = vec2.new(1, 0)
vec2.unit_y = vec2.new(0, 1)
vec2.unit_x = new(1, 0)
vec2.unit_y = new(0, 1)
if status then
ffi.metatype(new, vec2_mt)

View File

@ -6,7 +6,7 @@ local vec3 = {}
-- Private constructor.
local function new(x, y, z)
local v = {}
local v = {}
v.x, v.y, v.z = x, y, z
return setmetatable(v, vec3_mt)
end
@ -256,6 +256,10 @@ function vec3_mt.__call(self, x, y, z)
return vec3.new(x, y, z)
end
function vec3_mt.__tostring(a)
return vec3.tostring(a)
end
function vec3_mt.__unm(a)
return vec3.new(-a.x, -a.y, -a.z)
end
@ -271,18 +275,14 @@ function vec3_mt.__add(a, b)
assert(vec3.isvec3(a), "__add: Wrong argument type for left hand operant. (<cpml.vec3> expected)")
assert(vec3.isvec3(b), "__add: Wrong argument type for right hand operant. (<cpml.vec3> expected)")
local temp = vec3.new()
vec3.add(temp, a, b)
return temp
return vec3.add(new(), a, b)
end
function vec3_mt.__sub(a, b)
assert(vec3.isvec3(a), "__sub: Wrong argument type for left hand operant. (<cpml.vec3> expected)")
assert(vec3.isvec3(b), "__sub: Wrong argument type for right hand operant. (<cpml.vec3> expected)")
local temp = vec3.new()
vec3.sub(temp, a, b)
return temp
return vec3.sub(new(), a, b)
end
function vec3_mt.__mul(a, b)
@ -292,9 +292,7 @@ function vec3_mt.__mul(a, b)
assert(vec3.isvec3(a), "__mul: Wrong argument type for left hand operant. (<cpml.vec3> expected)")
assert(type(b) == "number", "__mul: Wrong argument type for right hand operant. (<number> expected)")
local temp = vec3.new()
vec3.mul(temp, a, b)
return temp
return vec3.mul(new(), a, b)
end
function vec3_mt.__div(a, b)
@ -304,14 +302,12 @@ function vec3_mt.__div(a, b)
assert(vec3.isvec3(a), "__div: Wrong argument type for left hand operant. (<cpml.vec3> expected)")
assert(type(b) == "number", "__div: Wrong argument type for right hand operant. (<number> expected)")
local temp = vec3.new()
vec3.div(temp, a, b)
return temp
return vec3.div(new(), a, b)
end
vec3.unit_x = vec3.new(1, 0, 0)
vec3.unit_y = vec3.new(0, 1, 0)
vec3.unit_z = vec3.new(0, 0, 1)
vec3.unit_x = new(1, 0, 0)
vec3.unit_y = new(0, 1, 0)
vec3.unit_z = new(0, 0, 1)
if status then
ffi.metatype(new, vec3_mt)