diff --git a/LICENSE.md b/LICENSE.md index 68be0b3..a6696a1 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,8 +1,8 @@ # Licenses -CPML is Copyright (c) 2014 Colby Klein . +CPML is Copyright (c) 2016 Colby Klein . -CPML is Copyright (c) 2014 Landon Manning . +CPML is Copyright (c) 2016 Landon Manning . Code in vec3.lua is derived from hump.vector. (c) 2010-2013 Matthias Richter. MIT. diff --git a/init.lua b/init.lua index 904d702..97037c6 100644 --- a/init.lua +++ b/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 diff --git a/modules/mat4.lua b/modules/mat4.lua index 199988a..9a4c6fb 100644 --- a/modules/mat4.lua +++ b/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. ( 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) diff --git a/modules/quat.lua b/modules/quat.lua index 7748760..e8dd6cb 100644 --- a/modules/quat.lua +++ b/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. ( expected)") assert(quat.is_quat(b), "__add: Wrong argument type for right hand operant. ( 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. ( expected)") assert(quat.is_quat(b), "__sub: Wrong argument type for right hand operant. ( 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. ( expected)") - assert(quat.is_quat(b) or vec3.is_vec3(b) or type(b) = "number", "__mul: Wrong argument type for right hand operant. ( or expected)") + assert(quat.is_quat(b) or vec3.is_vec3(b) or type(b) == "number", "__mul: Wrong argument type for right hand operant. ( or 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. ( expected)") assert(type(b) == "number", "__pow: Wrong argument type for right hand operant. ( expected)") - return quat.pow(new(), a, n) + return new():pow(a, n) end if status then diff --git a/modules/vec2.lua b/modules/vec2.lua index 7134df0..4f68f36 100644 --- a/modules/vec2.lua +++ b/modules/vec2.lua @@ -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. ( expected)") assert(vec2.is_vec2(b), "__add: Wrong argument type for right hand operant. ( 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. ( expected)") assert(vec2.is_vec2(b), "__add: Wrong argument type for right hand operant. ( 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. ( expected)") assert(type(b) == "number", "__mul: Wrong argument type for right hand operant. ( 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. ( expected)") assert(type(b) == "number", "__div: Wrong argument type for right hand operant. ( expected)") - return vec2.div(new(), a, b) + return new():div(a, b) end if status then diff --git a/modules/vec3.lua b/modules/vec3.lua index 62d0e6a..f9181b7 100644 --- a/modules/vec3.lua +++ b/modules/vec3.lua @@ -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. ( expected)") assert(vec3.is_vec3(b), "__add: Wrong argument type for right hand operant. ( 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. ( expected)") assert(vec3.is_vec3(b), "__sub: Wrong argument type for right hand operant. ( 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. ( expected)") assert(type(b) == "number", "__mul: Wrong argument type for right hand operant. ( 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. ( expected)") assert(type(b) == "number", "__div: Wrong argument type for right hand operant. ( expected)") - return vec3.div(new(), a, b) + return new():div(a, b) end if status then