9551

3d testing V7

Oct 10th, 2021 (edited)
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.15 KB | None | 0 0
  1. local pretty = require("cc.pretty")
  2. local t = require("bruh")
  3. local c
  4. local width,height
  5. local win
  6. local ot = term
  7. term = peripheral.find("monitor")
  8. term.setTextScale(0.5)
  9. term.setCursorPos(10,10)
  10. width,height = term.getSize()
  11. term = window.create(term,1,1,width,height)
  12. local function makeProjection(w,h,n,f)
  13.     --w = width
  14.     --h = height
  15.     --n = near plane
  16.     --f = far plane
  17.     return {
  18.         {2*n/w,0,0,0},
  19.         {0,2*n/h, 0,0},
  20.         {0,0,f/(f-n),-n*f/(f-n)},
  21.         {0,0,-1,0}
  22.     }
  23. end
  24. local makeIdentity = function()
  25.     return {
  26.         {1,0,0,0},
  27.         {0,1,0,0},
  28.         {0,0,1,0},
  29.         {0,0,0,1}
  30.     }
  31. end
  32. local makeTranslation = function(cords)
  33.     return {
  34.         {1,0,0,cords.x},
  35.         {0,1,0,cords.y},
  36.         {0,0,1,cords.z},
  37.         {0,0,0,1}
  38.     }
  39. end
  40. local function makeScale(scale)
  41.     return
  42.     {
  43.         {scale.x, 0, 0, 0},
  44.         {0, scale.y, 0, 0},
  45.         {0, 0, scale.z, 0},
  46.         {0, 0, 0, 1}
  47.     }        
  48. end
  49. local function makeRotation(eulers)
  50.     local x = math.rad(eulers.x)
  51.     local y = math.rad(eulers.y)
  52.     local z = math.rad(eulers.z)
  53.     local sx = math.sin(x)
  54.     local sy = math.sin(y)
  55.     local sz = math.sin(z)
  56.    
  57.     local cx = math.cos(x)
  58.     local cy = math.cos(y)
  59.     local cz = math.cos(z)
  60.     return
  61.     {
  62.         {cy * cz, -cy * sz, sy, 0},
  63.         {(sx * sy * cz) + (cx * sz), (-sx * sy * sz) + (cx * cz), -sx * cy, 0},
  64.         {(-cx * sy * cz) + (sx * sz), (cx * sy * sz) + (sx * cz), cx * cy, 0},
  65.         {0, 0, 0, 1,}
  66.     }
  67. end
  68. local function makePerspective(width, height, n, f, fov)
  69.     local aspectRatio = 3/2*height / width  
  70.     fov = math.rad(fov)
  71.     return
  72.     {
  73.         {aspectRatio/math.tan(fov*0.5),0,0,0},
  74.         {0,1/(math.tan(fov*0.5)),0,0},
  75.         {0,0,-f/(f-n),-f*n/(f-n)},
  76.         {0,0,-1,0}
  77.     }
  78. end
  79. local function matmul(m1, m2)
  80.     if #m1[1] ~= #m2 then
  81.         error("Columns m1 must match rows m2",2)
  82.     end
  83.     local result = {}
  84.     for i = 1, #m1 do
  85.         result[i] = {}
  86.         for j = 1, #m2[1] do
  87.             local sum = 0
  88.             for k = 1, #m2 do sum = sum + (m1[i][k] * m2[k][j]) end
  89.             result[i][j] = sum
  90.         end
  91.     end
  92.     return result
  93. end
  94. local function drawLine(startX, startY, endX, endY, color)
  95.     local sc = term.getBackgroundColor()
  96.     term.setBackgroundColor(color)
  97.     local drawPixelInternal = function(x,y) term.setCursorPos(x,y) term.write(" ") end
  98.     local startX,startY,endX,endY = math.floor(startX),math.floor(startY),math.floor(endX),math.floor(endY)
  99.     if startX == endX and startY == endY then drawPixelInternal(startX, startY) term.setBackgroundColor(sc) return end
  100.     local minX = math.min(startX, endX)
  101.     local maxX, minY, maxY
  102.     if minX == startX then minY = startY maxX = endX maxY = endY
  103.     else minY = endY maxX = startX maxY = startY end
  104.     local xDiff,yDiff = maxX - minX,maxY - minY
  105.     if xDiff > math.abs(yDiff) then
  106.         local y,dy = minY,yDiff / xDiff
  107.         for x = minX, maxX do drawPixelInternal(x, math.floor(y+0.5)) y = y + dy end
  108.     else
  109.         local x,dx = minX,xDiff / yDiff
  110.         if maxY >= minY then for y = minY, maxY do drawPixelInternal(math.floor(x ), y) x = x + dx end
  111.         else for y = minY, maxY, -1 do drawPixelInternal(math.floor(x+0.5), y) x = x - dx end end
  112.     end
  113.     term.setBackgroundColor(sc)
  114. end
  115. local function createColor(whitelist,blacklist)
  116.     local cols,clist,cCount = {},{},0
  117.     local acls = whitelist or {}
  118.     local useall = not whitelist
  119.     local bcls = blacklist or {}
  120.     local clist = {}
  121.     for k,v in pairs(colors) do
  122.         if type(v) == "number" and useall or acls[v] and not bcls[v] then
  123.             table.insert(clist,v)
  124.         end
  125.     end
  126.     return setmetatable({},{
  127.         __index=function(t,k)
  128.             cCount = cCount + 1
  129.             local col = clist[cCount]
  130.             if cCount >= #clist then cCount = 0 end
  131.             t[k]=col
  132.             return col
  133.         end
  134.     })
  135. end
  136. local function createPerspective(width,height,FOV)
  137.     return makePerspective(width,height,100,10,FOV)
  138. end
  139. local function createCamera(locVector,rotVector)
  140.     return {
  141.         loc=makeTranslation(-locVector),
  142.         rot=makeRotation(-rotVector)
  143.     }
  144. end
  145. local function transform(objList,persperctive,camera)
  146.     local objectsInt = setmetatable({},
  147.         {
  148.             __index=function(t,k)
  149.                 local new = {}
  150.                 t[k]=new
  151.                 return new
  152.             end
  153.         }
  154.     )
  155.     for k,v in pairs(objList) do
  156.         objectsInt[k] = {main=v,vectors={},origins={}}
  157.         local scale = makeScale(v.scale)
  158.         local rot = makeRotation(v.rot)
  159.         local loc = makeTranslation(v.loc)
  160.         local tempObj = {}
  161.         for k1,v1 in pairs(v.vertices) do
  162.             local model = matmul(loc, matmul(rot, matmul(scale, v1)))
  163.             local cam = matmul(camera.rot, matmul(camera.loc, model))
  164.             local projected = matmul(persperctive,cam)
  165.             table.insert(tempObj,projected)
  166.         end
  167.         for k2,v2 in pairs(tempObj) do
  168.             local projected = v2
  169.             local w = 1/projected[4][1]
  170.             projected[1][1] = (projected[1][1] * w  +1) * (width * 0.5)
  171.             projected[2][1] = (-projected[2][1] * w +1) * (height * 0.5)
  172.             table.insert(objectsInt[k].vectors,projected)
  173.             table.insert(objectsInt[k].origins,v2)
  174.         end
  175.     end
  176.     return objectsInt
  177. end
  178. local function getDrawArgs()
  179.     return {
  180.         doCulling = true,
  181.         drawWireFrame = false,
  182.         doZCheck = true,
  183.         drawTriangles = true
  184.     }
  185. end
  186. local function drawTransformed(objects,arguments)
  187.     if not arguments then
  188.         arguments = {
  189.             doCulling = true,
  190.             drawWireFrame = false,
  191.             doZCheck = true,
  192.             drawTriangles = true
  193.         }
  194.     end
  195.     for k,vm in pairs(objects) do
  196.         for k,v in pairs(vm.main.connections) do
  197.             local v1 = vector.new(vm.origins[v[1]][1][1],vm.origins[v[1]][2][1],vm.origins[v[1]][3][1])
  198.             local v2 = vector.new(vm.origins[v[2]][1][1],vm.origins[v[2]][2][1],vm.origins[v[2]][3][1])
  199.             local v3 = vector.new(vm.origins[v[3]][1][1],vm.origins[v[3]][2][1],vm.origins[v[3]][3][1])
  200.             if (math.abs(v1.z) > 1 and math.abs(v2.z) > 1 and math.abs(v3.z) > 1) or arguments.doZCheck then
  201.                 if ((v2:cross(v3)):dot(v1) >= 0) or not arguments.doCulling then
  202.                     if arguments.drawTriangles then
  203.                         t.drawSolidTriangle(term,v1,v2,v3,vm.main.color[k])
  204.                     end
  205.                     if arguments.drawWireFrame then
  206.                         drawLine(vm.vectors[v[1]][1][1],vm.vectors[v[1]][2][1],vm.vectors[v[2]][1][1],vm.vectors[v[2]][2][1],vm.main.color[k])
  207.                         drawLine(vm.vectors[v[2]][1][1],vm.vectors[v[2]][2][1],vm.vectors[v[3]][1][1],vm.vectors[v[3]][2][1],vm.main.color[k])
  208.                         drawLine(vm.vectors[v[3]][1][1],vm.vectors[v[3]][2][1],vm.vectors[v[1]][1][1],vm.vectors[v[1]][2][1],vm.main.color[k])
  209.                     end
  210.                 end
  211.             end
  212.         end
  213.         term.setBackgroundColor(colors.black)
  214.     end
  215. end
  216. local function newSquare()
  217.     local objData = {
  218.         scale = vector.new(1,1,1),
  219.         loc = vector.new(0,0,0),
  220.         rot = vector.new(0,0,0),
  221.         color = createColor(),
  222.         indexList = {1},
  223.         vertices = {
  224.             {{-0.5}, {-0.5}, {0}, {1}},
  225.             {{0.5}, {-0.5}, {0}, {1}},
  226.             {{-0.5},  {0.5}, {0}, {1}},
  227.             {{0.5},  {0.5}, {0}, {1}},
  228.         },
  229.         connections = {
  230.             {3,2,1},
  231.             {2,4,3},
  232.             {1,2,3},
  233.             {3,4,2},
  234.         }
  235.     }
  236.     for i,val in ipairs(objData.indexList) do
  237.         objData.indexList[i] = val*4-3
  238.     end
  239.     return objData
  240. end
  241. local function newCube()
  242.     local objData = {
  243.         scale = vector.new(1,1,1),
  244.         loc = vector.new(0,0,0),
  245.         rot = vector.new(0,0,0),
  246.         color = createColor(),
  247.         indexList = {1},
  248.         vertices = {
  249.             { { -0.5}, { -0.5}, {0.5}, {1} },  
  250.             { {0.5}, { -0.5}, {0.5}, {1} },
  251.             { { -0.5}, {0.5}, {0.5}, {1} },
  252.             { {0.5}, {0.5}, {0.5}, {1} },
  253.             { { -0.5}, { -0.5}, { -0.5}, {1}},
  254.             { {0.5}, { -0.5}, { -0.5}, {1}},
  255.             { { -0.5}, {0.5}, { -0.5}, {1}},
  256.             { {0.5}, {0.5}, { -0.5}, {1}}
  257.         },
  258.         connections = {{ 1,3,4 },{ 1,4,2 },{ 5,7,3 },{ 5,3,1 },{ 6,8,7 },{ 6,7,5 },{ 2,4,8 },{ 2,8,6 },{ 3,7,8 },{ 3,8,4 },{ 5,1,2 },{ 5,2,6 }}
  259.     }
  260.     for i,val in ipairs(objData.indexList) do
  261.         objData.indexList[i] = val*4-3
  262.     end
  263.     return objData
  264. end
  265. local function newPyramid()
  266.     local objData = {
  267.         scale = vector.new(1,1,1),
  268.         loc = vector.new(0,0,0),
  269.         rot = vector.new(0,0,0),
  270.         color = createColor(),
  271.         indexList = {1},
  272.         vertices = {
  273.             {{-0.5}, {-0.5}, {-0.5}, {1}},
  274.             {{0.5}, {-0.5}, {-0.5}, {1}},
  275.             {{-0.5}, {-0.5}, {0.5}, {1}},
  276.             {{0.5}, {-0.5}, {0.5}, {1}},
  277.             {{0}, {0.5}, {0}, {1}}
  278.         },
  279.         connections = {{3,2,1},{3,4,2},{2,5,1},{3,5,4},{4,5,2},{1,5,3}}
  280.     }
  281.     for i,val in ipairs(objData.indexList) do
  282.         objData.indexList[i] = val*4-3
  283.     end
  284.     return objData
  285. end
  286. local proj = {}
  287. local rot = 0
  288. local xFactor = height*0.5
  289. local yFactor = width*0.5
  290. local objList = {
  291.     p1=newPyramid(),
  292.     p2=newPyramid(),
  293.     p3=newPyramid()
  294. }
  295. local color = {
  296.     [colors.orange]=true
  297. }
  298. objList.p1.color = createColor(color)
  299. objList.p2.color = createColor(color)
  300. objList.p3.color = createColor(color)
  301. objList.p1.loc.z = 5
  302. local frames = 10000
  303. local st = os.epoch("utc")/1000
  304. local args = getDrawArgs()
  305. args.drawTriangles = true
  306. args.drawWireFrame = false
  307. args.doCulling = true
  308. for i=1,frames do
  309.     objList.p1.rot.y =  os.epoch()/2000
  310.     term.setVisible(false)
  311.     term.clear()
  312.     local pers = createPerspective(width,height,40)
  313.     local cam = createCamera(vector.new(0,0,0),vector.new(0,0,0))
  314.     local objectsInt = transform(objList,pers,cam)
  315.     drawTransformed(objectsInt,args)
  316.     term.setVisible(true)
  317.     os.queueEvent("fake")
  318.     os.pullEvent("fake")
  319. end
  320. local et = os.epoch("utc")/1000
  321. local fps = frames/(et-st)
  322. print("FPS: "..fps)
Add Comment
Please, Sign In to add comment