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:
parent
0481a97195
commit
c72efbad3c
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 })
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user