Author Topic: [Lua] Tiny3D  (Read 26834 times)

0 Members and 1 Guest are viewing this topic.

Offline Levak

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1002
  • Rating: +208/-39
    • View Profile
    • My website
Re: [Lua] Tiny3D
« Reply #30 on: September 28, 2011, 12:40:55 pm »
On my Clickpad.
Which one is the slowest ?
The CX =)

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()?

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.
« Last Edit: September 28, 2011, 12:41:29 pm by Levak »
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

Offline calc84maniac

  • eZ80 Guru
  • Coder Of Tomorrow
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2912
  • Rating: +471/-17
    • View Profile
    • TI-Boy CE
Re: [Lua] Tiny3D
« Reply #31 on: September 28, 2011, 12:44:25 pm »
On my Clickpad.
Which one is the slowest ?
The CX =)

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()?

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.

Hmm, in that case it is probably related to the screen buffer copy which is 4 times as much data on the CX, and TI had a pretty darn unoptimized memcpy() the last time I checked.
"Most people ask, 'What does a thing do?' Hackers ask, 'What can I make it do?'" - Pablos Holman

Offline Chockosta

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 447
  • Rating: +169/-6
    • View Profile
Re: [Lua] Tiny3D
« Reply #32 on: September 30, 2011, 12:27:41 pm »
New !
Mode 5 now has shading !
It can do beautiful things :)

And I've started a small game with that, it is fast enough to be fun. (see screenshots)

EDIT : Oops, forgot the code... Fixed.
Spoiler For Spoiler:
Code: [Select]
--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={}
 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)
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={}
 local faces2=sortFaces(vertices,faces)
 for i,e in pairs(faces2) do
  polygon={}
  drawPoly=true
  for j,f in pairs(faces2[i]) do
   if not pos[f] then
    drawPoly=false
   else
    table.insert(polygon,pos[f][1])
    table.insert(polygon,pos[f][2])
   end
  end
  if drawPoly then
   table.insert(polygon,pos[faces2[i][1]][1])
   table.insert(polygon,pos[faces2[i][1]][2])
   if mode==4 then
    gc:setColorRGB(color[1],color[2],color[3])
    gc:fillPolygon(polygon)
   elseif mode==5 then
    chooseColor(gc,vertices,e,color)
    gc:fillPolygon(polygon)
   end
   if mode==2 or mode==3 or mode==4 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)
 local yDist,pos=0,{}
 for i,e in pairs(vertices) do
  if e[2]>-5 then
   yDist=5/(e[2]+5)
   table.insert(pos,{e[1]*yDist*25+width()/2,height()/2-e[3]*yDist*25})
  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,color)
 end
end
« Last Edit: September 30, 2011, 02:03:36 pm by Chockosta »

Offline Levak

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1002
  • Rating: +208/-39
    • View Profile
    • My website
Re: [Lua] Tiny3D
« Reply #33 on: September 30, 2011, 05:44:14 pm »
Does your Shading mode use the crappy table.sort() I saw in previous versions ? or did you change it ?
I just wish to find what method you used to render that as fast as you say (I didn't tried yet, you just judges that it is fast :D).
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

Offline Chockosta

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 447
  • Rating: +169/-6
    • View Profile
Re: [Lua] Tiny3D
« Reply #34 on: October 01, 2011, 07:00:53 am »
It does not... It only calculates the angle with the camera.
But to choose which polygon I draw first, I use table.sort(). Is that bad ?
And I don't say that it's fast, but it is fast enough to be playable...
(Actually It's just a bit faster than Make3D, so I think I could optimize)

Offline Levak

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1002
  • Rating: +208/-39
    • View Profile
    • My website
Re: [Lua] Tiny3D
« Reply #35 on: October 01, 2011, 07:40:25 am »
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.

Quote
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 :
 - insert element at it right place with table.insert(e, n) while computing it (mine)
 - compute elements, then table.sort(l, fun) (your)

Quote
And I don't say that it's fast, but it is fast enough to be playable...
(Actually It's just a bit faster than Make3D, so I think I could optimize)
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.
This is why I was curious of what method you used without looking at your sources :D
« Last Edit: October 01, 2011, 07:41:06 am by Levak »
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

Offline Chockosta

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 447
  • Rating: +169/-6
    • View Profile
Re: [Lua] Tiny3D
« Reply #36 on: October 01, 2011, 09:08:14 am »
Let's try with 441 vertices and 400 faces...
Video here

Not really fast...
« Last Edit: October 01, 2011, 09:08:22 am by Chockosta »

Offline Levak

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1002
  • Rating: +208/-39
    • View Profile
    • My website
Re: [Lua] Tiny3D
« Reply #37 on: October 01, 2011, 10:32:11 am »
line 49 : I think you'd better use

count = 0
...
for ...
 count = count + 1
 faces2[count] = faces[j]
end
...
table.setn(faces2, count)

instead of table.insert which is 7 times slower.

EDIT : it seems that table.setn is depreaciated. Just test that without it and only if #faces2 is egual to 0, use it.
« Last Edit: October 01, 2011, 12:52:22 pm by Levak »
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

Offline Chockosta

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 447
  • Rating: +169/-6
    • View Profile
Re: [Lua] Tiny3D
« Reply #38 on: October 01, 2011, 12:07:21 pm »
I removed all table.insert()...
But the speed did not changed at all.
I think nSpire Lua doesn't work exactly like PC Lua.

However, here is the new code :
Spoiler For Spoiler:
Code: [Select]
--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={},0
 local faces2=sortFaces(vertices,faces)
 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 then
    chooseColor(gc,vertices,e,color)
    gc:fillPolygon(polygon)
   end
   if mode==2 or mode==3 or mode==4 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)
 local yDist,pos=0,{}
 for i,e in pairs(vertices) do
  if e[2]>-5 then
   yDist=5/(e[2]+5)
   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) then
  renderFaces(gc,vertices,faces,pos,mode,color)
 end
end

Offline Levak

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1002
  • Rating: +208/-39
    • View Profile
    • My website
Re: [Lua] Tiny3D
« Reply #39 on: October 01, 2011, 12:54:53 pm »
Strange, really strange.
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

Offline NecroBumpist

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 130
  • Rating: +14/-5
  • Master of Lua
    • View Profile
Re: [Lua] Tiny3D
« Reply #40 on: October 01, 2011, 02:07:19 pm »
If you're looking to micro-optimize at this point, you might as well begin changing constants to locals as well.

Code: (Example) [Select]
-- Use this
local _1 = 1;

if val == _1 then
-- stuff
end

aTable[_1];

I have no idea how much this will improve speed, but it will. Remember to localize both string and number constants.

Oh, and you need to localize the math library functions instead of getting them from the math table all the time.
Developing Lua scripts for the NSpire ?
Check out the Necrotorium
Need a few routines to run faster ? Checkout the MODS Lua Assembly Toolkit.
Need to save space for your scripts ? Checkout LuaSrcDiet

Offline Levak

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1002
  • Rating: +208/-39
    • View Profile
    • My website
Re: [Lua] Tiny3D
« Reply #41 on: October 01, 2011, 03:05:30 pm »
Oh, and you need to localize the math library functions instead of getting them from the math table all the time.

Really.
This page helped me a lot : http://trac.caspring.org/wiki/LuaPerformance
« Last Edit: October 01, 2011, 03:05:35 pm by Levak »
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: [Lua] Tiny3D
« Reply #42 on: October 23, 2011, 08:29:16 pm »
This looks nice though. if it was speed up, I wonder if a Star Fox clone could be made on the Nspire? Maybe a clone of Space Dementia 68K too :D

Offline flyingfisch

  • I'm 1337 now!
  • Members
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1620
  • Rating: +94/-17
  • Testing, testing, 1...2...3...4...5...6...7...8..9
    • View Profile
    • Top Page Website Design
Re: [Lua] Tiny3D
« Reply #43 on: October 23, 2011, 08:52:02 pm »
is it ok if i try to make a luaFX/AFX version of this?



Quote from: my dad
"welcome to the world of computers, where everything seems to be based on random number generators"



The Game V. 2.0

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: [Lua] Tiny3D
« Reply #44 on: October 23, 2011, 10:05:50 pm »
I bet there is no problem. Just ask Chokosta some permission if you plan to use the same code.

How fast is LuaFX?