_math: initial matrix/vector math library

This commit is contained in:
Zack Buhman 2026-02-22 21:28:08 +00:00
parent 955a3e09aa
commit 44a3c5b76e
4 changed files with 202 additions and 10 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.~*
.\#*
\#*
*~

161
_math.lua Normal file
View File

@ -0,0 +1,161 @@
local ffi = require 'ffi'
local sin = math.sin
local cos = math.cos
local mat4
local newmat4 = function(_t)
-- newByteData is zero-initialized
local data = love.data.newByteData(16 * 4)
local m = ffi.cast('float*', data:getFFIPointer())
value = {
data = data,
m = m,
}
setmetatable(value, mat4)
return value
end
mat4 = {
__call = newmat4,
identity = function()
local M = newmat4()
M.m[0 * 4 + 0] = 1.0
--M.m[0 * 4 + 1] = 0.0
--M.m[0 * 4 + 2] = 0.0
--M.m[0 * 4 + 3] = 0.0
--M.m[1 * 4 + 0] = 0.0
M.m[1 * 4 + 1] = 1.0
--M.m[1 * 4 + 2] = 0.0
--M.m[1 * 4 + 3] = 0.0
--M.m[2 * 4 + 0] = 0.0
--M.m[2 * 4 + 1] = 0.0
M.m[2 * 4 + 2] = 1.0
--M.m[2 * 4 + 3] = 0.0
--M.m[3 * 4 + 0] = 0.0
--M.m[3 * 4 + 1] = 0.0
--M.m[3 * 4 + 2] = 0.0
M.m[3 * 4 + 3] = 1.0
return M
end,
translation = function(x, y, z)
local M = newmat4()
M.m[0 * 4 + 0] = 1.0
--M.m[0 * 4 + 1] = 0.0
--M.m[0 * 4 + 2] = 0.0
--M.m[0 * 4 + 3] = 0.0
--M.m[1 * 4 + 0] = 0.0
M.m[1 * 4 + 1] = 1.0
--M.m[1 * 4 + 2] = 0.0
--M.m[1 * 4 + 3] = 0.0
--M.m[2 * 4 + 0] = 0.0
--M.m[2 * 4 + 1] = 0.0
M.m[2 * 4 + 2] = 1.0
--M.m[2 * 4 + 3] = 0.0
M.m[3 * 4 + 0] = x
M.m[3 * 4 + 1] = y
M.m[3 * 4 + 2] = z
M.m[3 * 4 + 3] = 1.0
return M
end,
rotation_x = function(angle)
local sin_angle = sin(angle)
local cos_angle = cos(angle)
local M = newmat4()
M.m[0 * 4 + 0] = 1.0
--M.m[0 * 4 + 1] = 0.0
--M.m[0 * 4 + 2] = 0.0
--M.m[0 * 4 + 3] = 0.0
--M.m[1 * 4 + 0] = 0.0
M.m[1 * 4 + 1] = cos_angle
M.m[1 * 4 + 2] = sin_angle
--M.m[1 * 4 + 3] = 0.0
--M.m[2 * 4 + 0] = 0.0
M.m[2 * 4 + 1] = -sin_angle
M.m[2 * 4 + 2] = cos_angle
--M.m[2 * 4 + 3] = 0.0
--M.m[3 * 4 + 0] = 0.0
--M.m[3 * 4 + 1] = 0.0
--M.m[3 * 4 + 2] = 0.0
M.m[3 * 4 + 3] = 1.0
return M
end,
rotation_y = function(angle)
local sin_angle = sin(angle)
local cos_angle = cos(angle)
local M = newmat4()
M.m[0 * 4 + 0] = cos_angle
--M.m[0 * 4 + 1] = 0.0
M.m[0 * 4 + 2] = -sin_angle
--M.m[0 * 4 + 3] = 0.0
--M.m[1 * 4 + 0] = 0.0
M.m[1 * 4 + 1] = 1.0
--M.m[1 * 4 + 2] = 0.0
--M.m[1 * 4 + 3] = 0.0
M.m[2 * 4 + 0] = sin_angle
--M.m[2 * 4 + 1] = 0.0
M.m[2 * 4 + 2] = cos_angle
--M.m[2 * 4 + 3] = 0.0
--M.m[3 * 4 + 0] = 0.0
--M.m[3 * 4 + 1] = 0.0
--M.m[3 * 4 + 2] = 0.0
M.m[3 * 4 + 3] = 1.0
return M
end,
rotation_z = function(angle)
local sin_angle = sin(angle)
local cos_angle = cos(angle)
local M = newmat4()
M.m[0 * 4 + 0] = cos_angle
M.m[0 * 4 + 1] = sin_angle
--M.m[0 * 4 + 2] = 0.0
--M.m[0 * 4 + 3] = 0.0
M.m[1 * 4 + 0] = -sin_angle
M.m[1 * 4 + 1] = cos_angle
--M.m[1 * 4 + 2] = 0.0
--M.m[1 * 4 + 3] = 0.0
--M.m[2 * 4 + 0] = 0.0
--M.m[2 * 4 + 1] = 0.0
M.m[2 * 4 + 2] = 1.0
--M.m[2 * 4 + 3] = 0.0
--M.m[3 * 4 + 0] = 0.0
--M.m[3 * 4 + 1] = 0.0
--M.m[3 * 4 + 2] = 0.0
M.m[3 * 4 + 3] = 1.0
return M
end,
dot = function(a, b)
print("dot" .. tostring(a) .. tostring(b))
end
}
setmetatable(mat4, mat4)
return {
mat4 = mat4
}

BIN
bird.dds Normal file

Binary file not shown.

View File

@ -1,15 +1,25 @@
local mesh
local rotation
local texture
local ffi = require 'ffi'
local pixelcode = [[
#pragma language glsl3
varying vec4 PixelColor;
varying vec4 PixelNormal;
varying vec4 PixelTexture;
uniform sampler2D texture_sampler;
out vec4 outData;
void pixelmain()
{
outData = PixelColor;
vec4 texColor = texture(texture_sampler, PixelTexture.xy);
float intensity = min(max(dot(vec3(1, 1, 1), PixelNormal.xyz), 0), 1);
outData = vec4(texColor.xyz * (0.1 + intensity * intensity), 1.0);
}
]]
@ -25,11 +35,13 @@ local vertexcode = [[
uniform mat4 model;
uniform mat4 model2;
varying vec4 PixelColor;
varying vec4 PixelNormal;
varying vec4 PixelTexture;
void vertexmain()
{
PixelColor = VertexNormal * 0.5 + 0.5;
PixelNormal = VertexNormal * 0.5 + 0.5;
PixelTexture = VertexTexture;
mat4 trans = projection * view * model * model2;
love_Position = trans * vec4(VertexPosition.xyz, 1);
}
@ -43,8 +55,6 @@ local vertexformat = {
{ name = 'VertexTexture', format = 'floatvec3', location = 2 },
}
local rotation
function look_at()
local m = {
1.000000, 0.000000, 0.000000, 0.000000,
@ -67,7 +77,7 @@ function projection()
end
function love.load(args)
love.window.setMode(600, 600, {depth=true})
love.window.setMode(1024, 1024, {depth=true})
local vertexdata = love.filesystem.newFileData("position_normal_texture.vtx")
local indexdata = love.filesystem.newFileData("index.idx")
@ -105,6 +115,9 @@ function love.load(args)
mesh = love.graphics.newMesh(attributelist, drawmode)
mesh:setIndexBuffer(indexbuffer)
local image_data = love.image.newCompressedData('bird.dds')
texture = love.graphics.newTexture(image_data)
end
local rotation = 0.0
@ -142,15 +155,29 @@ function rotate_z(t)
}
end
function print_matrix(ptr)
for i=0,15 do
io.write(tostring(ptr[i]))
io.write(" ")
if i % 4 == 3 then
io.write("\n")
end
end
end
local math = require '_math'
local mat4 = math.mat4
function love.draw()
local radius = 100
local mx, my = love.mouse.getPosition()
shader:send("projection", projection(1, 1))
shader:send("view", look_at())
shader:send("model", rotate_x(rotation))
shader:send("model2", rotate_z(rotation * 0.5))
shader:send("view", "column", mat4.translation(0, 0, -2).data)
shader:send("model", "column", mat4.rotation_x(rotation).data)
shader:send("model2", "column", mat4.rotation_z(rotation * 0.5).data)
shader:send("texture_sampler", texture)
rotation = rotation + 0.01
love.graphics.setShader(shader)
love.graphics.setDepthMode("less", true)