Advertisement
jig487

JIG3D_3D_Tools_Dev

Aug 23rd, 2021 (edited)
1,063
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.40 KB | None | 0 0
  1. -- 3D tools API
  2.  
  3. --Math functions
  4.  
  5. --Multiply a given matrix by every vertice in given verts table
  6. local function multiplyVerts(mat, vert) --m == matrix, v == vertice list
  7.     if #mat ~= 16 then
  8.         error("Matrix must have length of 16 (4x4 matrix)")
  9.     end
  10.     local result = {}
  11.     for i = 1, #vert, 4 do --Iterate through each vertice
  12.         for k = 1, 4 do --Multiply said vertice by the given matrix. result[1 -> 4] are equal to a 4x1 matrix.
  13.             result[i+k-1] = ( mat[k*4-3] * vert[i] ) + ( mat[k*4-2] * vert[i+1] ) + ( mat[k*4-1] * vert[i+2] ) + ( mat[k*4] * vert[i+3] )
  14.         end
  15.     end
  16.     return result
  17. end
  18. --Special matrix generators
  19.  
  20. --BUG FIX: add special matrix multiplication function for the makeView function so that it doesn't break
  21. --makeView not being used right now
  22. local function makeView(position, rotationEulers)
  23.     --return multiply(makeRotation(rotationEulers), makeTranslation(position))
  24. end
  25.  
  26. local function makeIdentity()
  27.     return
  28.     {
  29.         1, 0, 0, 0,
  30.         0, 1, 0, 0,
  31.         0, 0, 1, 0,
  32.         0, 0, 0, 1, }
  33. end
  34.  
  35. --Currently being replaced with makeCheapZ in the code
  36. local function makePerspective(width, height, n, f, fov) --n = near, f = far
  37.     local aspectRatio = height / width
  38.     fov = math.rad(fov)
  39.     local tFov = math.tan(fov*0.5)
  40.     return
  41.     {
  42.         1/(aspectRatio*tFov), 0, 0, 0,
  43.         0, 1/tFov, 0, 0,
  44.         0, 0, -(f+n) / (f-n), -(2*f*n) / (f-n),
  45.         0, 0, -1, 0 }
  46. end
  47.  
  48. local function makeRotation(eulers)
  49.     local x = math.rad(eulers.x)
  50.     local y = math.rad(eulers.y)
  51.     local z = math.rad(eulers.z)
  52.  
  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.          
  61.     return
  62.     {
  63.         cy * cz, -cy * sz, sy, 0,
  64.         (sx * sy * cz) + (cx * sz), (-sx * sy * sz) + (cx * cz), -sx * cy, 0,
  65.         (-cx * sy * cz) + (sx * sz), (cx * sy * sz) + (sx * cz), cx * cy, 0,
  66.         0, 0, 0, 1, }
  67. end
  68.  
  69. local function makeTranslation(translation)
  70.     return
  71.     {
  72.         1, 0, 0, translation.x,
  73.         0, 1, 0, translation.y,
  74.         0, 0, 1, translation.z,
  75.         0, 0, 0, 1, }
  76. end
  77.  
  78. local function makeScale(scale)
  79.     return
  80.     {
  81.         scale.x, 0, 0, 0,
  82.         0, scale.y, 0, 0,
  83.         0, 0, scale.z, 0,
  84.         0, 0, 0, 1 }        
  85. end
  86.  
  87. local function makeCheapZ(display)
  88.     return {
  89.         1/display.x, 0, 0, 0,
  90.         0, -1/display.y, 0, 0,
  91.         0, 0, 1, 0,
  92.         0, 0, 0, 1, }
  93. end
  94.  
  95. --Returns camera data
  96. --Camera doesn't work right now. Isn't part of anything in the code.
  97. local function makeCam()
  98.     return {
  99.         loc = vector.new(0,0,0),
  100.         rot = vector.new(0,0,0),
  101.     }
  102. end
  103.  
  104. --Returns data of default cube
  105. local function newCube()
  106.     local objData = {
  107.         --Matrix values
  108.         scale = vector.new(1,1,1), --Scale of model
  109.         loc = vector.new(0,0,0),   --Location of model
  110.         rot = vector.new(0,0,0),   --Rotation of model
  111.         --Texture stuff
  112.         UVList = { --UV coordinates for each vertice in vertices table.
  113.             0,0,
  114.             1,0,
  115.             0,1,
  116.             1,1,
  117.  
  118.             1,0,
  119.             0,0,
  120.             1,1,
  121.             0,1,
  122.         },
  123.         --base colors of each triangle in hexidecimal
  124.         colorList = {
  125.             0xBA1F33, 0xCD5D67,
  126.             0xF2A65A, 0xEEC170,
  127.  
  128.             0x46B1C9, 0x84C0C6,
  129.             0xBFACB5, 0xE5D0CC,
  130.  
  131.             0xF564A9, 0xFAA4BD,
  132.             0x8CD790, 0xAAFCB8, },
  133.         --points to three vertices in vertices list to describe a triangle
  134.         indexList = {
  135.             --These are later multiplied by 4 then offset by -3 because it's a 1D table and it's way easier to read if they are kept like this
  136.             1,3,2, 3,4,2,
  137.             2,4,6, 4,8,6,
  138.  
  139.             3,7,4, 4,7,8,
  140.             5,6,8, 5,8,7,
  141.  
  142.             1,5,3, 3,5,7,
  143.             1,2,5, 2,6,5, },
  144.         --Each possible vertice for the indexList to point to
  145.         vertices = { --4x1 matrix structure for each vertex.
  146.             -0.5, -0.5, -0.5, 1,
  147.              0.5, -0.5, -0.5, 1,
  148.             -0.5,  0.5, -0.5, 1,
  149.              0.5,  0.5, -0.5, 1,
  150.  
  151.             -0.5, -0.5, 0.5, 1,
  152.              0.5, -0.5, 0.5, 1,
  153.             -0.5,  0.5, 0.5, 1,  
  154.              0.5,  0.5, 0.5, 1, }
  155.     }
  156.     for i,val in ipairs(objData.indexList) do
  157.         objData.indexList[i] = val*4-3
  158.     end
  159.     return objData
  160. end
  161. --Returns data of default square
  162. local function newSqr() --Refer to newCube() for comments
  163.     local objData = {
  164.         scale = vector.new(1,1,1),
  165.         loc = vector.new(0,0,0),
  166.         rot = vector.new(0,0,0),
  167.         colorList = { 0xE56399, 0x7F96FF, },
  168.         indexList = { 1,3,2, 3,4,2, },
  169.         vertices = {
  170.             -0.5, -0.5, -0.5, 1,
  171.              0.5, -0.5, -0.5, 1,
  172.             -0.5,  0.5, -0.5, 1,
  173.              0.5,  0.5, -0.5, 1, } }
  174.     for i,val in ipairs(objData.indexList) do
  175.         objData.indexList[i] = val*4-3
  176.     end
  177.     return objData
  178. end
  179. --Returns data of default pyramid
  180. local function newPyr() --Refer to newCube() for comments
  181.     local objData = {
  182.         --Matrix values
  183.         scale = vector.new(1,1,1), --Scale of model
  184.         loc = vector.new(0,0,0),   --Location of model
  185.         rot = vector.new(0,0,0),   --Rotation of model
  186.         --Texture stuff
  187.         UVList = { --List of UV coordinates for each vertice.
  188.             -0.5, -0.5, -0.5, 1,
  189.              0.5, -0.5, -0.5, 1,
  190.             -0.5, -0.5,  0.5, 1,
  191.              0.5, -0.5,  0.5, 1,
  192.              0,    0.5,  0,   1, },
  193.         --base colors of each triangle in hexidecimal
  194.         colorList = {
  195.             0xBA1F33, 0xCD5D67,
  196.             0xF2A65A, 0xEEC170,
  197.             0x46B1C9, 0x84C0C6, },
  198.         --points to three vertices in vertices list to describe a triangle
  199.         indexList = {
  200.             --These are later multiplied by 4 then offset by -3 because it's a 1D table and it's way easier to read if they are kept like this
  201.             1,5,2,
  202.             2,5,4,
  203.             4,5,3,
  204.             3,5,1,
  205.             3,1,2,
  206.             3,2,4, },
  207.         --Each possible vertice for the indexList to point to
  208.         vertices = { --4x1 matrix structure for each vertex.
  209.             -0.5, -0.5, -0.5, 1,
  210.              0.5, -0.5, -0.5, 1,
  211.             -0.5, -0.5,  0.5, 1,
  212.              0.5, -0.5,  0.5, 1,
  213.              0,    0.5,  0,   1, }
  214.     }
  215.     for i,val in ipairs(objData.indexList) do
  216.         objData.indexList[i] = val*4-3
  217.     end
  218.     return objData
  219. end
  220.  
  221. --Takes in an entire object and returns transformed vertices and a cullFlag list
  222. local function screenTransform(objectData,display,camera,aspectRatio)
  223.     local iL = objectData.indexList
  224.     local uvL = objectData.UVList
  225.  
  226.     local scale =    makeScale(objectData.scale)
  227.     local rotMat =   makeRotation(objectData.rot)
  228.     local transMat = makeTranslation(objectData.loc)
  229.         --Transforms the entire object
  230.     local result = multiplyVerts(transMat, multiplyVerts(rotMat, multiplyVerts(scale, objectData.vertices)))
  231.         --Getting the cross product of each face to later be used for backface culling
  232.     result.cullFlags = {}
  233.     for i = 1, #iL, 3 do
  234.         local i1,i2 = i+1, i+2
  235.         local vec1 = vector.new(result[iL[i]], result[iL[i]+1], result[iL[i]+2])
  236.         local vec2 = vector.new(result[iL[i1]], result[iL[i1]+1], result[iL[i1]+2])
  237.         local vec3 = vector.new(result[iL[i2]], result[iL[i2]+1], result[iL[i2]+2])
  238.  
  239.         result.UVList[i]  = { x = objectData.UVList[iL[i]],  y = objectData.UVList[iL[i]+1] }
  240.         result.UVList[i1] = { x = objectData.UVList[iL[i1]], y = objectData.UVList[iL[i1]+1] }
  241.         result.UVList[i2] = { x = objectData.UVList[iL[i2]], y = objectData.UVList[iL[i2]+1] }
  242.  
  243.         result.cullFlags[i] = (vec3:cross(vec2)):dot(vec1)
  244.     end
  245.         --Perspective divide
  246.     for i = 1,#result, 4 do --Divide each vertice by its Z val
  247.         local zInv = 1/result[i+2]
  248.         result[i]   = ((result[i]  *zInv +1) * display.x)*aspectRatio --Transform to screen space and fix aspect ratio
  249.         result[i+1] = (-result[i+1]*zInv +1) * display.y --Transform to screen space
  250.         result[i+2] = zInv
  251.     end
  252.     return result
  253. end
  254.  
  255. -- expose library functions
  256. return
  257. {
  258.     screenTransform = screenTransform,
  259.     newCube = newCube,
  260.     newSqr = newSqr,
  261.     makeCam = makeCam,
  262.     newPyr = newPyr,
  263. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement