From 2b41e8debb83d9ca3119d2c4fab74b1cf61881e5 Mon Sep 17 00:00:00 2001 From: Colby Klein Date: Tue, 11 Nov 2014 03:46:25 -0800 Subject: [PATCH] Fix quaternion (THIS IS WHY WE NEED TESTS). Also gave vec3 a table constructor. --- modules/quat.lua | 28 +++++++++++++++------------- modules/vec3.lua | 9 +++++++-- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/modules/quat.lua b/modules/quat.lua index 015dcda..3ece1bb 100644 --- a/modules/quat.lua +++ b/modules/quat.lua @@ -8,9 +8,11 @@ This is a class for handling quaternion numbers. It was originally designed as a way of encoding rotations of 3 dimensional space. --]] +local current_folder = (...):gsub('%.[^%.]+$', '') .. "." +local constants = require(current_folder .. "constants") + local quaternion = {} quaternion.__index = quaternion -local FLT_EPSILON = 1.19209290e-07 --[[ A quaternion can either be specified by giving the four coordinates as @@ -53,7 +55,7 @@ function quaternion:to_axis_angle() local angle = 2 * math.acos(tmp.a) local s = math.sqrt(1-tmp.a*tmp.a) local x, y, z - if s < FLT_EPSILON then + if s < constants.FLT_EPSILON then x = tmp.b y = tmp.c z = tmp.d @@ -172,7 +174,7 @@ Scale the quaternion. --]] function quaternion:scale(l) - return quaternion(self.a * l,self.b * l,self.c * l, self.d * l) + return new(self.a * l,self.b * l,self.c * l, self.d * l) end --[[ @@ -181,9 +183,9 @@ Add two quaternions. Or add a real number to a quaternion. function quaternion:add(q) if type(q) == "number" then - return quaternion(self.a + q, self.b, self.c, self.d) + return new(self.a + q, self.b, self.c, self.d) else - return quaternion(self.a + q.a, self.b + q.b, self.c + q.c, self.d + q.d) + return new(self.a + q.a, self.b + q.b, self.c + q.c, self.d + q.d) end end @@ -200,7 +202,7 @@ Subtraction --]] function quaternion:subtract(q) - return quaternion(self.a - q.a, self.b - q.b, self.c - q.c, self.d - q.d) + return new(self.a - q.a, self.b - q.b, self.c - q.c, self.d - q.d) end --[[ @@ -239,7 +241,7 @@ function quaternion:multiplyRight(q) b = self.a * q.b + self.b * q.a + self.c * q.d - self.d * q.c c = self.a * q.c - self.b * q.d + self.c * q.a + self.d * q.b d = self.a * q.d + self.b * q.c - self.c * q.b + self.d * q.a - return quaternion(a,b,c,d) + return new(a,b,c,d) end --[[ @@ -269,7 +271,7 @@ Conjugation (corresponds to inverting a rotation). --]] function quaternion:conjugate() - return quaternion(self.a, - self.b, - self.c, - self.d) + return new(self.a, - self.b, - self.c, - self.d) end function quaternion:co() @@ -301,7 +303,7 @@ function quaternion:power(n) return false end if n == 0 then - return quaternion(1,0,0,0) + return new(1,0,0,0) elseif n > 0 then return self:multiplyRight(self:power(n-1)) elseif n < 0 then @@ -412,7 +414,7 @@ When we have access to the compass, the x-axis behaviour might change. function quaternion.gravity() local gxy, gy, gygxy, a, b, c, d if Gravity.x == 0 and Gravity.y == 0 then - return quaternion(1,0,0,0) + return new(1,0,0,0) else gy = - Gravity.y gxy = math.sqrt(math.pow(Gravity.x,2) + math.pow(Gravity.y,2)) @@ -433,7 +435,7 @@ function quaternion.gravity() c = - c d = - d end - return quaternion(a,b,c,d) + return new(a,b,c,d) end end --]] @@ -446,7 +448,7 @@ as three numbers. function quaternion.rotation(a,...) local q,c,s - q = quaternion(0,...) + q = new(0,...) q = q:normalize() c = math.cos(a/2) s = math.sin(a/2) @@ -494,7 +496,7 @@ The unit quaternion. --]] function quaternion.unit() - return quaternion(1,0,0,0) + return new(1,0,0,0) end --return quaternion diff --git a/modules/vec3.lua b/modules/vec3.lua index be9c28d..57a2cd5 100644 --- a/modules/vec3.lua +++ b/modules/vec3.lua @@ -34,6 +34,10 @@ local vector = {} vector.__index = vector local function new(x,y,z) + if type(x) == "table" then + return setmetatable({x = x.x or x[1] or 0, y = x.y or x[2] or 0, z = x.z or x[3] or 0}, vector) + end + return setmetatable({x = x or 0, y = y or 0, z = z or 0}, vector) end local zero = new(0,0,0) @@ -221,8 +225,9 @@ function vector:trimmed(maxLen) return self:clone():trim_inplace(maxLen) end -function vector:orientation_to_direction() - return new(0, 1, 0) +function vector:orientation_to_direction(orientation) + orientation = orientation or new(0, 1, 0) + return orientation :rotated(self.z, new(0, 0, 1)) :rotated(self.y, new(0, 1, 0)) :rotated(self.x, new(1, 0, 0))