On my Clickpad.The CX =)
Which one is the slowest ?
And, by the way, what is the fastest way to draw faces ?
With a lot of gc:fillRect(x,y,1,height) ?
Or with gc:fillPolygon ?
but I have to train with 3Dlol %)
Er... What's fun ?Quotebut I have to train with 3Dlol %)
Indeed you've never made 3D.. x)Er... What's fun ?Quotebut I have to train with 3Dlol %)
How do you use this library? Like, how should you store the data to render a 3D object?Two ways I guess :
cubeVertices={{0,0,0},{1,0,0},{1,1,0},{0,1,0},{0,0,1},{1,0,1},{1,1,1},{0,1,1}}
cubeFaces={{1,2,3,4},{1,2,6,5},{2,3,7,6},{3,4,8,7},{4,1,5,8},{5,6,7,8}}
color={200,200,200}
function on.paint(gc)
render(gc,cubeVertices,cubeFaces,4,color)
end
I thought CX was faster because it didn't have to do grayscale conversion. Or is that just for gc:drawImage()?On my Clickpad.The CX =)
Which one is the slowest ?
Computer Software > ClickPad/TouchPad > CX
I thought CX was faster because it didn't have to do grayscale conversion. Or is that just for gc:drawImage()?On my Clickpad.The CX =)
Which one is the slowest ?
Computer Software > ClickPad/TouchPad > CX
I thought CX was faster because it didn't have to do grayscale conversion. Or is that just for gc:drawImage()?On my Clickpad.The CX =)
Which one is the slowest ?
Computer Software > ClickPad/TouchPad > CX
I don't use drawImage() in Make3D and it is farly slower on the CX. With both Nspires rendering the same thing, the ClickPad goes faster to animate my default scene.
It does not... It only calculates the angle with the camera.I wasn't talking about that, but I think I will look at it since I think Make3D uses an old and heavy method with face normal calculations.
But to choose which polygon I draw first, I use table.sort(). Is that bad ?It depends on how table.sort() is implemented. We have to make benches about that :
And I don't say that it's fast, but it is fast enough to be playable...Make3D really slows down in shading view when we reach the limit of 200 faces displayed. It comes really fast since a 15*15 grid is 225 points and about 200 faces.
(Actually It's just a bit faster than Make3D, so I think I could optimize)
-- Use this
local _1 = 1;
if val == _1 then
-- stuff
end
aTable[_1];
Oh, and you need to localize the math library functions instead of getting them from the math table all the time.
--Lua Tiny3D - By Loic Pujet
function multiplyMatrix(matrix,vector)
local x=matrix[1][1]*vector[1]+matrix[1][2]*vector[2]+matrix[1][3]*vector[3]
local y=matrix[2][1]*vector[1]+matrix[2][2]*vector[2]+matrix[2][3]*vector[3]
local z=matrix[3][1]*vector[1]+matrix[3][2]*vector[2]+matrix[3][3]*vector[3]
return x,y,z
end
function rotate(vertices,angle,x,y,z)
local sum=x+y+z
x,y,z=x/sum,y/sum,z/sum
local c,s=math.cos(angle),math.sin(angle)
local matrix={{x*x+(1-x*x)*c,x*y*(1-c)-z*s,x*z*(1-c)+y*s},{x*y*(1-c)+z*s,y*y+(1-y*y)*c,y*z*(1-c)-x*s},{x*z*(1-c)-y*s,y*z*(1-c)+x*s,z*z+(1-z*z)*c}}
for i,e in pairs(vertices) do
vertices[i]={multiplyMatrix(matrix,e)}
end
end
function translate(vertices,x,y,z)
for i,e in pairs(vertices) do
vertices[i]={e[1]+x,e[2]+y,e[3]+z}
end
end
function scale(vertices,x,y,z)
for i,e in pairs(vertices) do
vertices[i]={e[1]*x,e[2]*y,e[3]*z}
end
end
function width() return platform.window:width() end
function height() return platform.window:height() end
function reverseTable(tbl)
local tbl2={}
for i,e in ipairs(tbl) do
tbl2[#tbl-i+1]=e
end
return tbl2
end
function replaceFaces(tbl1,tbl2,faces)
local faces2,count={},1
for i,e in pairs(tbl1) do
for j,e2 in pairs(tbl2) do
if e2 then
if e==e2 then
faces2[count]=faces[j]
count=count+1
tbl2[j]=nil
end
end
end
end
return reverseTable(faces2)
end
function sortFaces(vertices,faces)
local faces2,distTbl,facesTbl={},{},{}
local middle={}
local dist,xsum,ysum,zsum=0,0,0,0
for i,e in pairs(faces) do
xsum,ysum,zsum=0,0,0,0
for j,e2 in pairs(e) do
xsum,ysum,zsum=xsum+vertices[e2][1],ysum+vertices[e2][2],zsum+vertices[e2][3]
end
middle={xsum/#e,ysum/#e+5,zsum/#e}
dist=middle[1]*middle[1]+middle[2]*middle[2]+middle[3]*middle[3]
distTbl[i]=dist
facesTbl[i]=dist
end
table.sort(distTbl)
return replaceFaces(distTbl,facesTbl,faces)
end
function chooseColor(gc,vertices,face,color)
if #face<3 then
gc:setColorRGB(color[1],color[2],color[3])
else
local a,b,c=vertices[face[1]][1]-vertices[face[2]][1],vertices[face[1]][2]-vertices[face[2]][2],vertices[face[1]][3]-vertices[face[2]][3]
local d,e,f=vertices[face[1]][1]-vertices[face[3]][1],vertices[face[1]][2]-vertices[face[3]][2],vertices[face[1]][3]-vertices[face[3]][3]
local normale={math.abs(b*f-c*e),math.abs(c*d-a*f),math.abs(a*e-b*d)}
local angle=math.atan(math.sqrt(normale[1]*normale[1]+normale[3]*normale[3])/normale[2])
local R,G,B=color[1]+angle*-60+50,color[2]+angle*-60+50,color[3]+angle*-60+50
R,G,B=R>255 and 255 or R,G>255 and 255 or G,B>255 and 255 or B
R,G,B=R<0 and 0 or R,G<0 and 0 or G,B<0 and 0 or B
gc:setColorRGB(R,G,B)
end
end
function renderFaces(gc,vertices,faces,pos,mode,color)
local polygon,size,faces2={},0,{}
if mode==4 or mode==5 or mode==6 then
faces2=sortFaces(vertices,faces)
else
faces2=faces
end
for i,e in pairs(faces2) do
polygon,size={},0
drawPoly=true
for j,f in pairs(faces2[i]) do
if not pos[f] then
drawPoly=false
else
polygon[j*2-1]=pos[f][1]
polygon[j*2]=pos[f][2]
size=size+2
end
end
if drawPoly then
polygon[size+1]=pos[faces2[i][1]][1]
polygon[size+2]=pos[faces2[i][1]][2]
if mode==4 then
gc:setColorRGB(color[1],color[2],color[3])
gc:fillPolygon(polygon)
elseif mode==5 or mode==6 then
chooseColor(gc,vertices,e,color)
gc:fillPolygon(polygon)
end
if mode==2 or mode==3 or mode==4 or mode==5 then
gc:setColorRGB(0,0,0)
gc:setPen("thin","smooth")
gc:drawPolyLine(polygon)
end
end
end
end
function renderVertices(gc,pos)
gc:setColorRGB(0,0,0)
for i,e in pairs(pos) do
if e then
gc:fillRect(e[1]-1,e[2]-1,3,3)
end
end
end
function render(gc,vertices,faces,mode,color,offset)
local yDist,pos=0,{}
for i,e in pairs(vertices) do
if e[2]>-offset then
yDist=offset/(e[2]+offset)
pos[i]={e[1]*yDist*25+width()/2,height()/2-e[3]*yDist*25}
else
pos[i]=false
end
end
if mode==1 or mode==2 then
renderVertices(gc,pos)
end
if #faces>0 and (mode==2 or mode==3 or mode==4 or mode==5 or mode==6) then
renderFaces(gc,vertices,faces,pos,mode,color)
end
end
I just realised that I spent days to write this useless tool... :(
I just realised that I spent days to write this useless tool... :(
This is not useless, this can be made more powerful that the OS 3D graphing. Can you make it accept any functions? i.e. to insert x^2+y^2+z^2=2^2 which is an origin centered radius 2 sphere in the OS 3d graphing I've got to solve it in order to z before writing that which results in 2 equations: z(x,y)=sqrt(2^2-x^2-y^2) and z(x,y)=sqrt(2^2-x^2-y^2)
it would be nice if your Tiny3D accepted any function to draw.
This looks nice. You should post a tns demo so we can see how fast it is. :D I wonder if it could be fast enough for simple games like Star fox? I'm glad you're still working on this by the way. :DI'm not sure that it's possible, but I'll try. The main problem is the key input...
EDIT: Nvm I didn't see the zip file above the screenshots. Gonna try it soon.
--Lua Tiny3D - By Loic Pujet
function multiplyMatrix(matrix,vector)
local x=matrix[1][1]*vector[1]+matrix[1][2]*vector[2]+matrix[1][3]*vector[3]
local y=matrix[2][1]*vector[1]+matrix[2][2]*vector[2]+matrix[2][3]*vector[3]
local z=matrix[3][1]*vector[1]+matrix[3][2]*vector[2]+matrix[3][3]*vector[3]
return x,y,z
end
function width() return platform.window:width() end
function height() return platform.window:height() end
function reverseTable(tbl)
local tbl2={}
for i,e in ipairs(tbl) do
tbl2[#tbl-i+1]=e
end
return tbl2
end
function replaceFaces(tbl1,tbl2,faces)
local faces2,count={},1
for i,e in pairs(tbl1) do
for j,e2 in pairs(tbl2) do
if e2 then
if e==e2 then
faces2[count]=faces[j]
count=count+1
tbl2[j]=nil
end
end
end
end
return reverseTable(faces2)
end
function sortFaces(vertices,faces,offset)
local faces2,distTbl,facesTbl={},{},{}
local middle={}
local dist,xsum,ysum,zsum=0,0,0,0
for i,e in pairs(faces) do
xsum,ysum,zsum=0,0,0,0
for j,e2 in pairs(e) do
xsum,ysum,zsum=xsum+vertices[e2][1],ysum+vertices[e2][2],zsum+vertices[e2][3]
end
middle={xsum/#e,ysum/#e+offset,zsum/#e}
dist=middle[1]*middle[1]+middle[2]*middle[2]+middle[3]*middle[3]
distTbl[i]=dist
facesTbl[i]=dist
end
table.sort(distTbl)
return replaceFaces(distTbl,facesTbl,faces)
end
function chooseColor(gc,vertices,face,color)
if #face<3 then
gc:setColorRGB(color[1],color[2],color[3])
else
local a,b,c=vertices[face[1]][1]-vertices[face[2]][1],vertices[face[1]][2]-vertices[face[2]][2],vertices[face[1]][3]-vertices[face[2]][3]
local d,e,f=vertices[face[1]][1]-vertices[face[3]][1],vertices[face[1]][2]-vertices[face[3]][2],vertices[face[1]][3]-vertices[face[3]][3]
local normale={math.abs(b*f-c*e),math.abs(c*d-a*f),math.abs(a*e-b*d)}
local angle=math.atan(math.sqrt(normale[1]*normale[1]+normale[3]*normale[3])/normale[2])
local R,G,B=color[1]+angle*-60+50,color[2]+angle*-60+50,color[3]+angle*-60+50
R,G,B=R>255 and 255 or R,G>255 and 255 or G,B>255 and 255 or B
R,G,B=R<0 and 0 or R,G<0 and 0 or G,B<0 and 0 or B
gc:setColorRGB(R,G,B)
end
end
function renderFaces(gc,vertices,faces,pos,mode,color,offset)
local polygon,size,faces2={},0,{}
if mode==4 or mode==5 or mode==6 then
faces2=sortFaces(vertices,faces,offset)
else
faces2=faces
end
for i,e in pairs(faces2) do
polygon,size={},0
drawPoly=true
for j,f in pairs(faces2[i]) do
if not pos[f] then
drawPoly=false
else
polygon[j*2-1]=pos[f][1]
polygon[j*2]=pos[f][2]
size=size+2
end
end
if drawPoly then
polygon[size+1]=pos[faces2[i][1]][1]
polygon[size+2]=pos[faces2[i][1]][2]
if mode==4 then
gc:setColorRGB(color[1],color[2],color[3])
gc:fillPolygon(polygon)
elseif mode==5 or mode==6 then
chooseColor(gc,vertices,e,color)
gc:fillPolygon(polygon)
end
if mode==2 or mode==3 or mode==4 or mode==5 then
gc:setColorRGB(0,0,0)
gc:setPen("thin","smooth")
gc:drawPolyLine(polygon)
end
end
end
end
function renderVertices(gc,pos)
gc:setColorRGB(0,0,0)
for i,e in pairs(pos) do
if e then
gc:fillRect(e[1]-1,e[2]-1,3,3)
end
end
end
----------------------------------------------------------------------------
function rotate(vertices,angle,x,y,z)
local sum=x+y+z
x,y,z=x/sum,y/sum,z/sum
local c,s=math.cos(angle),math.sin(angle)
local matrix={{x*x+(1-x*x)*c,x*y*(1-c)-z*s,x*z*(1-c)+y*s},{x*y*(1-c)+z*s,y*y+(1-y*y)*c,y*z*(1-c)-x*s},{x*z*(1-c)-y*s,y*z*(1-c)+x*s,z*z+(1-z*z)*c}}
for i,e in pairs(vertices) do
vertices[i]={multiplyMatrix(matrix,e)}
end
end
function translate(vertices,x,y,z)
for i,e in pairs(vertices) do
vertices[i]={e[1]+x,e[2]+y,e[3]+z}
end
end
function scale(vertices,x,y,z)
for i,e in pairs(vertices) do
vertices[i]={e[1]*x,e[2]*y,e[3]*z}
end
end
function render(gc,vertices,faces,mode,color,offset)
local yDist,pos=0,{}
for i,e in pairs(vertices) do
if e[2]>-offset then
yDist=offset/(e[2]+offset)
pos[i]={e[1]*yDist*25+width()/2,height()/2-e[3]*yDist*25}
else
pos[i]=false
end
end
if mode==1 or mode==2 then
renderVertices(gc,pos)
end
if #faces>0 and (mode==2 or mode==3 or mode==4 or mode==5 or mode==6) then
renderFaces(gc,vertices,faces,pos,mode,color,offset)
end
end
----------------------------------------------------------------------------