Cleaned up internal code to be less verbose
This commit is contained in:
parent
d1a2c8c94b
commit
2aa0e7fcb6
@ -1,8 +1,8 @@
|
||||
# Licenses
|
||||
|
||||
CPML is Copyright (c) 2014 Colby Klein <shakesoda@gmail.com>.
|
||||
CPML is Copyright (c) 2016 Colby Klein <shakesoda@gmail.com>.
|
||||
|
||||
CPML is Copyright (c) 2014 Landon Manning <lmanning17@gmail.com>.
|
||||
CPML is Copyright (c) 2016 Landon Manning <lmanning17@gmail.com>.
|
||||
|
||||
Code in vec3.lua is derived from hump.vector. (c) 2010-2013 Matthias Richter. MIT.
|
||||
|
||||
|
8
init.lua
8
init.lua
@ -2,7 +2,7 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- @author Colby Klein
|
||||
-- @author Landon Manning
|
||||
-- @copyright 2015
|
||||
-- @copyright 2016
|
||||
-- @license MIT/X11
|
||||
-------------------------------------------------------------------------------
|
||||
.'@@@@@@@@@@@@@@#:
|
||||
@ -32,7 +32,7 @@
|
||||
:@@@@@@@++;;;+#@@@@@@+`
|
||||
.;'+++++;.
|
||||
--]]
|
||||
local current_folder = (...) and (...):gsub('%.init$', '') .. "." or ""
|
||||
local modules = (...) and (...):gsub('%.init$', '') .. ".modules." or ""
|
||||
|
||||
local cpml = {
|
||||
_LICENSE = "CPML is distributed under the terms of the MIT license. See LICENSE.md.",
|
||||
@ -56,8 +56,8 @@ local files = {
|
||||
"vec3",
|
||||
}
|
||||
|
||||
for _, v in ipairs(files) do
|
||||
cpml[v] = require(current_folder .. "modules." .. v)
|
||||
for _, file in ipairs(files) do
|
||||
cpml[file] = require(modules .. file)
|
||||
end
|
||||
|
||||
return cpml
|
||||
|
276
modules/mat4.lua
276
modules/mat4.lua
@ -24,6 +24,14 @@ local function new(m)
|
||||
return setmetatable(m, mat4_mt)
|
||||
end
|
||||
|
||||
local function identity(m)
|
||||
m[1], m[2], m[3], m[4] = 1, 0, 0, 0
|
||||
m[5], m[6], m[7], m[8] = 0, 1, 0, 0
|
||||
m[9], m[10], m[11], m[12] = 0, 0, 1, 0
|
||||
m[13], m[14], m[15], m[16] = 0, 0, 0, 1
|
||||
return m
|
||||
end
|
||||
|
||||
-- Do the check to see if JIT is enabled. If so use the optimized FFI structs.
|
||||
local status, ffi
|
||||
if type(jit) == "table" and jit.status() then
|
||||
@ -69,20 +77,15 @@ function mat4.new(a)
|
||||
end
|
||||
|
||||
function mat4.identity()
|
||||
return new {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1
|
||||
}
|
||||
return identity(new())
|
||||
end
|
||||
|
||||
function mat4.from_angle_axis(angle, axis)
|
||||
if type(angle) == "table" then
|
||||
angle, axis = vec3.to_angle_axis(angle)
|
||||
angle, axis = angle:to_angle_axis()
|
||||
end
|
||||
|
||||
local l = vec3.len(axis)
|
||||
local l = axis:len()
|
||||
if l == 0 then
|
||||
return new()
|
||||
end
|
||||
@ -100,9 +103,15 @@ function mat4.from_angle_axis(angle, axis)
|
||||
end
|
||||
|
||||
function mat4.from_direction(direction, up)
|
||||
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 forward = vec3():normalize(direction)
|
||||
|
||||
local side = vec3()
|
||||
:cross(forward, up)
|
||||
:normalize(side)
|
||||
|
||||
local new_up = vec3()
|
||||
:cross(side, forward)
|
||||
:normalize(new_up)
|
||||
|
||||
local out = new()
|
||||
out[1] = side.x
|
||||
@ -120,8 +129,8 @@ function mat4.from_direction(direction, up)
|
||||
end
|
||||
|
||||
function mat4.from_transform(trans, rot, scale)
|
||||
local angle, axis = vec3.to_angle_axis(rot)
|
||||
local l = vec3.len(axis)
|
||||
local angle, axis = rot:to_angle_axis()
|
||||
local l = axis:len()
|
||||
|
||||
if l == 0 then
|
||||
return new()
|
||||
@ -248,7 +257,7 @@ function mat4.from_hmd_perspective(tanHalfFov, zNear, zFar, flipZ, farAtInfinity
|
||||
projection[15] = handednessScale
|
||||
projection[16] = 0
|
||||
|
||||
return mat4.transpose(projection)
|
||||
return projection:transpose(projection)
|
||||
end
|
||||
|
||||
function mat4.clone(a)
|
||||
@ -286,85 +295,22 @@ function mat4.mul_mat4x1(out, a, b)
|
||||
end
|
||||
|
||||
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]
|
||||
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[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[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[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[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[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[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[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[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[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[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[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[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[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[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[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]
|
||||
|
||||
@ -380,22 +326,20 @@ function mat4.invert(out, a)
|
||||
end
|
||||
|
||||
function mat4.scale(out, a, s)
|
||||
local m = new {
|
||||
s.x, 0, 0, 0,
|
||||
0, s.y, 0, 0,
|
||||
0, 0, s.z, 0,
|
||||
0, 0, 0, 1
|
||||
}
|
||||
identity(tmp)
|
||||
tmp[1] = s.x
|
||||
tmp[6] = s.y
|
||||
tmp[11] = s.z
|
||||
|
||||
return mat4.mul(out, a, m)
|
||||
return out:mul(a, tmp)
|
||||
end
|
||||
|
||||
function mat4.rotate(out, a, angle, axis)
|
||||
if type(angle) == "table" then
|
||||
angle, axis = vec3.to_angle_axis(angle)
|
||||
angle, axis = angle:to_angle_axis()
|
||||
end
|
||||
|
||||
local l = vec3.len(axis)
|
||||
local l = axis:len()
|
||||
|
||||
if l == 0 then
|
||||
return a
|
||||
@ -404,64 +348,70 @@ function mat4.rotate(out, a, angle, axis)
|
||||
local x, y, z = axis.x / l, axis.y / l, axis.z / l
|
||||
local c = cos(angle)
|
||||
local s = sin(angle)
|
||||
local m = 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 mat4.mul(out, a, m)
|
||||
identity(tmp)
|
||||
tmp[1] = x * x * (1 - c) + c
|
||||
tmp[2] = y * x * (1 - c) + z * s
|
||||
tmp[3] = x * z * (1 - c) - y * s
|
||||
tmp[5] = x * y * (1 - c) - z * s
|
||||
tmp[6] = y * y * (1 - c) + c
|
||||
tmp[7] = y * z * (1 - c) + x * s
|
||||
tmp[9] = x * z * (1 - c) + y * s
|
||||
tmp[10] = y * z * (1 - c) - x * s
|
||||
tmp[11] = z * z * (1 - c) + c
|
||||
|
||||
return out:mul(a, tmp)
|
||||
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
|
||||
}
|
||||
identity(tmp)
|
||||
tmp[13] = t.x
|
||||
tmp[14] = t.y
|
||||
tmp[15] = t.z
|
||||
|
||||
return mat4.mul(out, a, m)
|
||||
return out:mul(a, tmp)
|
||||
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 = new {
|
||||
1, yx, zx, 0,
|
||||
xy, 1, zy, 0,
|
||||
xz, yz, 1, 0,
|
||||
0, 0, 0, 1
|
||||
}
|
||||
identity(tmp)
|
||||
tmp[2] = yx or 0
|
||||
tmp[3] = zx or 0
|
||||
tmp[5] = xy or 0
|
||||
tmp[7] = zy or 0
|
||||
tmp[9] = xz or 0
|
||||
tmp[10] = yz or 0
|
||||
|
||||
return mat4.mul(out, a, m)
|
||||
return out:mul(a, tmp)
|
||||
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))
|
||||
function mat4.look_at(out, a, eye, center, up)
|
||||
local forward = vec3():normalize(center - eye)
|
||||
|
||||
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 side = vec3()
|
||||
:cross(forward, up)
|
||||
:normalize(side)
|
||||
|
||||
local out = mat4.mul(new(), mat4.translate(new(), -eye - forward), view)
|
||||
local new_up = vec3()
|
||||
:cross(side, forward)
|
||||
:normalize(new_up)
|
||||
|
||||
return mat4.mul(out, out, a)
|
||||
identity(tmp)
|
||||
local view = tmp
|
||||
|
||||
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
|
||||
|
||||
return out
|
||||
:translate(-eye - forward)
|
||||
:mul(out, view)
|
||||
:mul(out, a)
|
||||
end
|
||||
|
||||
function mat4.transpose(out, a)
|
||||
@ -490,8 +440,9 @@ end
|
||||
function mat4.project(obj, view, projection, viewport)
|
||||
local position = { obj.x, obj.y, obj.z, 1 }
|
||||
|
||||
mat4.mul_mat4x1(position, mat4.transpose(mat4(), view), position)
|
||||
mat4.mul_mat4x1(position, mat4.transpose(mat4(), projection), position)
|
||||
identity(tmp)
|
||||
mat4.mul_mat4x1(position, tmp:transpose(view), position)
|
||||
mat4.mul_mat4x1(position, tmp:transpose(projection), position)
|
||||
|
||||
position[1] = position[1] / position[4] * 0.5 + 0.5
|
||||
position[2] = position[2] / position[4] * 0.5 + 0.5
|
||||
@ -507,10 +458,6 @@ end
|
||||
-- https://github.com/g-truc/glm/blob/master/glm/gtc/matrix_transform.inl#L338
|
||||
-- Note: GLM calls the view matrix "model"
|
||||
function mat4.unproject(win, view, projection, viewport)
|
||||
local inverse = mat4()
|
||||
mat4.mul(inverse, view, projection)
|
||||
mat4.invert(inverse, inverse)
|
||||
|
||||
local position = { win.x, win.y, win.z, 1 }
|
||||
|
||||
position[1] = (position[1] - viewport[1]) / viewport[3]
|
||||
@ -521,7 +468,9 @@ function mat4.unproject(win, view, projection, viewport)
|
||||
position[3] = position[3] * 2 - 1
|
||||
position[4] = position[4] * 2 - 1
|
||||
|
||||
mat4.mul_mat4x1(position, inverse, position)
|
||||
identity(tmp)
|
||||
tmp:mul(view, projection):invert(tmp)
|
||||
mat4.mul_mat4x1(position, tmp, position)
|
||||
|
||||
position[1] = position[1] / position[4]
|
||||
position[2] = position[2] / position[4]
|
||||
@ -566,17 +515,18 @@ function mat4.to_vec4s(a)
|
||||
end
|
||||
|
||||
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
|
||||
identity(tmp):transpose(a)
|
||||
|
||||
local q = quat.new(
|
||||
m[3][2] - m[2][3] / scale,
|
||||
m[1][3] - m[3][1] / scale,
|
||||
m[2][1] - m[1][2] / scale,
|
||||
local w = sqrt(1 + m[1] + m[6] + m[11]) / 2
|
||||
local scale = w * 4
|
||||
local q = quat.new(
|
||||
m[10] - m[7] / scale,
|
||||
m[3] - m[9] / scale,
|
||||
m[5] - m[2] / scale,
|
||||
w
|
||||
)
|
||||
return quat.normalize(q, q)
|
||||
|
||||
return q:normalize(q)
|
||||
end
|
||||
|
||||
local mat4_mt = {}
|
||||
@ -588,7 +538,7 @@ function mat4_mt.__call(self, a)
|
||||
end
|
||||
|
||||
function mat4_mt.__unm(a)
|
||||
return mat4.invert(new(), a)
|
||||
return new():invert(a)
|
||||
end
|
||||
|
||||
function mat4_mt.__eq(a, b)
|
||||
@ -609,7 +559,7 @@ function mat4_mt.__mul(a, b)
|
||||
assert(mat4.is_mat4(b) or #b == 4, "__mul: Wrong argument type for right hand operant. (<cpml.mat4> or table #4 expected)")
|
||||
|
||||
if mat4.is_mat4(b) then
|
||||
return mat4.mul(new(), a, b)
|
||||
return new():mul(a, b)
|
||||
end
|
||||
|
||||
return mat4.mul_mat4x1({}, a, b)
|
||||
|
100
modules/quat.lua
100
modules/quat.lua
@ -28,6 +28,9 @@ end
|
||||
quat.unit = new(0, 0, 0, 1)
|
||||
quat.zero = new(0, 0, 0, 0)
|
||||
|
||||
-- Statically allocate a temporary variable used in some of our functions.
|
||||
local tmp = new(0, 0, 0, 0)
|
||||
|
||||
-- Do the check to see if JIT is enabled. If so use the optimized FFI structs.
|
||||
local status, ffi
|
||||
if type(jit) == "table" and jit.status() then
|
||||
@ -75,7 +78,7 @@ end
|
||||
-- @tparam vec3 axis
|
||||
-- @treturn quat
|
||||
function quat.from_angle_axis(angle, axis)
|
||||
local len = vec3.len(axis)
|
||||
local len = axis:len()
|
||||
local s = sin(angle * 0.5)
|
||||
local c = cos(angle * 0.5)
|
||||
return new(axis.x * s, axis.y * s, axis.z * s, c)
|
||||
@ -86,8 +89,8 @@ end
|
||||
-- @tparam vec3 up
|
||||
-- @treturn quat
|
||||
function quat.from_direction(normal, up)
|
||||
local a = vec3.cross(vec3(), up, normal)
|
||||
local d = vec3.dot(up, normal)
|
||||
local a = vec3():cross(up, normal)
|
||||
local d = up:dot(normal)
|
||||
return new(a.x, a.y, a.z, d + 1)
|
||||
end
|
||||
|
||||
@ -144,13 +147,14 @@ end
|
||||
-- @treturn vec3 out
|
||||
local uv, uuv = vec3(), vec3()
|
||||
function quat.mul_vec3(out, a, b)
|
||||
vec3.cross(uv, a, b)
|
||||
vec3.cross(uuv, a, uv)
|
||||
vec3.mul(out, uv, a.w)
|
||||
vec3.add(out, out, uuv)
|
||||
vec3.mul(out, out, 2)
|
||||
vec3.add(out, b, out)
|
||||
uv:cross(a, b)
|
||||
uuv:cross(a, uv)
|
||||
|
||||
return out
|
||||
:mul(uv, a.w)
|
||||
:add(out, uuv)
|
||||
:mul(out, 2 )
|
||||
:add(b, out)
|
||||
end
|
||||
|
||||
--- Pow a quaternion by an exponent
|
||||
@ -169,9 +173,9 @@ function quat.pow(out, a, n)
|
||||
out.y = a.y^(n-1)
|
||||
out.z = a.z^(n-1)
|
||||
out.w = a.w^(n-1)
|
||||
quat.mul(out, a, out)
|
||||
out:mul(a, out)
|
||||
elseif n < 0 then
|
||||
quat.reciprocal(out, a)
|
||||
out:reciprocal(a)
|
||||
out.x = out.x^(-n)
|
||||
out.y = out.y^(-n)
|
||||
out.z = out.z^(-n)
|
||||
@ -186,9 +190,7 @@ end
|
||||
-- @tparam quat a
|
||||
-- @treturn quat out
|
||||
function quat.normalize(out, a)
|
||||
local l = 1 / quat.len(a)
|
||||
quat.scale(out, a, l)
|
||||
return out
|
||||
return out:scale(a, 1 / a:len())
|
||||
end
|
||||
|
||||
--- Return the inner angle between two quaternions.
|
||||
@ -243,9 +245,9 @@ end
|
||||
-- @tparam quat a
|
||||
-- @treturn quat out
|
||||
function quat.inverse(out, a)
|
||||
quat.conjugate(out, a)
|
||||
quat.normalize(out, out)
|
||||
return out
|
||||
:conjugate(a)
|
||||
:normalize(out)
|
||||
end
|
||||
|
||||
--- Return the reciprocal of a quaternion.
|
||||
@ -253,11 +255,10 @@ end
|
||||
-- @tparam quat a
|
||||
-- @treturn quat out
|
||||
function quat.reciprocal(out, a)
|
||||
assert(not quat.is_zer(a), "Cannot reciprocate a zero quaternion")
|
||||
local l = quat.len2(a)
|
||||
quat.conjugate(out, a)
|
||||
quat.scale(out, out, 1 / l)
|
||||
assert(not a:is_zero(), "Cannot reciprocate a zero quaternion")
|
||||
return out
|
||||
:conjugate(a)
|
||||
:scale(out, 1 / a:len2())
|
||||
end
|
||||
|
||||
--- Linearly interpolate from one quaternion to the next.
|
||||
@ -267,11 +268,11 @@ end
|
||||
-- @tparam number s 0-1 range number; 0 = a 1 = b
|
||||
-- @treturn quat out
|
||||
function quat.lerp(out, a, b, s)
|
||||
quat.sub(out, b, a)
|
||||
quat.mul(out, out, s)
|
||||
quat.add(out, a, out)
|
||||
quat.normalize(out, out)
|
||||
return out
|
||||
:sub(b, a)
|
||||
:mul(out, s)
|
||||
:add(a, out)
|
||||
:normalize(out)
|
||||
end
|
||||
|
||||
--- Slerp from one quaternion to the next.
|
||||
@ -281,29 +282,28 @@ end
|
||||
-- @tparam number s 0-1 range number; 0 = a 1 = b
|
||||
-- @treturn quat out
|
||||
function quat.slerp(out, a, b, s)
|
||||
local dot = quat.dot(a, b)
|
||||
local dot = a:dot(b)
|
||||
|
||||
if dot < 0 then
|
||||
quat.scale(a, a, -1)
|
||||
a:scale(a, -1)
|
||||
dot = -dot
|
||||
end
|
||||
|
||||
if dot > DOT_THRESHOLD then
|
||||
quat.lerp(out, a, b, s)
|
||||
return
|
||||
return out:lerp(a, b, s)
|
||||
end
|
||||
|
||||
dot = min(max(dot, -1), 1)
|
||||
local temp = quat.new()
|
||||
local theta = acos(dot) * s
|
||||
|
||||
quat.scale(out, a, dot)
|
||||
quat.sub(out, b, out)
|
||||
quat.normalize(out, out)
|
||||
quat.scale(out, out, sin(theta))
|
||||
quat.scale(temp, a, cos(theta))
|
||||
quat.add(out, temp, out)
|
||||
tmp:scale(a, cos(theta))
|
||||
|
||||
return out
|
||||
:scale(a, dot)
|
||||
:sub(b, out)
|
||||
:normalize(out)
|
||||
:scale(out, sin(theta))
|
||||
:add(tmp, out)
|
||||
end
|
||||
|
||||
--- Return the imaginary part of the quaternion as a vec3.
|
||||
@ -336,7 +336,7 @@ end
|
||||
|
||||
function quat.to_angle_axis(a)
|
||||
if a.w > 1 or a.w < -1 then
|
||||
a = quat.normalize(a, a)
|
||||
a:normalize(a)
|
||||
end
|
||||
|
||||
local angle = 2 * acos(a.w)
|
||||
@ -373,16 +373,16 @@ end
|
||||
--- Return a boolean showing if a table is or is not a quat
|
||||
-- @param q object to be tested
|
||||
-- @treturn boolean
|
||||
function quat.is_quat(q)
|
||||
function quat.is_quat(a)
|
||||
return
|
||||
(
|
||||
type(v) == "table" or
|
||||
type(v) == "cdata"
|
||||
type(a) == "table" or
|
||||
type(a) == "cdata"
|
||||
) and
|
||||
type(v.x) == "number" and
|
||||
type(v.y) == "number" and
|
||||
type(v.z) == "number" and
|
||||
type(v.w) == "number"
|
||||
type(a.x) == "number" and
|
||||
type(a.y) == "number" and
|
||||
type(a.z) == "number" and
|
||||
type(a.w) == "number"
|
||||
end
|
||||
|
||||
function quat.is_zero(a)
|
||||
@ -413,7 +413,7 @@ function quat_mt.__call(self, x, y, z, w)
|
||||
end
|
||||
|
||||
function quat_mt.__unm(a)
|
||||
return quat.scale(new(), a, -1)
|
||||
return new():scale(a, -1)
|
||||
end
|
||||
|
||||
function quat_mt.__eq(a,b)
|
||||
@ -425,25 +425,25 @@ end
|
||||
function quat_mt.__add(a, b)
|
||||
assert(quat.is_quat(a), "__add: Wrong argument type for left hand operant. (<cpml.quat> expected)")
|
||||
assert(quat.is_quat(b), "__add: Wrong argument type for right hand operant. (<cpml.quat> expected)")
|
||||
return quat.add(new(), a, b)
|
||||
return new():add(a, b)
|
||||
end
|
||||
|
||||
function quat_mt.__sub(a, b)
|
||||
assert(quat.is_quat(a), "__sub: Wrong argument type for left hand operant. (<cpml.quat> expected)")
|
||||
assert(quat.is_quat(b), "__sub: Wrong argument type for right hand operant. (<cpml.quat> expected)")
|
||||
return quat.sub(new(), a, b)
|
||||
return new():sub(a, b)
|
||||
end
|
||||
|
||||
function quat_mt.__mul(a, b)
|
||||
assert(quat.is_quat(a), "__mul: Wrong argument type for left hand operant. (<cpml.quat> expected)")
|
||||
assert(quat.is_quat(b) or vec3.is_vec3(b) or type(b) = "number", "__mul: Wrong argument type for right hand operant. (<cpml.quat> or <cpml.vec3> expected)")
|
||||
assert(quat.is_quat(b) or vec3.is_vec3(b) or type(b) == "number", "__mul: Wrong argument type for right hand operant. (<cpml.quat> or <cpml.vec3> expected)")
|
||||
|
||||
if quat.is_quat(b) then
|
||||
return quat.mul(new(), a, b)
|
||||
return new():mul(a, b)
|
||||
end
|
||||
|
||||
if type(b) == "number" then
|
||||
return quat.scale(new(), a, b)
|
||||
return new():scale(a, b)
|
||||
end
|
||||
|
||||
return quat.mul_vec3(vec3(), a, b)
|
||||
@ -452,7 +452,7 @@ end
|
||||
function quat_mt.__pow(a, n)
|
||||
assert(quat.is_quat(a), "__pow: Wrong argument type for left hand operant. (<cpml.quat> expected)")
|
||||
assert(type(b) == "number", "__pow: Wrong argument type for right hand operant. (<number> expected)")
|
||||
return quat.pow(new(), a, n)
|
||||
return new():pow(a, n)
|
||||
end
|
||||
|
||||
if status then
|
||||
|
@ -120,7 +120,7 @@ end
|
||||
-- @tparam vec2 out vector to store the result
|
||||
-- @tparam vec2 a vector to normalize
|
||||
function vec2.normalize(out, a)
|
||||
local l = vec2.len(a)
|
||||
local l = a:len()
|
||||
out.x = a.x / l
|
||||
out.y = a.y / l
|
||||
return out
|
||||
@ -131,10 +131,9 @@ end
|
||||
-- @tparam vec2 a vector to be trimmed
|
||||
-- @tparam number len the length to trim the vector to
|
||||
function vec2.trim(out, a, len)
|
||||
len = math.min(vec2.len(a), len)
|
||||
vec2.normalize(out, a)
|
||||
vec2.mul(out, out, len)
|
||||
return out
|
||||
:normalize(a)
|
||||
:mul(out, math.min(a:len(), len))
|
||||
end
|
||||
|
||||
--- Get the cross product of two vectors.
|
||||
@ -188,9 +187,10 @@ function vec2.dist2(a, b)
|
||||
end
|
||||
|
||||
function vec2.rotate(out, a, phi)
|
||||
local c, s = cos(phi), sin(phi)
|
||||
out.x = c * a.x - s * a.y
|
||||
out.y = s * a.x + c * a.y
|
||||
local c = cos(phi)
|
||||
local s = sin(phi)
|
||||
out.x = c * a.x - s * a.y
|
||||
out.y = s * a.x + c * a.y
|
||||
return out
|
||||
end
|
||||
|
||||
@ -207,10 +207,10 @@ end
|
||||
-- @tparam number s step value
|
||||
-- @treturn vec2
|
||||
function vec2.lerp(out, a, b, s)
|
||||
vec2.sub(out, b, a)
|
||||
vec2.mul(out, out, s)
|
||||
vec2.add(out, out, a)
|
||||
return out
|
||||
:sub(b, a)
|
||||
:mul(out, s)
|
||||
:add(out, a)
|
||||
end
|
||||
|
||||
--- Unpack a vector into form x,y
|
||||
@ -224,14 +224,18 @@ end
|
||||
--- Return a boolean showing if a table is or is not a vec2
|
||||
-- @param v the object to be tested
|
||||
-- @treturn boolean
|
||||
function vec2.is_vec2(v)
|
||||
function vec2.is_vec2(a)
|
||||
return
|
||||
(
|
||||
type(v) == "table" or
|
||||
type(v) == "cdata"
|
||||
type(a) == "table" or
|
||||
type(a) == "cdata"
|
||||
) and
|
||||
type(v.x) == "number" and
|
||||
type(v.y) == "number"
|
||||
type(a.x) == "number" and
|
||||
type(a.y) == "number"
|
||||
end
|
||||
|
||||
function vec2.is_zero(a)
|
||||
return a.x == 0 and a.y == 0
|
||||
end
|
||||
|
||||
--- Convert point from cartesian to polar.
|
||||
@ -261,7 +265,7 @@ function vec2_mt.__call(self, x, y)
|
||||
end
|
||||
|
||||
function vec2_mt.__unm(a)
|
||||
return vec2.new(-a.x, -a.y)
|
||||
return new(-a.x, -a.y)
|
||||
end
|
||||
|
||||
function vec2_mt.__eq(a,b)
|
||||
@ -273,25 +277,25 @@ end
|
||||
function vec2_mt.__add(a, b)
|
||||
assert(vec2.is_vec2(a), "__add: Wrong argument type for left hand operant. (<cpml.vec2> expected)")
|
||||
assert(vec2.is_vec2(b), "__add: Wrong argument type for right hand operant. (<cpml.vec2> expected)")
|
||||
return vec2.add(new(), a, b)
|
||||
return new():add(a, b)
|
||||
end
|
||||
|
||||
function vec2_mt.__sub(a, b)
|
||||
assert(vec2.is_vec2(a), "__add: Wrong argument type for left hand operant. (<cpml.vec2> expected)")
|
||||
assert(vec2.is_vec2(b), "__add: Wrong argument type for right hand operant. (<cpml.vec2> expected)")
|
||||
return vec2.sub(new(), a, b)
|
||||
return new():sub(a, b)
|
||||
end
|
||||
|
||||
function vec2_mt.__mul(a, b)
|
||||
assert(vec2.is_vec2(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)")
|
||||
return vec2.mul(new(), a, b)
|
||||
return new():mul(a, b)
|
||||
end
|
||||
|
||||
function vec2_mt.__div(a, b)
|
||||
assert(vec2.is_vec2(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)")
|
||||
return vec2.div(new(), a, b)
|
||||
return new():div(a, b)
|
||||
end
|
||||
|
||||
if status then
|
||||
|
@ -129,10 +129,9 @@ end
|
||||
-- @tparam vec3 a vector to be trimmed
|
||||
-- @tparam number len the length to trim the vector to
|
||||
function vec3.trim(out, a, len)
|
||||
len = math.min(vec3.len(a), len)
|
||||
vec3.normalize(out, a)
|
||||
vec3.mul(out, out, len)
|
||||
return out
|
||||
:normalize(a)
|
||||
:mul(out, math.min(vec3.len(a), len))
|
||||
end
|
||||
|
||||
--- Get the cross product of two vectors.
|
||||
@ -200,16 +199,17 @@ function vec3.rotate(out, a, phi, axis)
|
||||
end
|
||||
|
||||
local u = vec3.normalize(vec3(), axis)
|
||||
local c, s = cos(phi), sin(phi)
|
||||
local c = cos(phi)
|
||||
local s = sin(phi)
|
||||
|
||||
-- Calculate generalized rotation matrix
|
||||
local m1 = new((c + u.x * u.x * (1 - c)), (u.x * u.y * (1 - c) - u.z * s), (u.x * u.z * (1 - c) + u.y * s))
|
||||
local m2 = new((u.y * u.x * (1 - c) + u.z * s), (c + u.y * u.y * (1 - c)), (u.y * u.z * (1 - c) - u.x * s))
|
||||
local m3 = new((u.z * u.x * (1 - c) - u.y * s), (u.z * u.y * (1 - c) + u.x * s), (c + u.z * u.z * (1 - c)) )
|
||||
|
||||
out.x = vec3.dot(a, m1)
|
||||
out.y = vec3.dot(a, m2)
|
||||
out.z = vec3.dot(a, m3)
|
||||
out.x = a:dot(m1)
|
||||
out.y = a:dot(m2)
|
||||
out.z = a:dot(m3)
|
||||
return out
|
||||
end
|
||||
|
||||
@ -227,10 +227,10 @@ end
|
||||
-- @tparam number s step value
|
||||
-- @treturn vec3
|
||||
function vec3.lerp(out, a, b, s)
|
||||
vec3.sub(out, b, a)
|
||||
vec3.mul(out, out, s)
|
||||
vec3.add(out, out, a)
|
||||
return out
|
||||
:sub(b, a)
|
||||
:mul(out, s)
|
||||
:add(out, a)
|
||||
end
|
||||
|
||||
--- Unpack a vector into form x,y,z
|
||||
@ -256,6 +256,14 @@ function vec3.is_vec3(a)
|
||||
type(a.y) == "number" and
|
||||
type(a.z) == "number"
|
||||
end
|
||||
|
||||
function vec3.is_zero(a)
|
||||
return
|
||||
a.x == 0 and
|
||||
a.y == 0 and
|
||||
a.z == 0
|
||||
end
|
||||
|
||||
--- Return a string formatted "{x, y, z}"
|
||||
-- @tparam vec3 a the vector to be turned into a string
|
||||
-- @treturn string
|
||||
@ -272,7 +280,7 @@ function vec3_mt.__call(self, x, y, z)
|
||||
end
|
||||
|
||||
function vec3_mt.__unm(a)
|
||||
return vec3.new(-a.x, -a.y, -a.z)
|
||||
return new(-a.x, -a.y, -a.z)
|
||||
end
|
||||
|
||||
function vec3_mt.__eq(a,b)
|
||||
@ -284,25 +292,25 @@ end
|
||||
function vec3_mt.__add(a, b)
|
||||
assert(vec3.is_vec3(a), "__add: Wrong argument type for left hand operant. (<cpml.vec3> expected)")
|
||||
assert(vec3.is_vec3(b), "__add: Wrong argument type for right hand operant. (<cpml.vec3> expected)")
|
||||
return vec3.add(new(), a, b)
|
||||
return new():add(a, b)
|
||||
end
|
||||
|
||||
function vec3_mt.__sub(a, b)
|
||||
assert(vec3.is_vec3(a), "__sub: Wrong argument type for left hand operant. (<cpml.vec3> expected)")
|
||||
assert(vec3.is_vec3(b), "__sub: Wrong argument type for right hand operant. (<cpml.vec3> expected)")
|
||||
return vec3.sub(new(), a, b)
|
||||
return new():sub(a, b)
|
||||
end
|
||||
|
||||
function vec3_mt.__mul(a, b)
|
||||
assert(vec3.is_vec3(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)")
|
||||
return vec3.mul(new(), a, b)
|
||||
return new():mul(a, b)
|
||||
end
|
||||
|
||||
function vec3_mt.__div(a, b)
|
||||
assert(vec3.is_vec3(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)")
|
||||
return vec3.div(new(), a, b)
|
||||
return new():div(a, b)
|
||||
end
|
||||
|
||||
if status then
|
||||
|
Loading…
x
Reference in New Issue
Block a user