0 Members and 2 Guests are viewing this topic.
--Lua Tiny3D - By Loic Pujetfunction 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,zendfunction width() return platform.window:width() endfunction height() return platform.window:height() endfunction reverseTable(tbl) local tbl2={} for i,e in ipairs(tbl) do tbl2[#tbl-i+1]=e end return tbl2endfunction 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)endfunction 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)endfunction 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) endendfunction 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 endendfunction 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 endend----------------------------------------------------------------------------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)} endendfunction translate(vertices,x,y,z) for i,e in pairs(vertices) do vertices[i]={e[1]+x,e[2]+y,e[3]+z} endendfunction scale(vertices,x,y,z) for i,e in pairs(vertices) do vertices[i]={e[1]*x,e[2]*y,e[3]*z} endendfunction 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) endend----------------------------------------------------------------------------
On my Clickpad.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 3D
Quotebut I have to train with 3Dlol %)
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,zendfunction 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)} endendfunction translate(vertices,x,y,z) for i,e in pairs(vertices) do vertices[i]={e[1]+x,e[2]+y,e[3]+z} endendfunction scale(vertices,x,y,z) for i,e in pairs(vertices) do vertices[i]={e[1]*x,e[2]*y,e[3]*z} endendfunction width() return platform.window:width() endfunction height() return platform.window:height() endfunction reverseTable(tbl) local tbl2={} for i,e in ipairs(tbl) do tbl2[#tbl-i+1]=e end return tbl2endfunction replaceFaces(tbl1,tbl2,faces) local faces2={} for i,e in pairs(tbl1) do for j,e2 in pairs(tbl2) do if e2 then if e==e2 then table.insert(faces2,faces[j]) tbl2[j]=nil end end end end return reverseTable(faces2)endfunction 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=math.sqrt(middle[1]*middle[1]+middle[2]*middle[2]+middle[3]*middle[3]) table.insert(distTbl,dist) table.insert(facesTbl,dist) end table.sort(distTbl) return replaceFaces(distTbl,facesTbl,faces)endfunction renderFaces(gc,vertices,faces,pos,mode) local polygon={} local faces2=sortFaces(vertices,faces) for i,e in pairs(faces2) do polygon={} for j,f in pairs(faces2[i]) do table.insert(polygon,pos[f][1]) table.insert(polygon,pos[f][2]) end table.insert(polygon,pos[faces2[i][1]][1]) table.insert(polygon,pos[faces2[i][1]][2]) if mode==4 or mode==5 then gc:setColorRGB(200,200,200) gc:fillPolygon(polygon) end if mode==2 or mode==3 or mode==4 then gc:setColorRGB(0,0,0) gc:drawPolyLine(polygon) end endendfunction 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 endendfunction render(gc,vertices,faces,mode) local ray,dist,nb,pos={},0,0,{} for i,e in pairs(vertices) do if e[2]<5 then ray={e[1],e[2]-5,e[3]} dist=math.sqrt(ray[1]*ray[1]+ray[2]*ray[2]+ray[3]*ray[3]) nb=((dist*5)/(ray[2]))/dist table.insert(pos,{ray[1]*nb*25+width()/2,ray[3]*nb*25+height()/2}) else table.insert(pos,false) end end if mode==1 or mode==2 then renderVertices(gc,pos) end if mode==2 or mode==3 or mode==4 or mode==5 then renderFaces(gc,vertices,faces,pos,mode) endend