Advertisement
neuronix

3DSoftEngine v0.5

Dec 12th, 2017
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.43 KB | None | 0 0
  1. --debug
  2. local debug = false
  3. --debug
  4.  
  5. local RGB = unpack
  6. local cos = math.cos
  7. local sin = math.sin
  8. local tan = math.tan
  9.  
  10. local tCos, tSin, tTan = {}, {}, {}
  11.  
  12. local torad = function(a)
  13.     return (a * math.pi / 180)
  14. end
  15.  
  16. local init = function()
  17.     for k = -180, 180 do
  18.         table.insert(tCos, cos(torad(k)))
  19.         table.insert(tSin, sin(torad(k)))
  20.         table.insert(tTan, tan(torad(k)))
  21.     end
  22. end
  23.  
  24. if (#tCos) == 0 then
  25.     init()
  26. end
  27.  
  28. local defaultColor = { 0, 0, 0 }
  29.  
  30. local screen = platform.window
  31.  
  32. function def(var)
  33.     return (var ~= nil)
  34. end
  35.  
  36. function undef(var)
  37.     return (var == nil)
  38. end
  39.  
  40. --moteur 2D
  41. --point 2D
  42.  
  43. Point2D = class()
  44.  
  45. function Point2D:init(x, y, color)
  46.     self.x = x
  47.     self.y = y
  48.     if def(color) then
  49.         self.color = color
  50.     else
  51.         self.color = defaultColor
  52.     end
  53.     self.inscreen = true
  54. end
  55.  
  56. function Point2D:changeColor(newcolor)
  57.     self.color = newcolor
  58. end
  59.  
  60. function Point2D:isInScreen()
  61.     self.inscreen = (self.x >= 0 and self.x <= screen:width() and self.y >= 0 and self.y <= screen:height())
  62.     return self.inscreen
  63. end
  64.  
  65. function Point2D:move(x, y)
  66.     self.x = self.x + x
  67.     self.y = self.y + y
  68. end
  69.  
  70. function Point2D:disp(gc)
  71.     if self:isInScreen() then
  72.         gc:setColorRGB(RGB(self.color))
  73.         if debug then
  74.             gc:drawString("Disp Point2D", 0, 0, "top")
  75.         end
  76.         gc:setPixel(self.x, self.y)
  77.     end
  78. end
  79.  
  80. --ligne 2D
  81.  
  82. Line2D = class()
  83.  
  84. --Line2D(Point2D,Point2D[,color]) or Line2D(Point1x,Point1y,Point2x,Point2y[,color,...])
  85.  
  86. function Line2D:init(point1orx, point2or1y, ...)
  87.     local args = { ... }
  88.     if def(args[2]) then
  89.         if def(args[3]) then
  90.             self.color = args[3]
  91.         else
  92.             self.color = defaultColor
  93.         end
  94.         self.point1 = Point2D(point1orx, point2or1y, self.color)
  95.         self.point2 = Point2D(args[1], args[2], self.color)
  96.     else
  97.         if def(args[1]) then
  98.             self.color = args[1]
  99.         else
  100.             self.color = defaultColor
  101.         end
  102.         self.point1 = point1orx
  103.         self.point2 = point2or1y
  104.         self.point1:changeColor(self.color)
  105.         self.point2:changeColor(self.color)
  106.     end
  107. end
  108.  
  109. function Line2D:changeColor(newcolor)
  110.     self.point1:changeColor(newcolor)
  111.     self.point2:changeColor(newcolor)
  112.     self.color = newcolor
  113. end
  114.  
  115. function Line2D:move(x, y)
  116.     self.point1:move(x, y)
  117.     self.point2:move(x, y)
  118. end
  119.  
  120. function Line2D:disp(gc)
  121.     if debug then
  122.         gc:drawString("disp Line2D", 0, 0, "top")
  123.     end
  124.     gc:setColorRGB(RGB(self.color))
  125.     gc:drawLine(self.point1.x, self.point1.y, self.point2.x, self.point2.y)
  126. end
  127.  
  128. --moteur 3D
  129. --point 3D
  130.  
  131. local fov = 70
  132.  
  133. Point3D = class()
  134.  
  135. function Point3D:init(x, y, z, --[[w,]] color)
  136.     self.x = x
  137.     self.y = y
  138.     self.z = z
  139.     --self.w = w
  140.     if def(color) then
  141.         self.color = color
  142.     else
  143.         self.color = defaultColor
  144.     end
  145.     self.inscreen = true
  146.     self.proj2d = Point2D(0, 0, self.color)
  147. end
  148.  
  149. function Point3D:changeColor(newcolor)
  150.     self.color = newcolor
  151.     self.proj2d:changeColor()
  152. end
  153.  
  154. function Point3D:projection()
  155.     local f = (screen:width() / 2) / tTan[math.floor(fov / 2) + 181]
  156.     self.proj2d.x = math.floor(self.x * f / (self.z + 5) + (screen:width() / 2))
  157.     self.proj2d.y = math.floor((screen:height() / 2) - (self.y * f / (self.z + 5)))
  158.     return self.proj2d
  159. end
  160.  
  161. function Point3D:isInScreen()
  162.     self:projection()
  163.     self.inscreen = ((0 <= self.proj2d.x <= screen:width()) and (0 <= self.proj2d.y <= screen:height()))
  164.     return self.inscreen
  165. end
  166.  
  167. function Point3D:transform(matrix)
  168.     local newPoint3D = Point3D(0, 0, 0, self.color)
  169.     newPoint3D.x = matrix[1][1] * self.x + matrix[1][2] * self.y + matrix[1][3] * self.z
  170.     newPoint3D.y = matrix[2][1] * self.x + matrix[2][2] * self.y + matrix[2][3] * self.z
  171.     newPoint3D.z = matrix[3][1] * self.x + matrix[3][2] * self.y + matrix[3][3] * self.z
  172.     return newPoint3D
  173. end
  174.  
  175. function Point3D:move(x, y, z)
  176.     self.x = self.x + x
  177.     self.y = self.y + y
  178.     self.z = self.z + z
  179. end
  180.  
  181. function Point3D:rotate(xangle, yangle, zangle)
  182.     local newPoint
  183.  
  184.     local xangle, yangle, zangle = xangle + 181, yangle + 181, zangle + 181
  185.  
  186.     local xmatrix = {
  187.         { 1, 0, 0 },
  188.         { 0, tCos[xangle], -tSin[xangle] },
  189.         { 0, tSin[xangle], tCos[xangle] }
  190.     }
  191.     local ymatrix = {
  192.         { tCos[yangle], 0, tSin[yangle] },
  193.         { 0, 1, 0 },
  194.         { -tSin[yangle], 0, tCos[yangle] }
  195.     }
  196.     local zmatrix = {
  197.         { tCos[zangle], -tSin[zangle], 0 },
  198.         { tSin[zangle], tCos[zangle], 0 },
  199.         { 0, 0, 1 }
  200.     }
  201.  
  202.     newPoint = self:transform(xmatrix)
  203.     newPoint = newPoint:transform(ymatrix)
  204.     newPoint = newPoint:transform(zmatrix)
  205.     self.x = newPoint.x
  206.     self.y = newPoint.y
  207.     self.z = newPoint.z
  208. end
  209.  
  210. function Point3D:disp(gc)
  211.     if self:isInScreen() then
  212.         if debug then
  213.             gc:drawString("disp Point3D", 0, 0, "top")
  214.         end
  215.         self.proj2d:disp(gc)
  216.     end
  217. end
  218.  
  219. --ligne 3D
  220.  
  221. Line3D = class()
  222.  
  223. function Line3D:init(point1orx, point2or1y, ...)
  224.     local args = { ... }
  225.     if def(args[4]) then
  226.         if def(args[5]) then
  227.             self.color = args[5]
  228.         else
  229.             self.color = defaultColor
  230.         end
  231.         self.point1 = Point3D(point1orx, point2or1y, args[1], self.color)
  232.         self.point2 = Point3D(args[2], args[3], args[4], self.color)
  233.     else
  234.         if def(args[1]) then
  235.             self.color = args[1]
  236.         else
  237.             self.color = defaultColor
  238.         end
  239.         self.point1 = point1orx
  240.         self.point2 = point2or1y
  241.         self.point1:changeColor(self.color)
  242.         self.point2:changeColor(self.color)
  243.     end
  244.     self.proj2d = Line2D(Point2D(0, 0), Point2D(0, 0), self.color)
  245. end
  246.  
  247. function Line3D:changeColor(newcolor)
  248.     self.point1:changeColor(newcolor)
  249.     self.point2:changeColor(newcolor)
  250.     self.proj2d:changeColor(newcolor)
  251.     self.color = newcolor
  252. end
  253.  
  254. function Line3D:projection()
  255.     self.point1:projection()
  256.     self.point2:projection()
  257.     self.proj2d = Line2D(self.point1.proj2d, self.point2.proj2d, self.color)
  258. end
  259.  
  260. function Line3D:rotate(xangle, yangle, zangle)
  261.     self.point1:rotate(xangle, yangle, zangle)
  262.     self.point2:rotate(xangle, yangle, zangle)
  263. end
  264.  
  265. function Line3D:move(x, y, z)
  266.     self.point1:move(x, y, z)
  267.     self.point2:move(x, y, z)
  268. end
  269.  
  270. function Line3D:disp(gc)
  271.     if debug then
  272.         gc:drawString("disp Line3D", 0, 0, "top")
  273.     end
  274.     self:projection()
  275.     self.proj2d:disp(gc)
  276. end
  277.  
  278. --objet
  279. --triangle 3D
  280.  
  281. Triangle = class()
  282.  
  283. function Triangle:init(point1, point2, point3, color, auto)
  284.     if def(color) then
  285.         self.color = color
  286.     else
  287.         self.color = defaultColor
  288.     end
  289.     self.point1 = point1
  290.     self.point2 = point2
  291.     self.point3 = point3
  292.     self.point1:changeColor(self.color)
  293.     self.point2:changeColor(self.color)
  294.     self.point3:changeColor(self.color)
  295.     self.proj2d1 = Point2D(0, 0, self.color)
  296.     self.proj2d2 = Point2D(0, 0, self.color)
  297.     self.proj2d3 = Point2D(0, 0, self.color)
  298.  
  299.     self.fill = false
  300.     self.tofillcolor = { 0, 0, 0 }
  301.     self.auto = auto
  302. end
  303.  
  304. function Triangle:changeFillColor(color)
  305.     self.tofillcolor = color
  306. end
  307.  
  308. function Triangle:enableFillTriangle(color)
  309.     self:changeFillColor(color)
  310.     self.fill = true
  311. end
  312.  
  313. function Triangle:disableFillTriangle()
  314.     self.fill = false
  315. end
  316.  
  317. function Triangle:changeColor(newcolor)
  318.     self.point1:changeColor(newcolor)
  319.     self.point2:changeColor(newcolor)
  320.     self.point3:changeColor(newcolor)
  321.     self.proj2d1:changeColor(newcolor)
  322.     self.proj2d2:changeColor(newcolor)
  323.     self.proj2d3:changeColor(newcolor)
  324.     self.color = newcolor
  325. end
  326.  
  327. function Triangle:projection()
  328.     self.point1:projection()
  329.     self.point2:projection()
  330.     self.point3:projection()
  331.     self.proj2d1 = self.point1.proj2d
  332.     self.proj2d2 = self.point2.proj2d
  333.     self.proj2d3 = self.point3.proj2d
  334. end
  335.  
  336. function Triangle:move(x, y, z)
  337.     self.point1:move(x, y, z)
  338.     self.point2:move(x, y, z)
  339.     self.point3:move(x, y, z)
  340. end
  341.  
  342. function Triangle:rotate(xangle, yangle, zangle)
  343.     self.point1:rotate(xangle, yangle, zangle)
  344.     self.point2:rotate(xangle, yangle, zangle)
  345.     self.point3:rotate(xangle, yangle, zangle)
  346. end
  347.  
  348. function Triangle:fillTriangle(gc)
  349.     local v1, v2, v3 = self.point1:projection(), self.point2:projection(), self.point3:projection()
  350.     gc:setColorRGB(RGB(self.tofillcolor))
  351.     gc:fillPolygon({v1.x,v1.y,v2.x,v2.y,v3.x,v3.y})
  352. end
  353.  
  354. function Triangle:disp(gc)
  355.     if debug then
  356.         gc:drawString("disp Triangle", 0, 0, "top")
  357.     end
  358.     local line1, line2, line3
  359.     line1 = Line3D(self.point1, self.point2, self.color)
  360.     line2 = Line3D(self.point2, self.point3, self.color)
  361.     line3 = Line3D(self.point1, self.point3, self.color)
  362.     line1:disp(gc)
  363.     line2:disp(gc)
  364.     line3:disp(gc)
  365.     if self.auto or self.fill then
  366.         self:fillTriangle(gc)
  367.     end
  368. end
  369.  
  370. --camera
  371.  
  372. Camera = class()
  373.  
  374. function Camera:init()
  375.     self.position = Point3D(0, 0, 0)
  376.     self.target = Point3D(0, 0, 0)
  377. end
  378.  
  379. --objet 3D
  380.  
  381. Object3D = class()
  382.  
  383. function Object3D:init(name, listObject, color)
  384.     self.name = name
  385.     self.listObject = listObject
  386.     self.color = color
  387.     self.position = Point3D(0, 0, 0)
  388.     self.rotation = Point3D(0, 0, 0)
  389. end
  390.  
  391. function Object3D:rotate(xangle, yangle, zangle)
  392.     for k = 1, #self.listObject do
  393.         local obj = self.listObject[k]
  394.         obj:rotate(xangle, yangle, zangle)
  395.     end
  396. end
  397.  
  398. function Object3D:move(xmove, ymove, zmove)
  399.     for k = 1, #self.listObject do
  400.         local obj = self.listObject[k]
  401.         if undef(obj.axex) then
  402.             obj:move(xmove, ymove, zmove)
  403.         end
  404.     end
  405. end
  406.  
  407. function Object3D:disp(gc)
  408.     for k = 1, #self.listObject do
  409.         local obj = self.listObject[k]
  410.         if def(obj.name) then
  411.             gc:drawString(obj.name, screen:height(), 0, "bottom")
  412.         end
  413.         obj:disp(gc)
  414.     end
  415. end
  416.  
  417. --axes
  418.  
  419. Axes = class()
  420.  
  421. function Axes:init(posx, posy, posz)
  422.     print("Axes init")
  423.     self.axex = Line3D(Point3D(0, 0, 0), posx, posx.color)
  424.     self.axey = Line3D(Point3D(0, 0, 0), posy, posy.color)
  425.     self.axez = Line3D(Point3D(0, 0, 0), posz, posz.color)
  426. end
  427.  
  428. function Axes:rotate(xangle, yangle, zangle)
  429.     print("Axes rotate")
  430.     self.axex:rotate(xangle, yangle, zangle)
  431.     self.axey:rotate(xangle, yangle, zangle)
  432.     self.axez:rotate(xangle, yangle, zangle)
  433. end
  434.  
  435. function Axes:disp(gc)
  436.     print("Axes disp")
  437.     self.axex:disp(gc)
  438.     self.axey:disp(gc)
  439.     self.axez:disp(gc)
  440.     local pointx, pointy, pointz = self.axex.point2, self.axey.point2, self.axez.point2
  441.     pointx:projection()
  442.     pointy:projection()
  443.     pointz:projection()
  444.     gc:setColorRGB(RGB(self.axex.color))
  445.     gc:drawString("x", pointx.proj2d.x, pointx.proj2d.y)
  446.     gc:setColorRGB(RGB(self.axey.color))
  447.     gc:drawString("y", pointy.proj2d.x, pointy.proj2d.y)
  448.     gc:setColorRGB(RGB(self.axez.color))
  449.     gc:drawString("z", pointz.proj2d.x, pointz.proj2d.y)
  450. end
  451.  
  452. --main
  453. --devant
  454. local face1 = Object3D("face1", { Triangle(Point3D(-1, -1, -1), Point3D(-1, 1, -1), Point3D(1, -1, -1)), Triangle(Point3D(-1, 1, -1), Point3D(1, 1, -1), Point3D(1, -1, -1)) }, { 0, 0, 0 })
  455. face1.listObject[1]:enableFillTriangle({ 255, 0, 0 })
  456. face1.listObject[2]:enableFillTriangle({ 255, 0, 0 })
  457. print("devant")
  458. --gauche
  459. local face2 = Object3D("face2", { Triangle(Point3D(-1, -1, 1), Point3D(-1, 1, 1), Point3D(-1, -1, -1)), Triangle(Point3D(-1, -1, -1), Point3D(-1, 1, -1), Point3D(-1, 1, 1)) }, { 0, 0, 0 })
  460. print("gauche")
  461. face2.listObject[1]:enableFillTriangle({ 255, 0, 255 })
  462. face2.listObject[2]:enableFillTriangle({ 255, 0, 255 })
  463. --derriere
  464. local face3 = Object3D("face3", { Triangle(Point3D(-1, -1, 1), Point3D(1, 1, 1), Point3D(1, -1, 1)), Triangle(Point3D(-1, -1, 1), Point3D(-1, 1, 1), Point3D(1, 1, 1)) }, { 0, 0, 0 })
  465. face3.listObject[1]:enableFillTriangle({ 0, 255, 0 })
  466. face3.listObject[2]:enableFillTriangle({ 0, 255, 0 })
  467. print("derriere")
  468. --droite
  469. local face4 = Object3D("face4", { Triangle(Point3D(1, -1, -1), Point3D(1, 1, -1), Point3D(1, -1, 1)), Triangle(Point3D(1, -1, 1), Point3D(1, 1, -1), Point3D(1, 1, 1)) }, { 0, 0, 0 })
  470. print("droite")
  471. face4.listObject[1]:enableFillTriangle({ 0, 255, 255 })
  472. face4.listObject[2]:enableFillTriangle({ 0, 255, 255 })
  473. --haut
  474. local face5 = Object3D("face5", { Triangle(Point3D(-1, 1, -1), Point3D(-1, 1, 1), Point3D(1, 1, -1)), Triangle(Point3D(-1, 1, 1), Point3D(1, 1, 1), Point3D(1, 1, -1)) }, { 0, 0, 0 })
  475. print("haut")
  476. face5.listObject[1]:enableFillTriangle({ 0, 0, 255 })
  477. face5.listObject[2]:enableFillTriangle({ 0, 0, 255 })
  478. --bas
  479. local face6 = Object3D("face6", { Triangle(Point3D(-1, -1, 1), Point3D(-1, -1, -1), Point3D(1, -1, 1)), Triangle(Point3D(-1, -1, -1), Point3D(1, -1, -1), Point3D(1, -1, 1)) }, { 0, 0, 0 })
  480. face6.listObject[1]:enableFillTriangle({ 255, 255, 0 })
  481. face6.listObject[2]:enableFillTriangle({ 255, 255, 0 })
  482. print("bas")
  483.  
  484. --axes
  485. local axes = Axes(Point3D(0.5, 0, 0, { 255, 0, 0 }), Point3D(0, 0.5, 0, { 0, 0, 255 }), Point3D(0, 0, 0.5, { 0, 255, 0 }))
  486.  
  487. --cube
  488. local cube = Object3D("cube", { face1, face2, face3, face4, face5, face6, axes })
  489.  
  490. local incx = -5
  491. local incy = -5
  492.  
  493. function on.paint(gc)
  494.     if debug then
  495.         gc:drawString("test", 0, 0, "top")
  496.     end
  497.     gc:drawString(string.format(--[[X = %d Y= %d Z= %d          ]]"fov = %d°", --[[face1t1.point1.x, face1t1.point1.y, face1t1.point1.z,]] fov), 0, 0, "top")
  498.  
  499.     cube:disp(gc)
  500. end
  501.  
  502. function on.charIn(ch)
  503.     if ch == '+' and fov > 0 then
  504.         fov = fov - 5
  505.     elseif ch == '-' and fov < 180 then
  506.         fov = fov + 5
  507.     elseif ch == '8' then
  508.         incx = -5
  509.     elseif ch == '2' then
  510.         incx = 5
  511.     elseif ch == '6' then
  512.         incy = -5
  513.     elseif ch == '4' then
  514.         incy = 5
  515.     elseif ch == 'p' then
  516.         timer.stop()
  517.     elseif ch == 's' then
  518.         timer.start(0.01)
  519.     end
  520.     screen:invalidate()
  521. end
  522.  
  523. function on.timer()
  524.     cube:rotate(incx, incy, 0)
  525.  
  526.     screen:invalidate()
  527. end
  528.  
  529. function on.arrowLeft()
  530.     cube:move(-1, 0, 0)
  531.  
  532.     screen:invalidate()
  533. end
  534.  
  535. function on.arrowRight()
  536.     cube:move(1, 0, 0)
  537.  
  538.     screen:invalidate()
  539. end
  540.  
  541. function on.arrowUp()
  542.     cube:move(0, 1, 0)
  543.  
  544.     screen:invalidate()
  545. end
  546.  
  547. function on.arrowDown()
  548.     cube:move(0, -1, 0)
  549.  
  550.     screen:invalidate()
  551. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement