Files
SDL3CPlusPlus/scripts/math3d.lua
Richard Ward 3ca9ce773d code
2025-12-18 19:13:31 +00:00

120 lines
2.6 KiB
Lua

local math3d = {}
local function normalize(vec)
local x, y, z = vec[1], vec[2], vec[3]
local len = math.sqrt(x * x + y * y + z * z)
if len == 0.0 then
return {x, y, z}
end
return {x / len, y / len, z / len}
end
local function cross(a, b)
return {
a[2] * b[3] - a[3] * b[2],
a[3] * b[1] - a[1] * b[3],
a[1] * b[2] - a[2] * b[1],
}
end
local function dot(a, b)
return a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
end
local function identity_matrix()
return {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
}
end
function math3d.identity()
return identity_matrix()
end
function math3d.multiply(a, b)
local result = {}
for row = 1, 4 do
for col = 1, 4 do
local sum = 0.0
for idx = 1, 4 do
sum = sum + a[(idx - 1) * 4 + row] * b[(col - 1) * 4 + idx]
end
result[(col - 1) * 4 + row] = sum
end
end
return result
end
function math3d.translation(x, y, z)
return {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
x, y, z, 1.0,
}
end
function math3d.rotation_x(radians)
local c = math.cos(radians)
local s = math.sin(radians)
return {
1.0, 0.0, 0.0, 0.0,
0.0, c, s, 0.0,
0.0, -s, c, 0.0,
0.0, 0.0, 0.0, 1.0,
}
end
function math3d.rotation_y(radians)
local c = math.cos(radians)
local s = math.sin(radians)
return {
c, 0.0, -s, 0.0,
0.0, 1.0, 0.0, 0.0,
s, 0.0, c, 0.0,
0.0, 0.0, 0.0, 1.0,
}
end
function math3d.look_at(eye, center, up)
local f = normalize({center[1] - eye[1], center[2] - eye[2], center[3] - eye[3]})
local s = normalize(cross(f, up))
local u = cross(s, f)
local result = identity_matrix()
result[1] = s[1]
result[2] = u[1]
result[3] = -f[1]
result[5] = s[2]
result[6] = u[2]
result[7] = -f[2]
result[9] = s[3]
result[10] = u[3]
result[11] = -f[3]
result[13] = -dot(s, eye)
result[14] = -dot(u, eye)
result[15] = dot(f, eye)
return result
end
function math3d.perspective(fov, aspect, zNear, zFar)
local tanHalf = math.tan(fov / 2.0)
local result = {
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
}
result[1] = 1.0 / (aspect * tanHalf)
result[6] = -1.0 / tanHalf
result[11] = zFar / (zNear - zFar)
result[12] = -1.0
result[15] = (zNear * zFar) / (zNear - zFar)
return result
end
return math3d