Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --debug
- local debug = false
- --debug
- local RGB = unpack
- local cos = math.cos
- local sin = math.sin
- local tan = math.tan
- local tCos, tSin, tTan = {}, {}, {}
- local torad = function(a)
- return (a * math.pi / 180)
- end
- local init = function()
- for k = -180, 180 do
- table.insert(tCos, cos(torad(k)))
- table.insert(tSin, sin(torad(k)))
- table.insert(tTan, tan(torad(k)))
- end
- end
- if (#tCos) == 0 then
- init()
- end
- local defaultColor = { 0, 0, 0 }
- local screen = platform.window
- function def(var)
- return (var ~= nil)
- end
- function undef(var)
- return (var == nil)
- end
- --moteur 2D
- --point 2D
- Point2D = class()
- function Point2D:init(x, y, color)
- self.x = x
- self.y = y
- if def(color) then
- self.color = color
- else
- self.color = defaultColor
- end
- self.inscreen = true
- end
- function Point2D:changeColor(newcolor)
- self.color = newcolor
- end
- function Point2D:isInScreen()
- self.inscreen = (self.x >= 0 and self.x <= screen:width() and self.y >= 0 and self.y <= screen:height())
- return self.inscreen
- end
- function Point2D:move(x, y)
- self.x = self.x + x
- self.y = self.y + y
- end
- function Point2D:disp(gc)
- if self:isInScreen() then
- gc:setColorRGB(RGB(self.color))
- if debug then
- gc:drawString("Disp Point2D", 0, 0, "top")
- end
- gc:setPixel(self.x, self.y)
- end
- end
- --ligne 2D
- Line2D = class()
- --Line2D(Point2D,Point2D[,color]) or Line2D(Point1x,Point1y,Point2x,Point2y[,color,...])
- function Line2D:init(point1orx, point2or1y, ...)
- local args = { ... }
- if def(args[2]) then
- if def(args[3]) then
- self.color = args[3]
- else
- self.color = defaultColor
- end
- self.point1 = Point2D(point1orx, point2or1y, self.color)
- self.point2 = Point2D(args[1], args[2], self.color)
- else
- if def(args[1]) then
- self.color = args[1]
- else
- self.color = defaultColor
- end
- self.point1 = point1orx
- self.point2 = point2or1y
- self.point1:changeColor(self.color)
- self.point2:changeColor(self.color)
- end
- end
- function Line2D:changeColor(newcolor)
- self.point1:changeColor(newcolor)
- self.point2:changeColor(newcolor)
- self.color = newcolor
- end
- function Line2D:move(x, y)
- self.point1:move(x, y)
- self.point2:move(x, y)
- end
- function Line2D:disp(gc)
- if debug then
- gc:drawString("disp Line2D", 0, 0, "top")
- end
- gc:setColorRGB(RGB(self.color))
- gc:drawLine(self.point1.x, self.point1.y, self.point2.x, self.point2.y)
- end
- --moteur 3D
- --point 3D
- local fov = 70
- Point3D = class()
- function Point3D:init(x, y, z, --[[w,]] color)
- self.x = x
- self.y = y
- self.z = z
- --self.w = w
- if def(color) then
- self.color = color
- else
- self.color = defaultColor
- end
- self.inscreen = true
- self.proj2d = Point2D(0, 0, self.color)
- end
- function Point3D:changeColor(newcolor)
- self.color = newcolor
- self.proj2d:changeColor()
- end
- function Point3D:projection()
- local f = (screen:width() / 2) / tTan[math.floor(fov / 2) + 181]
- self.proj2d.x = math.floor(self.x * f / (self.z + 5) + (screen:width() / 2))
- self.proj2d.y = math.floor((screen:height() / 2) - (self.y * f / (self.z + 5)))
- return self.proj2d
- end
- function Point3D:isInScreen()
- self:projection()
- self.inscreen = ((0 <= self.proj2d.x <= screen:width()) and (0 <= self.proj2d.y <= screen:height()))
- return self.inscreen
- end
- function Point3D:transform(matrix)
- local newPoint3D = Point3D(0, 0, 0, self.color)
- newPoint3D.x = matrix[1][1] * self.x + matrix[1][2] * self.y + matrix[1][3] * self.z
- newPoint3D.y = matrix[2][1] * self.x + matrix[2][2] * self.y + matrix[2][3] * self.z
- newPoint3D.z = matrix[3][1] * self.x + matrix[3][2] * self.y + matrix[3][3] * self.z
- return newPoint3D
- end
- function Point3D:move(x, y, z)
- self.x = self.x + x
- self.y = self.y + y
- self.z = self.z + z
- end
- function Point3D:rotate(xangle, yangle, zangle)
- local newPoint
- local xangle, yangle, zangle = xangle + 181, yangle + 181, zangle + 181
- local xmatrix = {
- { 1, 0, 0 },
- { 0, tCos[xangle], -tSin[xangle] },
- { 0, tSin[xangle], tCos[xangle] }
- }
- local ymatrix = {
- { tCos[yangle], 0, tSin[yangle] },
- { 0, 1, 0 },
- { -tSin[yangle], 0, tCos[yangle] }
- }
- local zmatrix = {
- { tCos[zangle], -tSin[zangle], 0 },
- { tSin[zangle], tCos[zangle], 0 },
- { 0, 0, 1 }
- }
- newPoint = self:transform(xmatrix)
- newPoint = newPoint:transform(ymatrix)
- newPoint = newPoint:transform(zmatrix)
- self.x = newPoint.x
- self.y = newPoint.y
- self.z = newPoint.z
- end
- function Point3D:disp(gc)
- if self:isInScreen() then
- if debug then
- gc:drawString("disp Point3D", 0, 0, "top")
- end
- self.proj2d:disp(gc)
- end
- end
- --ligne 3D
- Line3D = class()
- function Line3D:init(point1orx, point2or1y, ...)
- local args = { ... }
- if def(args[4]) then
- if def(args[5]) then
- self.color = args[5]
- else
- self.color = defaultColor
- end
- self.point1 = Point3D(point1orx, point2or1y, args[1], self.color)
- self.point2 = Point3D(args[2], args[3], args[4], self.color)
- else
- if def(args[1]) then
- self.color = args[1]
- else
- self.color = defaultColor
- end
- self.point1 = point1orx
- self.point2 = point2or1y
- self.point1:changeColor(self.color)
- self.point2:changeColor(self.color)
- end
- self.proj2d = Line2D(Point2D(0, 0), Point2D(0, 0), self.color)
- end
- function Line3D:changeColor(newcolor)
- self.point1:changeColor(newcolor)
- self.point2:changeColor(newcolor)
- self.proj2d:changeColor(newcolor)
- self.color = newcolor
- end
- function Line3D:projection()
- self.point1:projection()
- self.point2:projection()
- self.proj2d = Line2D(self.point1.proj2d, self.point2.proj2d, self.color)
- end
- function Line3D:rotate(xangle, yangle, zangle)
- self.point1:rotate(xangle, yangle, zangle)
- self.point2:rotate(xangle, yangle, zangle)
- end
- function Line3D:move(x, y, z)
- self.point1:move(x, y, z)
- self.point2:move(x, y, z)
- end
- function Line3D:disp(gc)
- if debug then
- gc:drawString("disp Line3D", 0, 0, "top")
- end
- self:projection()
- self.proj2d:disp(gc)
- end
- --objet
- --triangle 3D
- Triangle = class()
- function Triangle:init(point1, point2, point3, color, auto)
- if def(color) then
- self.color = color
- else
- self.color = defaultColor
- end
- self.point1 = point1
- self.point2 = point2
- self.point3 = point3
- self.point1:changeColor(self.color)
- self.point2:changeColor(self.color)
- self.point3:changeColor(self.color)
- self.proj2d1 = Point2D(0, 0, self.color)
- self.proj2d2 = Point2D(0, 0, self.color)
- self.proj2d3 = Point2D(0, 0, self.color)
- self.fill = false
- self.tofillcolor = { 0, 0, 0 }
- self.auto = auto
- end
- function Triangle:changeFillColor(color)
- self.tofillcolor = color
- end
- function Triangle:enableFillTriangle(color)
- self:changeFillColor(color)
- self.fill = true
- end
- function Triangle:disableFillTriangle()
- self.fill = false
- end
- function Triangle:changeColor(newcolor)
- self.point1:changeColor(newcolor)
- self.point2:changeColor(newcolor)
- self.point3:changeColor(newcolor)
- self.proj2d1:changeColor(newcolor)
- self.proj2d2:changeColor(newcolor)
- self.proj2d3:changeColor(newcolor)
- self.color = newcolor
- end
- function Triangle:projection()
- self.point1:projection()
- self.point2:projection()
- self.point3:projection()
- self.proj2d1 = self.point1.proj2d
- self.proj2d2 = self.point2.proj2d
- self.proj2d3 = self.point3.proj2d
- end
- function Triangle:move(x, y, z)
- self.point1:move(x, y, z)
- self.point2:move(x, y, z)
- self.point3:move(x, y, z)
- end
- function Triangle:rotate(xangle, yangle, zangle)
- self.point1:rotate(xangle, yangle, zangle)
- self.point2:rotate(xangle, yangle, zangle)
- self.point3:rotate(xangle, yangle, zangle)
- end
- function Triangle:fillTriangle(gc)
- local v1, v2, v3 = self.point1:projection(), self.point2:projection(), self.point3:projection()
- gc:setColorRGB(RGB(self.tofillcolor))
- gc:fillPolygon({v1.x,v1.y,v2.x,v2.y,v3.x,v3.y})
- end
- function Triangle:disp(gc)
- if debug then
- gc:drawString("disp Triangle", 0, 0, "top")
- end
- local line1, line2, line3
- line1 = Line3D(self.point1, self.point2, self.color)
- line2 = Line3D(self.point2, self.point3, self.color)
- line3 = Line3D(self.point1, self.point3, self.color)
- line1:disp(gc)
- line2:disp(gc)
- line3:disp(gc)
- if self.auto or self.fill then
- self:fillTriangle(gc)
- end
- end
- --camera
- Camera = class()
- function Camera:init()
- self.position = Point3D(0, 0, 0)
- self.target = Point3D(0, 0, 0)
- end
- --objet 3D
- Object3D = class()
- function Object3D:init(name, listObject, color)
- self.name = name
- self.listObject = listObject
- self.color = color
- self.position = Point3D(0, 0, 0)
- self.rotation = Point3D(0, 0, 0)
- end
- function Object3D:rotate(xangle, yangle, zangle)
- for k = 1, #self.listObject do
- local obj = self.listObject[k]
- obj:rotate(xangle, yangle, zangle)
- end
- end
- function Object3D:move(xmove, ymove, zmove)
- for k = 1, #self.listObject do
- local obj = self.listObject[k]
- if undef(obj.axex) then
- obj:move(xmove, ymove, zmove)
- end
- end
- end
- function Object3D:disp(gc)
- for k = 1, #self.listObject do
- local obj = self.listObject[k]
- if def(obj.name) then
- gc:drawString(obj.name, screen:height(), 0, "bottom")
- end
- obj:disp(gc)
- end
- end
- --axes
- Axes = class()
- function Axes:init(posx, posy, posz)
- print("Axes init")
- self.axex = Line3D(Point3D(0, 0, 0), posx, posx.color)
- self.axey = Line3D(Point3D(0, 0, 0), posy, posy.color)
- self.axez = Line3D(Point3D(0, 0, 0), posz, posz.color)
- end
- function Axes:rotate(xangle, yangle, zangle)
- print("Axes rotate")
- self.axex:rotate(xangle, yangle, zangle)
- self.axey:rotate(xangle, yangle, zangle)
- self.axez:rotate(xangle, yangle, zangle)
- end
- function Axes:disp(gc)
- print("Axes disp")
- self.axex:disp(gc)
- self.axey:disp(gc)
- self.axez:disp(gc)
- local pointx, pointy, pointz = self.axex.point2, self.axey.point2, self.axez.point2
- pointx:projection()
- pointy:projection()
- pointz:projection()
- gc:setColorRGB(RGB(self.axex.color))
- gc:drawString("x", pointx.proj2d.x, pointx.proj2d.y)
- gc:setColorRGB(RGB(self.axey.color))
- gc:drawString("y", pointy.proj2d.x, pointy.proj2d.y)
- gc:setColorRGB(RGB(self.axez.color))
- gc:drawString("z", pointz.proj2d.x, pointz.proj2d.y)
- end
- --main
- --devant
- 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 })
- face1.listObject[1]:enableFillTriangle({ 255, 0, 0 })
- face1.listObject[2]:enableFillTriangle({ 255, 0, 0 })
- print("devant")
- --gauche
- 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 })
- print("gauche")
- face2.listObject[1]:enableFillTriangle({ 255, 0, 255 })
- face2.listObject[2]:enableFillTriangle({ 255, 0, 255 })
- --derriere
- 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 })
- face3.listObject[1]:enableFillTriangle({ 0, 255, 0 })
- face3.listObject[2]:enableFillTriangle({ 0, 255, 0 })
- print("derriere")
- --droite
- 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 })
- print("droite")
- face4.listObject[1]:enableFillTriangle({ 0, 255, 255 })
- face4.listObject[2]:enableFillTriangle({ 0, 255, 255 })
- --haut
- 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 })
- print("haut")
- face5.listObject[1]:enableFillTriangle({ 0, 0, 255 })
- face5.listObject[2]:enableFillTriangle({ 0, 0, 255 })
- --bas
- 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 })
- face6.listObject[1]:enableFillTriangle({ 255, 255, 0 })
- face6.listObject[2]:enableFillTriangle({ 255, 255, 0 })
- print("bas")
- --axes
- 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 }))
- --cube
- local cube = Object3D("cube", { face1, face2, face3, face4, face5, face6, axes })
- local incx = -5
- local incy = -5
- function on.paint(gc)
- if debug then
- gc:drawString("test", 0, 0, "top")
- end
- 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")
- cube:disp(gc)
- end
- function on.charIn(ch)
- if ch == '+' and fov > 0 then
- fov = fov - 5
- elseif ch == '-' and fov < 180 then
- fov = fov + 5
- elseif ch == '8' then
- incx = -5
- elseif ch == '2' then
- incx = 5
- elseif ch == '6' then
- incy = -5
- elseif ch == '4' then
- incy = 5
- elseif ch == 'p' then
- timer.stop()
- elseif ch == 's' then
- timer.start(0.01)
- end
- screen:invalidate()
- end
- function on.timer()
- cube:rotate(incx, incy, 0)
- screen:invalidate()
- end
- function on.arrowLeft()
- cube:move(-1, 0, 0)
- screen:invalidate()
- end
- function on.arrowRight()
- cube:move(1, 0, 0)
- screen:invalidate()
- end
- function on.arrowUp()
- cube:move(0, 1, 0)
- screen:invalidate()
- end
- function on.arrowDown()
- cube:move(0, -1, 0)
- screen:invalidate()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement