141 lines
3.2 KiB
Lua
141 lines
3.2 KiB
Lua
--column major!
|
|
local love = assert( love )
|
|
|
|
local ffi = require('ffi')
|
|
ffi.cdef[[ typedef struct{ float m[4][4]; } mat4_t ]]
|
|
local ctype = ffi.typeof( "mat4_t*" )
|
|
local t = {}
|
|
--this is actually the argument we need to send to shader:send
|
|
--and to newMesh
|
|
local data = love.data.newByteData( ffi.sizeof( "mat4_t" ) * 1024 )
|
|
t.data = data
|
|
local ptr = data:getFFIPointer()
|
|
print( "size", data:getSize() )
|
|
|
|
function t.__tostring( idx )
|
|
assert( idx < 1024 )
|
|
local ptr = ffi.cast( ctype, data:getFFIPointer() )
|
|
local m = ptr[ idx ].m
|
|
return ([[
|
|
%.2f %.2f %.2f %.2f
|
|
%.2f %.2f %.2f %.2f
|
|
%.2f %.2f %.2f %.2f
|
|
%.2f %.2f %.2f %.2f
|
|
]]):format(
|
|
m[0][0], m[1][0], m[2][0], m[3][0],
|
|
m[0][1], m[1][1], m[2][1], m[3][1],
|
|
m[0][2], m[1][2], m[2][2], m[3][2],
|
|
m[0][3], m[1][3], m[2][3], m[3][3])
|
|
end
|
|
|
|
function t.lTRS( x, y, z, a, b, g, dx, dy, dz )
|
|
local c, s = math.cos, math.sin
|
|
local ca, sa, cb, sb, cg, sg = c(a), s(a), c(b), s(b), c(g), s(g)
|
|
return {
|
|
{x*ca*cb, y*sa*cb, z*(-sb), 0},
|
|
{x*(ca*sb*sg - sa*cg), y*(sa*sb*sg+ca*cg), z*(cb*sg), 0},
|
|
{x*(ca*sb*cg+sa*sg), y*(sa*sb*cg-ca*sg), z*cb*cg, 0},
|
|
{dx, dy, dz, 1}}
|
|
end
|
|
|
|
function t.transpose( A )
|
|
for i = 1, 4 do
|
|
for j = 1, 4 do
|
|
A[i][j] = A[j][i]
|
|
end
|
|
end
|
|
end
|
|
|
|
function t.TRS( idx, x, y, z, a, b, g, dx, dy, dz )
|
|
assert( idx < 1024 )
|
|
local ptr = ffi.cast( ctype, data:getFFIPointer() )
|
|
local m = ptr[ idx ].m
|
|
|
|
local c, s = math.cos, math.sin
|
|
local ca, sa, cb, sb, cg, sg = c(a), s(a), c(b), s(b), c(g), s(g)
|
|
m[0][0], m[0][1], m[0][2], m[0][3],
|
|
m[1][0], m[1][1], m[1][2], m[1][3],
|
|
m[2][0], m[2][1], m[2][2], m[2][3],
|
|
m[3][0], m[3][1], m[3][2], m[3][3] =
|
|
|
|
x*ca*cb, x*(ca*sb*sg - sa*cg), x*(ca*sb*cg+sa*sg), dx,
|
|
y*sa*cb, y*(sa*sb*sg+ca*cg), y*(sa*sb*cg-ca*sg), dy,
|
|
z*(-sb), z*(cb*sg), z*cb*cg, dz,
|
|
0, 0, 0, 1
|
|
|
|
|
|
do local p, m = ptr, m end --keep alive
|
|
return idx
|
|
end
|
|
|
|
function t.__mul( A, B )
|
|
local C = ffi.gc(cmat4(),nil)
|
|
for j = 1, 4 do
|
|
for i = 1, 4 do
|
|
C.x[j][i] =
|
|
A.x[1][i] * B.x[j][1] +
|
|
A.x[2][i] * B.x[j][2] +
|
|
A.x[3][i] * B.x[j][3] +
|
|
A.x[4][i] * B.x[j][4]
|
|
end
|
|
end
|
|
return C
|
|
end
|
|
|
|
function t.__add( A, B )
|
|
local C = cmat4()
|
|
for i = 1, 4 do
|
|
for j = 1, 4 do
|
|
C[i][j] = A.x[i][j] + B.x[i][j]
|
|
end
|
|
end
|
|
return C
|
|
end
|
|
|
|
function t.randomise( start, len )
|
|
start = start or 0
|
|
len = len or 1023
|
|
for i = start, start + len do
|
|
t.TRS( i,
|
|
--scale
|
|
1,
|
|
1,
|
|
1,
|
|
0,
|
|
0,
|
|
0,
|
|
--pos
|
|
0,
|
|
0,
|
|
-4 )
|
|
end
|
|
end
|
|
|
|
function t.id()
|
|
local ptr = ffi.cast( ctype, data:getFFIPointer() )
|
|
for i = 1, 1024 do
|
|
local m = ptr[ i ].m
|
|
|
|
m[0][0], m[1][1], m[2][2], m[3][3] = 1, 1, 1, 1
|
|
|
|
do local p, m = ptr, m end --keep alive
|
|
end
|
|
end
|
|
|
|
do --tests
|
|
local math = math
|
|
--[[ for i = 0, 1023 do
|
|
t.TRS( i,
|
|
0.5 + math.random(),
|
|
0.5 + math.random(),
|
|
0.5 + math.random(),
|
|
2 * math.pi * math.random(),
|
|
2 * math.pi * math.random(),
|
|
2 * math.pi * math.random(),
|
|
10 * math.random(),
|
|
10 * math.random(),
|
|
10 * math.random() )
|
|
end]]
|
|
end
|
|
|
|
return t |