Advertisement
oli414

[TI nspire CX] 3D engine

Mar 31st, 2015
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.60 KB | None | 0 0
  1. local screen = platform.window
  2. Polygon = class()
  3. Rectangle = class()
  4. Cube = class()
  5. DVector = class()
  6. cameraPoint = {40,40,10}
  7. cameraViewPoint = {0,1,10}
  8. degreesx = 500
  9. radius = 140
  10. --0 = Nothing
  11. --1 = W
  12. --2 = S
  13. --3 = Left
  14. --4 = Right
  15. --5 = Up
  16. --6 = Down
  17.  
  18. --0 = Nothing
  19. --1 = x
  20. --2 = y
  21. --3 = z
  22. --4 = -x
  23. --5 = -y
  24. --6 = -z
  25.  
  26. currentInput = 1
  27. inputI = {4,4,6,5,0,0,3,3}
  28. inputI2 = {3,0,5,1,0,5,1,3}
  29. inputI3 = {4,4,4,3,3,2,0,0}
  30. inputI4 = {6,0,5,0,3,3,6,6}
  31. inputR = {41,32,44,20,80,40,40,40}
  32. inputI = {0}
  33. inputI2 = {0}
  34. inputI3 = {0}
  35. inputI4 = {0}
  36. inputR = {1}
  37.  
  38. screenWidth = 318
  39. screenHeight = 212
  40.  
  41. varGlobal = 0
  42.  
  43. polygons = {}
  44. polyCount = 1
  45.  
  46. function DVector:init(x, y, z)
  47.     local length = math.sqrt(x*x + y*y + z*z)
  48.     self.x = 0
  49.     self.y = 0
  50.     self.z = 0
  51.     if length>0 then
  52.         self.x = x / length
  53.         self.= y / length
  54.         self.= z / length
  55.     end
  56. end
  57.  
  58. function DVector:cross(v)
  59.     local retvec = DVector(self.y * v.z - self.z * v.y, self.z * v.x - self.x * v.z, self.x * v.y - self.y * v.x)
  60.     return retvec
  61. end
  62.  
  63. function ReCalculation()
  64.     ViewVector = DVector(cameraViewPoint[1] - cameraPoint[1], cameraViewPoint[2] - cameraPoint[2], cameraViewPoint[3] - cameraPoint[3])
  65.     local DirectionVector = DVector(1,1,1)
  66.     local PlaneVector1 = ViewVector:cross(DirectionVector)
  67.     local PlaneVector2 = ViewVector:cross(PlaneVector1)
  68.    
  69.     local tx = math.abs(cameraPoint[1]-cameraViewPoint[1])
  70.     local ty = math.abs(cameraPoint[2]-cameraViewPoint[2])
  71.     local xrot = ty/(tx+ty)
  72.     local yrot = tx/(ty+tx)
  73.     if cameraPoint[2]>cameraViewPoint[2] then
  74.         xrot = xrot * -1
  75.     end
  76.     if cameraPoint[1]<cameraViewPoint[1] then
  77.         yrot = yrot * -1
  78.     end
  79.     local RotationVector = DVector(xrot,yrot,0)
  80.     WVector1 = ViewVector:cross(RotationVector)
  81.     WVector2 = ViewVector:cross(WVector1)
  82. end
  83.  
  84. function CalculatePosition(x, y, z)
  85.     local ViewToPoint = DVector(x - cameraPoint[1], y - cameraPoint[2], z - cameraPoint[3])
  86.     t = (ViewVector.x*cameraViewPoint[1] + ViewVector.y*cameraViewPoint[2] + ViewVector.z*cameraViewPoint[3] - (ViewVector.x*cameraPoint[1] + ViewVector.y*cameraPoint[2] + ViewVector.z*cameraPoint[3])) / (ViewVector.x*ViewToPoint.x + ViewVector.y*ViewToPoint.y + ViewVector.z*ViewToPoint.z)
  87.     x = cameraPoint[1] + ViewToPoint.x * t
  88.     y = cameraPoint[2] + ViewToPoint.y * t
  89.     z = cameraPoint[3] + ViewToPoint.z * t
  90.     local retx
  91.     local rety
  92.     if t >= 0 then
  93.         retx = WVector2.x * x + WVector2.y * y + WVector2.z * z
  94.         rety = WVector1.x * x + WVector1.y * y + WVector1.z * z
  95.     end
  96.     return retx, rety
  97. end
  98.  
  99. function Polygon:init(x1, y1, z1, x2, y2, z2, x3, y3, z3, c)
  100.     polyCount = polyCount + 1
  101.     self.c = c
  102.     self.x1 = x1
  103.     self.y1 = y1
  104.     self.z1 = z1
  105.     self.x2 = x2
  106.     self.y2 = y2
  107.     self.z2 = z2
  108.     self.x3 = x3
  109.     self.y3 = y3
  110.     self.z3 = z3
  111. end
  112.  
  113. function Polygon:draw(gc)
  114.     local viewLimit = 800
  115.     local zoom = 2
  116.     local vx, vy = CalculatePosition(cameraViewPoint[1],cameraViewPoint[2],cameraViewPoint[3])
  117.     vx = vx * -zoom
  118.     vy = vy * -zoom
  119.     local dx1, dy1 = CalculatePosition(self.x1,self.y1,self.z1)
  120.     local dx2, dy2 = CalculatePosition(self.x2,self.y2,self.z2)
  121.     local dx3, dy3 = CalculatePosition(self.x3,self.y3,self.z3)
  122.     gc:setColorRGB(self.c[1], self.c[2], self.c[3])
  123.     if dx3 ~= nil and dx2 ~= nil and dx1 ~= nil and dy3 ~= nil and dy2 ~= nil and dy1 ~= nil then
  124.         dx1 = vx + (dx1 * 2) + (screenWidth/2)
  125.         dy1 = vy + (dy1 * zoom) + (screenHeight/2)
  126.         dx2 = vx + (dx2 * zoom) + (screenWidth/2)
  127.         dy2 = vy + (dy2 * zoom) + (screenHeight/2)
  128.         dx3 = vx + (dx3 * zoom) + (screenWidth/2)
  129.         dy3 = vy + (dy3 * zoom) + (screenHeight/2)
  130.         changed = 0
  131.         if dx1 > -viewLimit and dx1 < screenWidth+viewLimit and dx2 > -viewLimit and dx2 < screenWidth+viewLimit and dx3 > -viewLimit and dx3 < screenWidth+viewLimit then
  132.                 if dy1 > -viewLimit and dy1 < screenHeight+viewLimit and dy2 > -viewLimit and dy2 < screenHeight+viewLimit and dy3 > -viewLimit and dy3 < screenHeight+viewLimit then
  133.                     gc:fillPolygon({dx1, dy1, dx2, dy2, dx3, dy3})
  134.                 end
  135.         end
  136.     end
  137. end
  138.  
  139. function Polygon:getDistance()
  140.     local sdistance = 0
  141.     local tx = cameraPoint[1] - self.x1
  142.     local ty = cameraPoint[2] - self.y1
  143.     local tz = cameraPoint[3] - self.z1
  144.     local sdistance1 =  math.sqrt(tx * tx + ty * ty + tz * tz)
  145.     tx = cameraPoint[1] - self.x2
  146.     ty = cameraPoint[2] - self.y2
  147.     tz = cameraPoint[3] - self.z2
  148.     local sdistance2 =  math.sqrt(tx * tx + ty * ty + tz * tz)
  149.     tx = cameraPoint[1] - self.x3
  150.     ty = cameraPoint[2] - self.y3
  151.     tz = cameraPoint[3] - self.z3
  152.     local sdistance3 =  math.sqrt(tx * tx + ty * ty + tz * tz)
  153.     sdistance = (sdistance1 + sdistance2 + sdistance3) / 3
  154.     return sdistance
  155. end
  156.  
  157. function Plane(x1,y1,z1,x2,y2, c)
  158.     polygons[polyCount] = Polygon(x1,y1,z1,x1 + x2,y1,z1,x1 + x2,y1 + y2,z1, c)
  159.     polygons[polyCount] = Polygon(x1,y1,z1,x1,y1 + y2,z1,x1 + x2,y1 + y2,z1, c)
  160. end
  161.    
  162. function getPointOnCircle(r,a,x,y)
  163.     x = x + r * math.cos(a)
  164.     y = y + r * math.sin(a)
  165.     return x,y
  166. end
  167.  
  168. function Floor(x1,y1,x2,y2,z, c)
  169.     for i = x1, x2, 20 do
  170.         for j = y1, y2, 20 do
  171.             Plane(i,j,z,20,20, c)
  172.         end
  173.     end
  174. end
  175.  
  176. function DrawSky(gc, c)
  177.     dx, dy =  getPointOnCircle(1000,degreesx,cameraPoint[1],cameraPoint[2])
  178.     tx, ty = CalculatePosition(dx,dy,cameraPoint[3])
  179.     gc:setColorRGB(c[1],c[2], c[3])
  180.     if dy ~= nil then
  181.         gc:fillRect(0,(ty * 2) - (screenHeight / 2) + 20,screenWidth,screenHeight)
  182.     end
  183. end
  184. function DrawFloor(gc, c)
  185.     gc:setColorRGB(c[1],c[2], c[3])
  186.     gc:fillRect(0,0,screenWidth,screenHeight)
  187. end
  188.  
  189. function Cube:init(x1, y1, z1, x2, y2, z2, c)
  190.     x2 = x1 + x2
  191.     y2 = y1 + y2
  192.     z2 = z1 + z2
  193.     c1 = {c[1], c[2], c[3]}
  194.     c2 = {c[1] - 40, c[2] - 40, c[3] - 40}
  195.     c3 = {c[1] - 20, c[2] - 20, c[3] - 20}
  196.     for i = 1, 3, 1 do if c1[i]<0 then c1[i]=0 end end
  197.     for i = 1, 3, 1 do if c2[i]<0 then c2[i]=0 end end
  198.     for i = 1, 3, 1 do if c3[i]<0 then c3[i]=0 end end
  199.     polygons[polyCount] = Polygon(x1,y1,z1,x2,y2,z1,x1,y2,z1, c1)
  200.     polygons[polyCount] = Polygon(x1,y1,z1,x2,y2,z1,x2,y1,z1, c1)
  201.     polygons[polyCount] = Polygon(x1,y1,z1,x1,y2,z2,x1,y2,z1, c2)
  202.     polygons[polyCount] = Polygon(x1,y1,z1,x1,y2,z2,x1,y1,z2, c2)
  203.     polygons[polyCount] = Polygon(x2,y2,z2,x1,y1,z2,x2,y1,z2, c1)
  204.     polygons[polyCount] = Polygon(x2,y2,z2,x1,y1,z2,x1,y2,z2, c1)
  205.     polygons[polyCount] = Polygon(x2,y2,z2,x2,y1,z1,x2,y1,z2, c2)
  206.     polygons[polyCount] = Polygon(x2,y2,z2,x2,y1,z1,x2,y2,z1, c2)  
  207.     polygons[polyCount] = Polygon(x1,y1,z1,x2,y1,z1,x2,y1,z2, c3)
  208.     polygons[polyCount] = Polygon(x1,y1,z1,x1,y1,z2,x2,y1,z2, c3)
  209.     polygons[polyCount] = Polygon(x1,y2,z1,x2,y2,z1,x2,y2,z2, c3)
  210.     polygons[polyCount] = Polygon(x1,y2,z1,x1,y2,z2,x2,y2,z2, c3)
  211. end
  212.  
  213. cube = Cube(0,0,0,20,20,20,{0,0,128})
  214. cube = Cube(0,20,0,20,20,20,{0,0,100})
  215. cube = Cube(0,40,0,20,20,20,{0,0,128})
  216. cube = Cube(20,-20,0,20,20,20,{0,0,128})
  217. --cube = Cube(40,-20,0,20,20,20,{0,0,100})
  218. Cube(40,-20,0,20,2,20,{95,60,0})
  219.  
  220. cube = Cube(60,-20,0,20,20,20,{0,0,128})
  221. cube = Cube(80,0,0,20,20,20,{0,0,128})
  222. cube = Cube(80,20,0,20,20,20,{0,0,100})
  223. cube = Cube(80,40,0,20,20,20,{0,0,128})
  224. cube = Cube(60,60,0,20,20,20,{0,0,128})
  225. cube = Cube(40,60,0,20,20,20,{0,0,100})
  226. cube = Cube(20,60,0,20,20,20,{0,0,128})
  227.  
  228. function on.paint(gc)
  229.     cameraViewPoint[1], cameraViewPoint[2] = getPointOnCircle(radius,degreesx,cameraPoint[1],cameraPoint[2])
  230.     ReCalculation()
  231.     DrawFloor(gc,{128,128,128})
  232.     DrawSky(gc, {64,64,64})
  233.     highest = polygons[1]:getDistance()
  234.     highesti = 1
  235.     order = {}
  236.     done = {}
  237.     distances = {}
  238.     for i = 1, polyCount - 1, 1 do
  239.         distances[i] = polygons[i]:getDistance()
  240.         if polygons[i]:getDistance() < highest then
  241.             highest = polygons[i]:getDistance()
  242.         end
  243.     end
  244.     lowest = highest
  245.     for i = 1, polyCount - 1, 1 do
  246.         done[i] = 0
  247.     end
  248.     for k = 1, polyCount - 1, 1 do
  249.         for i = 1, polyCount - 1, 1 do
  250.             if polygons[i]:getDistance() >= highest then
  251.                 if done[i]==0 then
  252.                     highest = polygons[i]:getDistance()
  253.                     highesti = i
  254.                 end
  255.             end
  256.         end
  257.         done[highesti] = 1
  258.         order[k] = highesti
  259.         highest = lowest
  260.     end
  261.     for i = 1, polyCount - 1, 1 do
  262.         polygons[order[i]]:draw(gc)
  263.     end
  264. end
  265.  
  266. function on.charIn(char)
  267.     if char == "w" then
  268.         x1,y1 = getPointOnCircle(1,degreesx,cameraPoint[1],cameraPoint[2])
  269.         cameraPoint[1] = x1
  270.         cameraPoint[2] = y1
  271.     end
  272.     if char == "s" then
  273.         x1,y1 = getPointOnCircle(1,degreesx,cameraPoint[1],cameraPoint[2])
  274.         cameraViewPoint[1] = cameraViewPoint[1] + cameraPoint[1] - x1
  275.         cameraViewPoint[2] = cameraViewPoint[2] + cameraPoint[2] - y1
  276.         cameraPoint[1] = cameraPoint[1] + cameraPoint[1] - x1
  277.         cameraPoint[2] = cameraPoint[2] + cameraPoint[2] - y1
  278.     end
  279. end
  280.  
  281. function on.arrowDown()
  282.     cameraViewPoint[3] = cameraViewPoint[3] - 2
  283. end
  284. function on.arrowUp()
  285.     cameraViewPoint[3] = cameraViewPoint[3] + 2
  286. end
  287. function on.arrowLeft()
  288.     degreesx = degreesx - .06
  289.     end
  290. function on.arrowRight()
  291.     degreesx = degreesx + .06
  292. end
  293.  
  294. function goToRelative(x,y,z)
  295.     cameraViewPoint[1] = cameraViewPoint[1] + x
  296.     cameraViewPoint[2] = cameraViewPoint[2] + y
  297.     cameraViewPoint[3] = cameraViewPoint[3] + z
  298.     cameraPoint[1] = cameraPoint[1] + x
  299.     cameraPoint[2] = cameraPoint[2] + y
  300.     cameraPoint[3] = cameraPoint[3] + z
  301. end
  302.  
  303. timer.start(1)
  304.  
  305. function on.timer()
  306.         if inputI[currentInput]==1 then
  307.             goToRelative(1,0,0)
  308.         elseif inputI[currentInput]==2 then
  309.             goToRelative(0,1,0)
  310.         elseif inputI[currentInput]==3 then
  311.             goToRelative(0,0,1)
  312.         elseif inputI[currentInput]==4 then
  313.             goToRelative(-1,0,0)
  314.         elseif inputI[currentInput]==5 then
  315.             goToRelative(0,-1,0)
  316.         elseif inputI[currentInput]==6 then
  317.             goToRelative(0,0,-1)
  318.         end
  319.         if inputI2[currentInput]==1 then
  320.             goToRelative(1,0,0)
  321.         elseif inputI2[currentInput]==2 then
  322.             goToRelative(0,1,0)
  323.         elseif inputI2[currentInput]==3 then
  324.             goToRelative(0,0,1)
  325.         elseif inputI2[currentInput]==4 then
  326.             goToRelative(-1,0,0)
  327.         elseif inputI2[currentInput]==5 then
  328.             goToRelative(0,-1,0)
  329.         elseif inputI2[currentInput]==6 then
  330.             goToRelative(0,0,-1)
  331.         end
  332.         if inputI3[currentInput]==1 then
  333.             on.charIn("w")
  334.         elseif inputI3[currentInput]==2 then
  335.             on.charIn("s")
  336.         elseif inputI3[currentInput]==3 then
  337.             on.arrowLeft()
  338.         elseif inputI3[currentInput]==4 then
  339.             on.arrowRight()
  340.         elseif inputI3[currentInput]==5 then
  341.             on.arrowUp()
  342.         elseif inputI3[currentInput]==6 then
  343.             on.arrowDown()
  344.         end
  345.         if inputI4[currentInput]==1 then
  346.             on.charIn("w")
  347.         elseif inputI4[currentInput]==2 then
  348.             on.charIn("s")
  349.         elseif inputI4[currentInput]==3 then
  350.             on.arrowLeft()
  351.         elseif inputI4[currentInput]==4 then
  352.             on.arrowRight()
  353.         elseif inputI4[currentInput]==5 then
  354.             on.arrowUp()
  355.         elseif inputI4[currentInput]==6 then
  356.             on.arrowDown()
  357.         end
  358.         screen:invalidate()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement