81de993d66
* `cmake`: Remove trailing spaces * `build`, `src`: Remove trailing spaces * `templates`: Remove trailing spaces * `demos`: Remove trailing spaces * `include`: Remove trailing spaces
297 lines
8.6 KiB
Lua
297 lines
8.6 KiB
Lua
-- title: ModelRenderer
|
|
-- author: FlamingPandas
|
|
-- desc: Shows 3D models
|
|
-- script: lua
|
|
|
|
point={x=0,y=0,z=300}
|
|
fov=100
|
|
mesh={} -- Table that contains all the 3D points
|
|
polygon={} -- Table that contains all connections of 3D points to create triangle polygons, with their texture specified too
|
|
zorder={} -- Table used to know the rendering order of the triangles
|
|
rspeed=.1 -- Rotation speed, you can change it
|
|
tspeed=10 -- Translation speed, you can change it
|
|
|
|
function addMesh(mx,my,mz)
|
|
local m={x=mx,y=my,z=mz,u=0,v=0}
|
|
table.insert(mesh,m)
|
|
end
|
|
|
|
function addPolygon(pp1,pp2,pp3,pu1,pv1,pu2,pv2,pu3,pv3)
|
|
local p={p1=pp1,p2=pp2,p3=pp3,u1=pu1,v1=pv1,u2=pu2,v2=pv2,u3=pu3,v3=pv3,zOrd=0}
|
|
table.insert(polygon,p)
|
|
end
|
|
|
|
function addZOrder(polygon,zor)
|
|
local z={poly=polygon,zo=zor}
|
|
table.insert(zorder,z)
|
|
end
|
|
|
|
function init()
|
|
--"Loading" points and polygon data
|
|
local m=addMesh
|
|
m(-60,-60,5)
|
|
m(60,-60,5)
|
|
m(-60,-100,0)
|
|
m(60,-100,0)
|
|
m(-60,-105,-20)
|
|
m(60,-105,-20)
|
|
m(-60,-90,-30)
|
|
m(60,-90,-30)
|
|
m(-60,95,-30)
|
|
m(60,95,-30)
|
|
m(-60,100,-25)
|
|
m(60,100,-25)
|
|
m(-60,100,0)
|
|
m(60,100,0)
|
|
m(-60,50,5)
|
|
m(60,50,5)
|
|
m(-55,10,30)
|
|
m(55,10,30)
|
|
m(-55,-50,30)
|
|
m(55,-50,30)
|
|
local p=addPolygon
|
|
--UnderNeath Surface
|
|
p(7,8,10, 32,0,48,0,48,16)
|
|
p(7,10,9, 32,0,48,16,32,16)
|
|
--Back Protection
|
|
p(5,6,8, 16,12,32,12,32,16)
|
|
p(5,8,7, 16,12,32,16,16,16)
|
|
--Back lights
|
|
p(3,4,6, 16,8,32,8,32,12)
|
|
p(3,6,5, 16,8,32,12,16,12)
|
|
--Back Capo... maletera
|
|
p(1,2,4, 0,0,16,0,16,8)
|
|
p(1,4,3, 0,0,16,8,0,8)
|
|
--Back WindShield
|
|
p(19,20,2, 48,8,64,8,64,14)
|
|
p(19,2,1, 48,8,64,14,48,14)
|
|
--Roof
|
|
p(20,19,17, 0,7,16,7,16,16)
|
|
p(20,17,18, 0,7,16,16,0,16)
|
|
--Front WindShield
|
|
p(18,15,16, 48,0,64,8,48,8)
|
|
p(18,17,15, 48,0,64,0,64,8)
|
|
--Front Capo
|
|
p(16,13,14, 0,0,16,8,0,8)
|
|
p(16,15,13, 0,0,16,0,16,8)
|
|
--Front Lights
|
|
p(14,13,11, 16,0,32,0,32,4)
|
|
p(14,11,12, 16,0,32,4,16,4)
|
|
--Front Protection
|
|
p(12,11,9, 16,5,32,5,32,8)
|
|
p(12,9,10, 16,5,32,5,16,8)
|
|
--Left WindShield
|
|
p(16,20,18, 64,8,80,0,64,0)
|
|
p(16,2,20, 64,8,80,8,80,0)
|
|
--Right WindShield
|
|
p(15,17,19, 64,8,64,0,80,0)
|
|
p(15,19,1, 64,8,80,0,80,8)
|
|
|
|
--Right side
|
|
p(4,2,6, 32,24,24,24,32,28)
|
|
p(6,2,8, 32,28,24,24,28,32)
|
|
p(2,16,8, 24,24,10,24,28,32)
|
|
p(8,16,10, 28,32,10,24,1,32)
|
|
p(16,12,10, 10,24,0,31,1,32)
|
|
p(16,14,12, 10,24,0,24,0,31)
|
|
|
|
--Left side
|
|
p(1,3,5, 24,16,32,16,32,20)
|
|
p(1,5,7, 24,16,32,20,28,24)
|
|
p(15,1,7, 10,16,24,16,28,24)
|
|
p(15,7,9, 10,16,28,24,1,24)
|
|
p(15,9,11, 10,16,1,24,0,23)
|
|
p(15,11,13, 10,16,0,23,0,16)
|
|
for i,p in pairs(polygon) do
|
|
addZOrder(i,0)
|
|
end
|
|
end
|
|
init()
|
|
|
|
mode=1
|
|
|
|
function TIC()
|
|
if btn(6) then
|
|
if btn(0) then translate(0,-tspeed,0) end
|
|
if btn(1) then translate(0,tspeed,0) end
|
|
if btn(2) then translate(-tspeed,0,0) end
|
|
if btn(3) then translate(tspeed,0,0) end
|
|
else
|
|
if btn(0) then rotatateX(-rspeed) end
|
|
if btn(1) then rotatateX(rspeed) end
|
|
if btn(2) then rotatateY(-rspeed) end
|
|
if btn(3) then rotatateY(rspeed) end
|
|
end
|
|
if btn(4) then if fov<800 then fov=fov+10 end end
|
|
if btn(5) then if fov>10 then fov=fov-10 end end
|
|
if btnp(7) then if mode<3 then mode=mode+1 else mode=1 end end
|
|
cls(13)
|
|
--Shows info from the zorder table
|
|
-- for i,z in pairs(zorder) do
|
|
-- print(z.poly.." - "..z.zo,10,10*i)
|
|
-- end
|
|
calculateMeshUV()
|
|
calculateZOrder()
|
|
table.sort(zorder,function(a,b) return a.zo > b.zo end)
|
|
|
|
if mode==1 then showMesh() end
|
|
if mode==2 then showWireFrame() end
|
|
if mode==3 then showMesh() showWireFrame() end
|
|
end
|
|
|
|
--Given this 3D points calculate how they would look in a 2D screen
|
|
function calculateMeshUV()
|
|
for i,m in pairs(mesh) do
|
|
m.u=((m.x+point.x)*(fov/(m.z+point.z)))+120
|
|
m.v=((m.y+point.y)*(fov/(m.z+point.z)))+70
|
|
end
|
|
end
|
|
|
|
-- I made this up but not works... it gives the average of the depth of the three points of each triangle, it works good enough to know witch triangles to draw first (the further ones)
|
|
function calculateZOrder()
|
|
m=mesh
|
|
for i,p in pairs(polygon) do
|
|
p.zord=(m[p.p1].z+m[p.p2].z+m[p.p3].z)/3
|
|
updateZOrder(i,p.zord)
|
|
end
|
|
end
|
|
|
|
-- Once calculated the zorder you need to update the zorder table with those values
|
|
-- Why do we need this values in another table? well... lua can sort this table and now we have the order in witch to draw the triangles
|
|
function updateZOrder(polygon,zor)
|
|
for i,z in pairs(zorder) do
|
|
if z.poly==polygon then
|
|
z.zo=zor
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Using the textri function you can show triangles with textures
|
|
-- This function draws all triangles that are facimg the camera with the textures defined on the init function
|
|
-- The function draws them in the zorder from further to closest so when a triangle is closer it shows "Above" othee triangles
|
|
function showMesh()
|
|
m=mesh
|
|
for i,z in pairs(zorder) do
|
|
p=polygon[z.poly]
|
|
-- If the triangle points are clockwise they are facing the camera
|
|
if isClockWise(p) then
|
|
--Draw the textured triangle
|
|
ttri(m[p.p1].u,m[p.p1].v,
|
|
m[p.p2].u,m[p.p2].v,
|
|
m[p.p3].u,m[p.p3].v,
|
|
p.u1,p.v1,
|
|
p.u2,p.v2,
|
|
p.u3,p.v3,
|
|
0,{},
|
|
(m[p.p1].z+point.z),
|
|
(m[p.p2].z+point.z),
|
|
(m[p.p3].z+point.z))
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Given a triangle return true if it's points are clockwise false if they aren't
|
|
function isClockWise(poly)
|
|
p=poly
|
|
m=mesh
|
|
if ((m[p.p2].v-m[p.p1].v)*
|
|
(m[p.p3].u-m[p.p2].u))-
|
|
((m[p.p3].v-m[p.p2].v)*
|
|
(m[p.p2].u-m[p.p1].u))>0 then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
--Function that draws all lines in the three points of a triangle (it just shpws the WireFrame and also the individual points)
|
|
function showWireFrame()
|
|
m=mesh
|
|
for i,p in pairs(polygon) do
|
|
line(m[p.p1].u,m[p.p1].v,m[p.p2].u,m[p.p2].v,15)
|
|
line(m[p.p2].u,m[p.p2].v,m[p.p3].u,m[p.p3].v,15)
|
|
line(m[p.p3].u,m[p.p3].v,m[p.p1].u,m[p.p1].v,15)
|
|
end
|
|
for i,m in pairs(mesh) do
|
|
circ(m.u,m.v,1,0)
|
|
print(i,m.u,m.v+5,3)
|
|
end
|
|
end
|
|
|
|
-- Rotates all pf the points in the mesh by an angle in the x axes
|
|
function rotatateX(angle)
|
|
cos=math.cos(angle)
|
|
sin=math.sin(angle)
|
|
for i,p in pairs(mesh) do
|
|
y=p.y*cos-p.z*sin
|
|
z=p.z*cos+p.y*sin
|
|
p.y=y
|
|
p.z=z
|
|
end
|
|
end
|
|
|
|
function rotatateY(angle)
|
|
cos=math.cos(angle)
|
|
sin=math.sin(angle)
|
|
for i,p in pairs(mesh) do
|
|
x=p.x*cos-p.z*sin
|
|
z=p.z*cos+p.x*sin
|
|
p.x=x
|
|
p.z=z
|
|
end
|
|
end
|
|
|
|
function rotatateZ(angle)
|
|
cos=math.cos(angle)
|
|
sin=math.sin(angle)
|
|
for i,p in pairs(mesh) do
|
|
x=p.x*cos-p.y*sin
|
|
y=p.y*cos+p.x*sin
|
|
p.x=x
|
|
p.y=y
|
|
end
|
|
end
|
|
|
|
-- Translate all of the points an x,y and z distance
|
|
function translate(dx,dy,dz)
|
|
point.x=point.x+dx
|
|
point.y=point.y+dy
|
|
point.z=point.z+dz
|
|
end
|
|
-- <TILES>
|
|
-- 000:66666ff666666ff666666ff666666ff666666ff666666ff666666ff666666ff6
|
|
-- 001:6ff666666ff666666ff666666ff666666ff666666ff666666ff666666ff66666
|
|
-- 002:66666ff66ee373736ee737376666666663333333633333336333333363333333
|
|
-- 003:6ff6666673737ee637373ee66666666633333336333333363333333633333336
|
|
-- 004:63337733633377336333377363333773633aaaa3633aaaa3633aaaa3633aaaa3
|
|
-- 005:337733363377333637733336377333363aaaa3363aaaa3363aaaa3363aaaa336
|
|
-- 006:66666ff66888dd33688ddd8868ddd8886ddd888d6dd888dd6d00000d66666ff6
|
|
-- 007:6ff6666633ddd8868ddd8886ddd88886dd888886d8888886800000866ff66666
|
|
-- 008:6666666668888888688888886888888868888888688888886888888866666666
|
|
-- 009:6666666688888886888888868888888688888886888888868888888666666666
|
|
-- 010:6666666666666666666666666666666666666666666666666666666666666666
|
|
-- 011:6666666666666666666666666666666666666666666666666666666666666666
|
|
-- 016:66666f00666660ff66660ff066660fff66660fff666660ff66666f0066666ff6
|
|
-- 017:00f66666ff0666660ff066660ff066660ff06666ff06666600f666666ff66666
|
|
-- 018:66666ff669996faa69996faa666600f663337733633377336333773363337733
|
|
-- 019:6ff66666aaf69996aaf699966f00666633773336337733363377333633773336
|
|
-- 020:6333337363333373633337336333373363333733633337336333333363333333
|
|
-- 021:3733333637333336337333363373333633733336337333363333333633333336
|
|
-- 022:66666ff66888ddd8688ddd8868ddd8886dd0000066666ff60000000000000000
|
|
-- 023:6ff6666688ddd8868ddd8886ddd88886dd8888866ff666660000000000000000
|
|
-- 026:6666666666666666666666666666666666666666666666666666666666666666
|
|
-- 027:6666666666666666666666666666666666666666666666666666666666666666
|
|
-- 032:6666666666666666666666666666666666666666666666336666630066663000
|
|
-- 033:6666666666666666666006666666666666666666336666660036666600036666
|
|
-- 034:6666666666666666666666666666666666666666666666336666630066663000
|
|
-- 035:6666666666666666666666666666666666666666336666660036666600036666
|
|
-- 048:6666666666666666666666666666666666666666666666336666630066663000
|
|
-- 049:6666666666666666666006666666666666666666336666660036666600036666
|
|
-- 050:6666666666666666666666666666666666666666666666336666630066663000
|
|
-- 051:6666666666666666666666666666666666666666336666660036666600036666
|
|
-- </TILES>
|
|
|
|
-- <PALETTE>
|
|
-- 000:140c1c44243430346d4e4a4e854c30346524d04648757161597dceb23c408595a16daa2cd2aa996dc2cadad45edeeed6
|
|
-- </PALETTE>
|