buncha goodies

* Changed add/sub in vec2/vec3 to allow for integer math
* Fixed a string display error in quat
* Other stuff that @shakesoda probably did
This commit is contained in:
Landon Manning 2015-12-13 06:16:57 -04:00
parent 0481a97195
commit c72efbad3c
6 changed files with 117 additions and 59 deletions

View File

@ -32,29 +32,6 @@ local function matrix_mult_nxn(m1, m2)
return mtx
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 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
return view
end
function mat4:to_quat()
local m = self:transpose():to_vec4s()
local w = math.sqrt(1 + m[1][1] + m[2][2] + m[3][3]) / 2
@ -263,19 +240,15 @@ function mat4:scale(s)
return mat4(m) * mat4(self)
end
local function len(v)
return math.sqrt(v[1] * v[1] + v[2] * v[2] + v[3] * v[3])
end
function mat4:rotate(angle, axis)
if type(angle) == "table" then
angle, axis = angle:to_axis_angle()
end
local l = len(axis)
local l = axis:len()
if l == 0 then
return self
end
local x, y, z = axis[1] / l, axis[2] / l, axis[3] / l
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 = {
@ -539,4 +512,52 @@ function mat4:to_vec4s()
}
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 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
return view
end
function mat4.from_transform(t, rot, scale)
-- local m = {
-- scale.x, 0, 0, 0,
-- 0, scale.y, 0, 0,
-- 0, 0, scale.z, 0,
-- 0, 0, 0, 1
-- }
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 setmetatable(m, mat4)
end
return mat4

View File

@ -104,10 +104,11 @@ end
--- Cast a ray through the node and its children
-- @param ray Ray with a position and a direction
-- @param func Function to execute on any objects within child nodes
-- @param out Table to store results of func in
-- @return boolean True is is an intersect detected
function Octree:cast_ray(ray, func)
function Octree:cast_ray(ray, func, out)
assert(func)
return self.rootNode:cast_ray(ray, func)
return self.rootNode:cast_ray(ray, func, out)
end
--- Draws node boundaries visually for debugging.
@ -116,8 +117,8 @@ function Octree:draw_bounds(cube)
end
--- Draws the bounds of all objects in the tree visually for debugging.
function Octree:draw_objects(cube)
self.rootNode:draw_objects(cube)
function Octree:draw_objects(cube, filter)
self.rootNode:draw_objects(cube, filter)
end
--- Grow the octree to fit in all objects.
@ -352,13 +353,14 @@ end
--- Cast a ray through the node and its children
-- @param ray Ray with a position and a direction
-- @param func Function to execute on any objects within child nodes
-- @param out Table to store results of func in
-- @return boolean True if an intersect is detected
function OctreeNode:cast_ray(ray, func, level)
level = level or 1
function OctreeNode:cast_ray(ray, func, out, depth)
depth = depth or 1
if intersect.ray_aabb(ray, self.bounds.min, self.bounds.max) then
if #self.objects > 0 then
local hit = func(ray, self.objects)
local hit = func(ray, self.objects, out)
if hit then
return hit
@ -366,7 +368,7 @@ function OctreeNode:cast_ray(ray, func, level)
end
for _, child in ipairs(self.children) do
local hit = child:cast_ray(ray, func, level+1)
local hit = child:cast_ray(ray, func, out, depth + 1)
if hit then
return hit
@ -585,9 +587,8 @@ function OctreeNode:draw_bounds(cube, depth)
love.graphics.draw(cube)
love.graphics.setWireframe(false)
depth = depth + 1
for _, child in ipairs(self.children) do
child:draw_bounds(cube, depth)
child:draw_bounds(cube, depth + 1)
end
love.graphics.setColor(255, 255, 255)
@ -595,20 +596,22 @@ end
--- Draws the bounds of all objects in the tree visually for debugging.
-- @param cube Cube model to draw
function OctreeNode:draw_objects(cube)
function OctreeNode:draw_objects(cube, filter)
local tint = self.baseLength / 20
love.graphics.setColor(0, (1 - tint) * 255, tint * 255, 63)
for _, object in ipairs(self.objects) do
love.graphics.updateMatrix("transform", mat4()
:translate(object.bounds.center)
:scale(object.bounds.size)
)
love.graphics.draw(cube)
if filter and filter(object.data) or not filter then
love.graphics.updateMatrix("transform", mat4()
:translate(object.bounds.center)
:scale(object.bounds.size)
)
love.graphics.draw(cube)
end
end
for _, child in ipairs(self.children) do
child:draw_objects(cube)
child:draw_objects(cube, filter)
end
love.graphics.setColor(255, 255, 255)

