summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine-a <sanine.not@pm.me>2020-10-28 21:40:28 -0500
committersanine-a <sanine.not@pm.me>2020-10-28 21:40:28 -0500
commitc6790ae7b77e32af33ab290ff6b645536b69210e (patch)
tree3c37ed4fef87e20bd2e78f14921d79fb97cf2492
parent6199061d7367127aee3fb5e10990f751f5b97622 (diff)
refactor Matrix.lua
-rw-r--r--demo/FPSCamera.lua112
-rw-r--r--demo/Matrix.lua443
-rw-r--r--demo/main.lua15
3 files changed, 410 insertions, 160 deletions
diff --git a/demo/FPSCamera.lua b/demo/FPSCamera.lua
index 5e21117..1ec5097 100644
--- a/demo/FPSCamera.lua
+++ b/demo/FPSCamera.lua
@@ -1,29 +1,5 @@
local Vector = require('Vector')
-local Mat3, Mat4 = require('Matrix')()
-
-local Basis = function(M)
- local m = Mat3.new()
- honey.cglm.mat4.pick3(M, m)
-
- local x0 = honey.cglm.get_value(m, Mat3.index(1,1))
- local x1 = honey.cglm.get_value(m, Mat3.index(2,1))
- local x2 = honey.cglm.get_value(m, Mat3.index(3,1))
-
- local y0 = honey.cglm.get_value(m, Mat3.index(1,2))
- local y1 = honey.cglm.get_value(m, Mat3.index(2,2))
- local y2 = honey.cglm.get_value(m, Mat3.index(3,2))
-
- local z0 = honey.cglm.get_value(m, Mat3.index(1,3))
- local z1 = honey.cglm.get_value(m, Mat3.index(2,3))
- local z2 = honey.cglm.get_value(m, Mat3.index(3,3))
-
- local b = {}
- b.x = Vector.Vec3.new{x0, x1, x2}
- b.y = Vector.Vec3.new{y0, y1, y2}
- b.z = Vector.Vec3.new{z0, z1, z2}
-
- return b
-end
+local Matrix = require('Matrix')
local camera = {}
@@ -36,46 +12,40 @@ camera.movement_speed = 1
camera.position = Vector.Vec3.new{0,0,-1}
-camera.view = Mat4.new()
-honey.cglm.mat4.identity(camera.view)
-
-camera.basis = Basis(camera.view)
+camera.view = Matrix.Mat4.eye()
+camera.basis = camera.view:basis()
-camera.projection = Mat4.new()
-honey.cglm.camera.perspective(
- camera.projection,
- math.rad(90),
- 640/480,
- 0.1,
- 8192)
+camera.projection = Matrix.Mat4.perspective(math.rad(90),
+ 640/480,
+ 0.1,
+ 8192)
function camera:update()
- local M = Mat4.new()
- honey.cglm.mat4.identity(M)
- honey.cglm.affine.rotate(M, Vector.Vec3.ZERO.array, self.basis.x.array, math.rad(self.pitch))
- honey.cglm.affine.rotate(M, Vector.Vec3.ZERO.array, Vector.Vec3.Y_UNIT.array, math.rad(self.yaw))
- self.basis = Basis(M)
-
- movement = Vector.Vec3.new()
- if honey.input.key.is_down(honey.input.key.w) then
- movement:add(self.basis.z, movement)
- end
- if honey.input.key.is_down(honey.input.key.a) then
- movement:add(self.basis.x, movement)
- end
- if honey.input.key.is_down(honey.input.key.s) then
- movement:sub(self.basis.z, movement)
- end
- if honey.input.key.is_down(honey.input.key.d) then
- movement:sub(self.basis.x, movement)
- end
-
- movement:setAt(1, 0)
- movement:normalize()
- movement:muls(self.movement_speed, movement)
- self.position:add(movement, self.position)
-
- honey.cglm.camera.look(self.position.array, self.basis.z.array, Vector.Vec3.Y_UNIT.array, self.view)
+ local M = Matrix.Mat4.eye()
+ M:rotate(Vector.Vec3.ZERO, self.basis.x, math.rad(self.pitch))
+ M:rotate(Vector.Vec3.ZERO, Vector.Vec3.Y_UNIT, math.rad(self.yaw))
+ self.basis = M:basis()
+
+ movement = Vector.Vec3.new()
+ if honey.input.key.is_down(honey.input.key.w) then
+ movement:add(self.basis.z, movement)
+ end
+ if honey.input.key.is_down(honey.input.key.a) then
+ movement:add(self.basis.x, movement)
+ end
+ if honey.input.key.is_down(honey.input.key.s) then
+ movement:sub(self.basis.z, movement)
+ end
+ if honey.input.key.is_down(honey.input.key.d) then
+ movement:sub(self.basis.x, movement)
+ end
+
+ movement:setAt(1, 0)
+ movement:normalize()
+ movement:muls(self.movement_speed, movement)
+ self.position:add(movement, self.position)
+
+ Matrix.Mat4.look(self.position, self.basis.z, Vector.Vec3.Y_UNIT, self.view)
end
camera.mouse_pos = {}
@@ -83,18 +53,18 @@ camera.mouse_pos.x = 0
camera.mouse_pos.y = 0
honey.input.mouse.bind_movement(
- function(xpos, ypos)
- local dx = xpos - camera.mouse_pos.x
- local dy = ypos - camera.mouse_pos.y
+ function(xpos, ypos)
+ local dx = xpos - camera.mouse_pos.x
+ local dy = ypos - camera.mouse_pos.y
- camera.mouse_pos = { x=xpos, y=ypos }
+ camera.mouse_pos = { x=xpos, y=ypos }
- camera.pitch = camera.pitch + camera.sensitivity * dy
- camera.yaw = camera.yaw - camera.sensitivity * dx
+ camera.pitch = camera.pitch + camera.sensitivity * dy
+ camera.yaw = camera.yaw - camera.sensitivity * dx
- if camera.pitch > 89 then camera.pitch = 89 end
- if camera.pitch < -89 then camera.pitch = -89 end
- end
+ if camera.pitch > 89 then camera.pitch = 89 end
+ if camera.pitch < -89 then camera.pitch = -89 end
+ end
)
honey.input.mouse.set_mode(honey.input.mouse.mode.disabled)
diff --git a/demo/Matrix.lua b/demo/Matrix.lua
index 11b704c..eae210f 100644
--- a/demo/Matrix.lua
+++ b/demo/Matrix.lua
@@ -1,90 +1,375 @@
-local Mat3 = {}
-
-Mat3.index = function(i, j)
- return (i-1) + 3*(j-1)
-end
-
-Mat3.tostring = function(mat)
- local str = '[ ['..
- tostring(honey.cglm.get_value(mat, 0))..', '..
- tostring(honey.cglm.get_value(mat, 3))..', '..
- tostring(honey.cglm.get_value(mat, 6))..']\n ['..
- tostring(honey.cglm.get_value(mat, 1))..', '..
- tostring(honey.cglm.get_value(mat, 4))..', '..
- tostring(honey.cglm.get_value(mat, 7))..']\n ['..
- tostring(honey.cglm.get_value(mat, 2))..', '..
- tostring(honey.cglm.get_value(mat, 5))..', '..
- tostring(honey.cglm.get_value(mat, 8))..'] ]'
- return str
-end
-
-Mat3.new = function(tbl)
- if tbl == nil then
- return honey.cglm.new_array_zero(9)
- end
-
- if #tbl ~= 9 then
- error('3x3 matrices require exactly nine elements!')
- end
-
- local mat3 = honey.cglm.new_array_zero(9)
- for i = 0,8 do
- honey.cglm.set_value(mat3, i, tbl[i+1])
- end
+local Vector = require('Vector')
+
+local Matrix = {}
+
+Matrix.Mat3 = {}
+
+Matrix.Mat3.prototype = {}
+
+Matrix.Mat3.prototype.at = function(self, i, j)
+ return honey.cglm.get_value(self.array, (i-1) + 3*(j-1))
+end
+
+Matrix.Mat3.prototype.setAt = function(self, i, j, value)
+ honey.cglm.set_value(self.array, (i-1) + 3*(j-1), value)
+end
+
+Matrix.Mat3.prototype.clone = function(self)
+ local clone = honey.cglm.new_array_zero(9)
+ clone.array = honey.cglm.copy_array(self.array, 9)
+ return clone
+end
+
+Matrix.Mat3.prototype.mul = function(self, M, dest)
+ local result
+ if dest == nil then
+ result = Matrix.Mat3.new()
+ else
+ result = dest
+ end
+
+ honey.cglm.mat3.mul(self.array, M.array, result)
+ return result
+end
+
+Matrix.Mat3.prototype.muls = function(self, s, dest)
+ local result
+ if dest == nil then
+ result = Matrix.Mat3.new()
+ else
+ result = dest
+ end
+
+ honey.cglm.mat3.muls(s, self.array, result)
+ return result
+end
+
+Matrix.Mat3.prototype.mulv = function(self, v, dest)
+ local result
+ if dest == nil then
+ result = Matrix.Mat3.new()
+ else
+ result = dest
+ end
+
+ honey.cglm.mat3.mulv(self.array, v.array, result)
+ return result
+end
+
+Matrix.Mat3.prototype.T = function(self, auto)
+ auto = auto or false
+ if auto then
+ honey.cglm.mat3.trans(self.array)
+ return
+ end
+
+ local M = self.clone()
+
+ honey.cglm.mat3.trans(M.array)
+ return M
+end
+
+Matrix.Mat3.prototype.det = function(self)
+ return honey.cglm.mat3.det(self.array)
+end
+
+Matrix.Mat3.prototype.trace = function(self)
+ return honey.cglm.mat3.trace(self.array)
+end
+
+Matrix.Mat3.prototype.inv = function(self, dest)
+ local result
+ if dest == nil then
+ result = Matrix.Mat3.new()
+ else
+ result = dest
+ end
+
+ honey.cglm.mat3.inv(self.array, result.array)
+ return result
+end
+
+Matrix.Mat3.prototype.basis = function(self)
+ local x0 = self:at(1,1)
+ local x1 = self:at(2,1)
+ local x2 = self:at(3,1)
+
+ local y0 = self:at(1,2)
+ local y1 = self:at(2,2)
+ local y2 = self:at(3,2)
+
+ local z0 = self:at(1,3)
+ local z1 = self:at(2,3)
+ local z2 = self:at(3,3)
+
+ local b = {}
+ b.x = Vector.Vec3.new{x0, x1, x2}
+ b.y = Vector.Vec3.new{y0, y1, y2}
+ b.z = Vector.Vec3.new{z0, z1, z2}
+
+ return b
+end
+
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Matrix.Mat3.mt = {}
+
+Matrix.Mat3.mt.__index = Matrix.Mat3.prototype
+Matrix.Mat3.mt.__tostring = function(mat3)
+ local line1 = 'mat3('..
+ tostring(mat3:at(1,1))..', '..
+ tostring(mat3:at(1,2))..', '..
+ tostring(mat3:at(1,3))..', \n'
+ local line2 = ' '..
+ tostring(mat3:at(2,1))..', '..
+ tostring(mat3:at(2,2))..', '..
+ tostring(mat3:at(2,3))..', \n'
+ local line3 = ' '..
+ tostring(mat3:at(3,1))..', '..
+ tostring(mat3:at(3,2))..', '..
+ tostring(mat3:at(3,3))..')'
+ return line1..line2..line3
+end
+
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Matrix.Mat3.new = function(tbl)
+ local mat3 = {}
+ mat3.array = honey.cglm.new_array_zero(9)
+ setmetatable(mat3, Matrix.Mat3.mt)
+
+ if tbl == nil then return mat3 end
+
+ for i = 1,3 do
+ for j = 1,3 do
+ mat3:setAt(i,j, tbl[3*(i-1) + j])
+ end
+ end
return mat3
end
+Matrix.Mat3.eye = function()
+ local eye3 = Matrix.Mat3.new()
+ honey.cglm.mat3.identity(eye3.array)
+ return eye3
+end
+
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+--
+-- Mat4
+--
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Matrix.Mat4 = {}
+
+Matrix.Mat4.prototype = {}
+
+Matrix.Mat4.prototype.at = function(self, i, j)
+ return honey.cglm.get_value(self.array, (i-1) + 4*(j-1))
+end
+
+Matrix.Mat4.prototype.setAt = function(self, i, j, value)
+ honey.cglm.set_value(self.array, (i-1) + 4*(j-1), value)
+end
+
+Matrix.Mat4.prototype.clone = function(self)
+ local clone = honey.cglm.new_array_zero(16)
+ clone.array = honey.cglm.copy_array(self.array, 16)
+ return clone
+end
+
+Matrix.Mat4.prototype.pick3 = function(self, dest)
+ local result
+ if dest == nil then
+ result = Matrix.Mat3.new()
+ else
+ result = dest
+ end
+
+ honey.cglm.mat4.pick3(self.array, result.array)
+ return result
+end
+
+Matrix.Mat4.prototype.mul = function(self, M, dest)
+ local result
+ if dest == nil then
+ result = Matrix.Mat4.new()
+ else
+ result = dest
+ end
+
+ honey.cglm.mat4.mul(self.array, M.array, result)
+ return result
+end
+
+Matrix.Mat4.prototype.muls = function(self, s, dest)
+ local result
+ if dest == nil then
+ result = Matrix.Mat4.new()
+ else
+ result = dest
+ end
+
+ honey.cglm.mat4.muls(s, self.array, result)
+ return result
+end
+
+Matrix.Mat4.prototype.mulv = function(self, v, dest)
+ local result
+ if dest == nil then
+ result = Matrix.Mat4.new()
+ else
+ result = dest
+ end
+
+ honey.cglm.mat4.mulv(self.array, v.array, result)
+ return result
+end
+
+Matrix.Mat4.prototype.T = function(self, auto)
+ auto = auto or false
+ if auto then
+ honey.cglm.mat4.trans(self.array)
+ return
+ end
+
+ local M = self.clone()
+
+ honey.cglm.mat4.trans(M.array)
+ return M
+end
+
+Matrix.Mat4.prototype.det = function(self)
+ return honey.cglm.mat4.det(self.array)
+end
+
+Matrix.Mat4.prototype.trace = function(self)
+ return honey.cglm.mat4.trace(self.array)
+end
+
+Matrix.Mat4.prototype.inv = function(self, dest)
+ local result
+ if dest == nil then
+ result = Matrix.Mat4.new()
+ else
+ result = dest
+ end
+
+ honey.cglm.mat4.inv(self.array, result.array)
+ return result
+end
+
+Matrix.Mat4.prototype.fastInv = function(self, dest)
+ local result
+ if dest == nil then
+ result = Matrix.Mat4.new()
+ else
+ result = dest
+ end
+
+ honey.cglm.mat4.inv_fast(self.array, result.array)
+ return result
+end
+
+Matrix.Mat4.prototype.basis = function(self)
+ local M = self:pick3()
+
+ return M:basis()
+end
+
+Matrix.Mat4.prototype.rotate = function(self, center, axis, angle)
+ honey.cglm.affine.rotate(self.array, center.array, axis.array, angle)
+end
+
+Matrix.Mat4.prototype.translate = function(self, v)
+ honey.cglm.affine.translate(self.array, v.array)
+end
+
+Matrix.Mat4.prototype.scale = function(self, v)
+ honey.cglm.affine.scale(self.array, v.array)
+end
+
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-local Mat4 = {}
-
-Mat4.index = function(i, j)
- return (i-1) + 4*(j-1)
-end
-
-Mat4.tostring = function(matrix)
- str = ''
- for i = 1,4 do
- for j = 1,4 do
- str = str..tostring(honey.cglm.get_value(matrix, Mat4.index(i,j)))..', '
- end
- str = str..'\n'
- end
- return str
-end
-
-Mat4.new = function(tbl)
- if tbl == nil then
- return honey.cglm.new_array_zero(16)
- end
-
- if #tbl ~= 16 then
- error('4x4 matrices require exactly 16 elements!')
- end
-
- local mat4 = honey.cglm.new_array_zero(16)
- honey.cglm.set_value(mat4, 0, tbl[1])
- honey.cglm.set_value(mat4, 1, tbl[5])
- honey.cglm.set_value(mat4, 2, tbl[9])
- honey.cglm.set_value(mat4, 3, tbl[13])
- honey.cglm.set_value(mat4, 4, tbl[2])
- honey.cglm.set_value(mat4, 5, tbl[6])
- honey.cglm.set_value(mat4, 6, tbl[10])
- honey.cglm.set_value(mat4, 7, tbl[14])
- honey.cglm.set_value(mat4, 8, tbl[3])
- honey.cglm.set_value(mat4, 9, tbl[7])
- honey.cglm.set_value(mat4, 10, tbl[11])
- honey.cglm.set_value(mat4, 11, tbl[15])
- honey.cglm.set_value(mat4, 12, tbl[4])
- honey.cglm.set_value(mat4, 13, tbl[8])
- honey.cglm.set_value(mat4, 14, tbl[12])
- honey.cglm.set_value(mat4, 15, tbl[16])
-
- setmetatable(mat4, Mat4.mt)
+Matrix.Mat4.mt = {}
+
+Matrix.Mat4.mt.__index = Matrix.Mat4.prototype
+Matrix.Mat4.mt.__tostring = function(mat4)
+ local line1 = 'mat4('..
+ tostring(mat4:at(1,1))..', '..
+ tostring(mat4:at(1,2))..', '..
+ tostring(mat4:at(1,3))..', '..
+ tostring(mat4:at(1,4))..', \n'
+ local line2 = ' '..
+ tostring(mat4:at(2,1))..', '..
+ tostring(mat4:at(2,2))..', '..
+ tostring(mat4:at(2,3))..', '..
+ tostring(mat4:at(2,4))..', \n'
+ local line3 = ' '..
+ tostring(mat4:at(3,1))..', '..
+ tostring(mat4:at(3,2))..', '..
+ tostring(mat4:at(3,3))..', '..
+ tostring(mat4:at(3,4))..')'
+ local line4 = ' '..
+ tostring(mat4:at(4,1))..', '..
+ tostring(mat4:at(4,2))..', '..
+ tostring(mat4:at(4,3))..', '..
+ tostring(mat4:at(4,4))..')'
+ return line1..line2..line4
+end
+
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Matrix.Mat4.new = function(tbl)
+ local mat4 = {}
+ mat4.array = honey.cglm.new_array_zero(16)
+ setmetatable(mat4, Matrix.Mat4.mt)
+
+ if tbl == nil then return mat4 end
+
+ for i = 1,4 do
+ for j = 1,4 do
+ mat4:setAt(i,j, tbl[4*(i-1) + j])
+ end
+ end
return mat4
end
+Matrix.Mat4.eye = function()
+ local eye4 = Matrix.Mat4.new()
+ honey.cglm.mat4.identity(eye4.array)
+ return eye4
+end
+
+Matrix.Mat4.perspective = function(fov, aspectRatio, near, far)
+ local M = Matrix.Mat4.new()
+ honey.cglm.camera.perspective(M.array, fov, aspectRatio, near, far)
+ return M
+end
+
+Matrix.Mat4.orthographic = function(a, b)
+ local M = Matrix.Mat4.new()
+ honey.cglm.camera.orthographic(M.array, a.array, b.array)
+ return M
+end
+
+Matrix.Mat4.look = function(position, direction, up, dest)
+ local result
+ if dest == nil then
+ result = Matrix.Mat4.new()
+ else
+ result = dest
+ end
+
+ honey.cglm.camera.look(position.array,
+ direction.array,
+ up.array,
+ dest.array)
+ return dest
+end
+
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-return function() return Mat3, Mat4 end
+return Matrix
diff --git a/demo/main.lua b/demo/main.lua
index 62ffcd2..f534952 100644
--- a/demo/main.lua
+++ b/demo/main.lua
@@ -1,13 +1,8 @@
local Vector = require('Vector')
-local Mat3, Mat4 = require('Matrix')()
+local Matrix = require('Matrix')
local FPSCamera = require('FPSCamera')
-local model = Mat4.new()
-honey.cglm.mat4.identity(model)
-honey.cglm.affine.rotate(model,
- Vector.Vec3.ZERO.array,
- Vector.Vec3.X_UNIT.array,
- math.pi/4)
+local model = Matrix.Mat4.eye()
honey.input.key.bind(honey.input.key.escape, honey.exit)
@@ -47,9 +42,9 @@ end
function honey.draw()
FPSCamera:update()
- honey.shader.set_mat4(shader, 'model', model)
- honey.shader.set_mat4(shader, 'view', FPSCamera.view)
- honey.shader.set_mat4(shader, 'projection', FPSCamera.projection)
+ honey.shader.set_mat4(shader, 'model', model.array)
+ honey.shader.set_mat4(shader, 'view', FPSCamera.view.array)
+ honey.shader.set_mat4(shader, 'projection', FPSCamera.projection.array)
honey.shader.set_vec4(shader, "base_color", color.array)
honey.mesh.draw(plane, shader)
end