I used the example.
https://stackoverflow.com/questions/280 ... 0#28084380
but something went wrong
does anyone have experience with something like this
Code: Select all
---@type love
local love = require("love")
--perspective
local znear = 100.0 --focal length for perspective
local zfar = 2100.0 --visibility
--view
local xs2 = 400 --screen half resolution
local ys2 = 300
--camera
local yaw = 0.0 --euler yaw angle [rad]
local camera = {} --camera direct transform matrix
local icamera = {} --camera inverse transform matrix
local m_pi = 3.14159265358979323846
function matrix_inv(a, b) -- a[16] = Inverse(b[16])
--transpose of rotation matrix
a[0] = b[0]
a[5] = b[5]
a[10] = b[10]
local x = b[1] a[1] = b[4] a[4] = x;
x = b[2] a[2] = b[8] a[8] = x
x = b[6] a[6] = b[9] a[9] = x
--copy projection part
a[ 3] = b[ 3]
a[ 7] = b[ 7]
a[11] = b[11]
a[15] = b[15]
--convert origin: new_pos = - new_rotation_matrix * old_pos
x=(a[ 0]*b[12])+(a[ 4]*b[13])+(a[ 8]*b[14])
local y=(a[ 1]*b[12])+(a[ 5]*b[13])+(a[ 9]*b[14])
local z=(a[ 2]*b[12])+(a[ 6]*b[13])+(a[10]*b[14])
a[12]=-x
a[13]=-y
a[14]=-z
end
function matrix_mul_vector(c, a, b) --c[3] = a[16]*b[3]
local q = {}
q[0] = (a[ 0]*b[0])+(a[ 4]*b[1])+(a[ 8]*b[2])+(a[12])
q[1] = (a[ 1]*b[0])+(a[ 5]*b[1])+(a[ 9]*b[2])+(a[13])
q[2] = (a[ 2]*b[0])+(a[ 6]*b[1])+(a[10]*b[2])+(a[14])
for i = 0, 2 do
c[i] = q[i]
end
end
function compute_matrices()
--bound angle
while yaw > 2.0 * m_pi do yaw = yaw - 2.0 * m_pi end
while yaw < 0.0 do yaw = yaw + 2.0 * m_pi end
--X = right
camera[ 0] = math.cos( yaw )
camera[ 1] = 0.0
camera[ 2] = math.sin( yaw )
--Y = up
camera[ 4] = 0.0
camera[ 5] = 1.0
camera[ 6] = 0.0
--Z = forward
camera[ 8] = -math.sin( yaw )
camera[ 9] = 0.0
camera[10] = math.cos( yaw )
--no projection
camera[ 3] = 0.0
camera[ 7] = 0.0
camera[11] = 0.0
camera[15] = 1.0
--compute the inverse matrix
matrix_inv( icamera, camera );
end
function perspective( P ) --apply perspective transform
--perspectve division
P[0]= P[0] * znear/P[2]
P[1] = P[1] * znear/P[2]
--screen coordinate system
P[0] = xs2 + P[0] -- move (0,0) to screen center
P[1] = ys2 - P[1] -- axises: x=right, y=up
end
function draw_line(pA, pB) -- draw 3D line
local t
local D=create_table_0() A=create_table_0() B=create_table_0()
--transform to camera coordinate system
matrix_mul_vector(A, icamera, pA);
matrix_mul_vector(B, icamera, pB);
--sort points so A.z<B.z
if A[2] > B[2] then
for i=0, 2 do D[i]=A[i] A[i]=B[i] B[i]=D[i] end
end
--D = B-A
for i=0, 2 do D[i]=B[i]-A[i] end
--ignore out of Z view lines
if A[2] > zfar then return end
if B[2] < znear then return end
--cut line to view if needed
if A[2] < znear then
t=(znear-A[2])/D[2]
A[0]= A[0] + D[0]*t
A[1]= A[1] + D[1]*t
A[2] = znear
end
if B[2]>zfar then
t=(zfar-B[2])/D[2]
B[0] = B[0] + D[0]*t
B[1] = B[1] + D[1]*t
B[2] = zfar
end
--apply perspective
perspective(A);
perspective(B);
--render
love.graphics.line( A[0], A[1], B[0], B[1] )
end
function draw_plane_xz( y, step ) -- draw 3D plane
local t, size
local A=create_table_0() B=create_table_0()
local U={} U[0] = 1.0 U[1] = 0.0 U[2] = 0.0 -- U = X
local V={} V[0] = 0.0 V[1] = 0.0 V[2] = 1.0 -- V = Z
local O=create_table_0() -- Origin
-- compute origin near view center but align to step
local tt=0
O[tt]=math.floor(camera[12+tt]/step)*step
tt=2
O[tt]=math.floor(camera[12+tt]/step)*step
O[1] = y
-- set size so plane safely covers whole view
t = xs2*zfar/znear
size = t -- x that will convert to xs2 at zfar
t = 0.5*(zfar+znear)
if size<t then size=t end -- half of depth range
t= t + step; -- + one grid cell beacuse O is off up to 1 grid cell
t= t * math.sqrt(2); -- diagonal so no matter how are we rotate in Yaw
-- U lines
for i=0, 2 do
A[i]=O[i]+(size*U[i])-((step+size)*V[i])
B[i]=O[i]-(size*U[i])-((step+size)*V[i])
end
for ii=-size, size, step do
for i=0, 2 do
A[i]= A[i] + step*V[i]
B[i] = B[i] + step*V[i]
end
draw_line( A, B )
end
-- V lines
for i=0, 2 do
A[i]=O[i]-((step+size)*U[i])+(size*V[i])
B[i]=O[i]-((step+size)*U[i])-(size*V[i])
end
for ii=-size, size, step do
for i=0, 2 do
A[i]=A[i] + step*U[i];
B[i]=B[i] + step*U[i];
end
draw_line( A, B );
end
matrix_mul_vector( A, icamera, A );
end
function love.load( arg, unfilteredArg )
camera[12]=0.0
camera[13]=0.0
camera[14]=0.0
compute_matrices()
end
function create_table_0()
local table = {}
table[0] = 0.0
table[1] = 0.0
table[2] = 0.0
return table;
end
function test()
local A={0.0, 0.0, 0.0}
for i=1, 3 do
print("test "..i.."="..A[i]);
end
end
function love.draw()
--init/update variables
local step= 50.0
--sky
love.graphics.setColor(0, 0, 255)
draw_plane_xz( 200.0, step )
--terrain
love.graphics.setColor(0, 255, 0)
draw_plane_xz( -200.0, step )
end
function love.update(dt)
local da=5.0*m_pi / 180.0 --turn speed
local dl=15.0
local recompute = false
if love.keyboard.isDown("up") then
for i=0, 2 do camera[12+i]=camera[12+i] + dl*camera[8+i] end
recompute = true
end
if love.keyboard.isDown("down") then
for i=0, 2 do camera[12+i]=camera[12+i] - dl*camera[8+i] end
recompute = true
end
if love.keyboard.isDown("left") then
yaw=yaw + da
recompute = true
end
if love.keyboard.isDown("right") then
yaw=yaw-da
recompute = true
end
if recompute == true then compute_matrices() end
end