View File

@ -119,7 +119,7 @@ function quaternion.__eq(a, b)
end
function quaternion:__tostring()
return string.format("(%0.3f,%0.3f,%0.3f,%0.3f)", self.x, self.y, self.z, self.x)
return string.format("(%0.3f,%0.3f,%0.3f,%0.3f)", self.x, self.y, self.z, self.w)
end
function quaternion:unpack()
@ -149,7 +149,7 @@ function quaternion:to_axis_angle()
z = self.z / s
end
return angle, { x, y, z }
return angle, vec3(x, y, z)
end
-- Test if we are zero
@ -279,6 +279,16 @@ local function rotate(angle, axis)
return new(axis.x * sin, axis.y * sin, axis.z * sin, cos)
end
--- Create a quaternion from a direction + up vector.
-- @param normal
-- @param up
-- @return quat
local function from_direction(normal, up)
local a = up:cross(normal)
local d = up:dot(normal)
return new(a.x, a.y, a.z, d + 1)
end
function quaternion:to_euler()
local sqx = self.x*self.x
local sqy = self.y*self.y
@ -345,5 +355,5 @@ end
-- return quaternion
-- the module
return setmetatable({ new = new, rotate = rotate },
return setmetatable({ new = new, rotate = rotate, from_direction = from_direction },
{ __call = function(_, ...) return new(...) end })

View File

@ -41,8 +41,8 @@ if not has_ffi then
end
-- Modules --
local bit = require("bit")
local math = require("math")
-- local bit = require("bit")
-- local math = require("math")
-- Imports --
local band = bit.band

View File

@ -65,13 +65,25 @@ function vector.__unm(a)
end
function vector.__add(a,b)
assert(isvector(a) and isvector(b), "Add: wrong argument types (<vector> expected)")
return new(a.x+b.x, a.y+b.y)
if type(a) == "number" then
return new(a+b.x, a+b.y)
elseif type(b) == "number" then
return new(b+a.x, b+a.y)
else
assert(isvector(a) and isvector(b), "Add: wrong argument types (<vector> expected)")
return new(a.x+b.x, a.y+b.y)
end
end
function vector.__sub(a,b)
assert(isvector(a) and isvector(b), "Sub: wrong argument types (<vector> expected)")
return new(a.x-b.x, a.y-b.y)
if type(a) == "number" then
return new(a-b.x, a-b.y)
elseif type(b) == "number" then
return new(b-a.x, b-a.y)
else
assert(isvector(a) and isvector(b), "Sub: wrong argument types (<vector> expected)")
return new(a.x-b.x, a.y-b.y)
end
end
function vector.__mul(a,b)

View File

@ -82,13 +82,25 @@ function vector.__unm(a)
end
function vector.__add(a,b)
assert(isvector(a) and isvector(b), "Add: wrong argument types (<vector> expected)")
return new(a.x+b.x, a.y+b.y, a.z+b.z)
if type(a) == "number" then
return new(a+b.x, a+b.y, a+b.z)
elseif type(b) == "number" then
return new(b+a.x, b+a.y, b+a.z)
else
assert(isvector(a) and isvector(b), "Add: wrong argument types (<vector> expected)")
return new(a.x+b.x, a.y+b.y, a.z+b.z)
end
end
function vector.__sub(a,b)
assert(isvector(a) and isvector(b), "Sub: wrong argument types (<vector> expected)")
return new(a.x-b.x, a.y-b.y, a.z-b.z)
if type(a) == "number" then
return new(a-b.x, a-b.y, a-b.z)
elseif type(b) == "number" then
return new(b-a.x, b-a.y, b-a.z)
else
assert(isvector(a) and isvector(b), "Sub: wrong argument types (<vector> expected)")
return new(a.x-b.x, a.y-b.y, a.z-b.z)
end
end
function vector.__mul(a,b)