Advertisement
jig487

Plum3DMath

Nov 11th, 2021 (edited)
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.07 KB | None | 0 0
  1. --Multiply a given matrix by every vertice in given verts table
  2. local function multiplyVerts(mat, vert) --m == matrix, v == vertice list
  3.     local result = {}
  4.     for i = 1, #vert, 4 do --Iterate through each vertice
  5.             result[i] =
  6.               ( vert[i]   * mat[1])
  7.             + ( vert[i+1] * mat[2])
  8.             + ( vert[i+2] * mat[3])
  9.             + ( vert[i+3] * mat[4])
  10.  
  11.             result[i+1] =
  12.               ( vert[i]   * mat[5])
  13.             + ( vert[i+1] * mat[6])
  14.             + ( vert[i+2] * mat[7])
  15.             + ( vert[i+3] * mat[8])
  16.  
  17.             result[i+2] =
  18.               ( vert[i]   * mat[9])
  19.             + ( vert[i+1] * mat[10])
  20.             + ( vert[i+2] * mat[11])
  21.             + ( vert[i+3] * mat[12])
  22.  
  23.             result[i+3] =
  24.               ( vert[i]   * mat[13])
  25.             + ( vert[i+1] * mat[14])
  26.             + ( vert[i+2] * mat[15])
  27.             + ( vert[i+3] * mat[16])
  28.     end
  29.     return result
  30. end
  31.  
  32. --returns an identity matrix
  33. local function makeIdentity()
  34.     return {
  35.         1, 0, 0, 0,
  36.         0, 1, 0, 0,
  37.         0, 0, 1, 0,
  38.         0, 0, 0, 1, }
  39. end
  40.  
  41. --returns a projection matrix
  42. local function makeProjectionMat(fov,n,f)
  43.     local s = 1/(math.tan(fov/2*(3.14/180)))
  44.     return {
  45.         s, 0, 0, 0,
  46.         0, s, 0, 0,
  47.         0, 0, -f/(f-n), -f*n/(f-n),
  48.         0, 0, -1, 0
  49.     }
  50. end
  51.  
  52. --returns a rotation matrix
  53. local function makeRotation(eulers)
  54.     local x = math.rad(eulers.x)
  55.     local y = math.rad(eulers.y)
  56.     local z = math.rad(eulers.z)
  57.  
  58.     local sx = math.sin(x)
  59.     local sy = math.sin(y)
  60.     local sz = math.sin(z)
  61.    
  62.     local cx = math.cos(x)
  63.     local cy = math.cos(y)
  64.     local cz = math.cos(z)    
  65.     return
  66.     {
  67.         cy * cz, -cy * sz, sy, 0,
  68.         (sx * sy * cz) + (cx * sz), (-sx * sy * sz) + (cx * cz), -sx * cy, 0,
  69.         (-cx * sy * cz) + (sx * sz), (cx * sy * sz) + (sx * cz), cx * cy, 0,
  70.         0, 0, 0, 1, }
  71. end
  72.  
  73. --return translation matrix
  74. local function makeTranslation(translation)
  75.     return
  76.     {
  77.         1, 0, 0, translation.x,
  78.         0, 1, 0, translation.y,
  79.         0, 0, 1, translation.z,
  80.         0, 0, 0, 1, }
  81. end
  82.  
  83. --make scale matrix
  84. local function makeScale(scale)
  85.     return
  86.     {
  87.         scale.x, 0, 0, 0,
  88.         0, scale.y, 0, 0,
  89.         0, 0, scale.z, 0,
  90.         0, 0, 0, 1 }        
  91. end
  92.  
  93. --Returns data of default cube
  94. local function newCube()
  95.     local objData = {
  96.             --Matrix values
  97.         scale = vector.new(1,1,1), --Scale of model
  98.         loc = vector.new(0,0,0),   --Location of model
  99.         rot = vector.new(0,0,0),   --Rotation of model
  100.             --define the colors of each triangle in hexidecimal
  101.         colorList = {
  102.             0xBA1F33, 0xCD5D67,
  103.             0xF2A65A, 0xEEC170,
  104.  
  105.             0x46B1C9, 0x84C0C6,
  106.             0xBFACB5, 0xE5D0CC,
  107.  
  108.             0xF564A9, 0xFAA4BD,
  109.             0x8CD790, 0xAAFCB8,
  110.         },
  111.         indexList = {
  112.                 --1 face, composed of 2 triangles, each defined by 3 points.
  113.                 --These are 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
  114.             1,3,2, 3,4,2,
  115.             2,4,6, 4,8,6,
  116.  
  117.             3,7,4, 7,8,4,
  118.             6,8,5, 8,7,5,
  119.  
  120.             5,7,1, 7,3,1,
  121.             5,1,6, 1,2,6, },
  122.             --Each possible vertice for the indexList to point to
  123.         vertices = { --4x1 matrix structure for each vertex.
  124.             -0.5, -0.5, -0.5, 1,
  125.              0.5, -0.5, -0.5, 1,
  126.             -0.5,  0.5, -0.5, 1,
  127.              0.5,  0.5, -0.5, 1,
  128.  
  129.             -0.5, -0.5, 0.5, 1,
  130.              0.5, -0.5, 0.5, 1,
  131.             -0.5,  0.5, 0.5, 1,  
  132.              0.5,  0.5, 0.5, 1, }
  133.         }
  134.         for i,val in ipairs(objData.indexList) do
  135.             objData.indexList[i] = val*4-3
  136.         end
  137.     return objData
  138. end
  139.  
  140. --Centers drawings, divides by Z, multiplies X by aspect ratio
  141. --takes in a vector (v) with 4 values (x,y,z,w) and info about the display (x,y)
  142. local function processTriangle(x,y,z,w,xF,yF)
  143.         --Geometry shader here
  144.  
  145.         --Post process stuff here
  146.     --v.w = v.z
  147.     fw = (1/w)
  148.     fx = (x * fw  +1) * xF
  149.     fy = (-y * fw +1) * yF
  150.     fz = z * fw
  151.     return fx,fy,fz,fw
  152. end
  153.  
  154. local function crossProduct(ax,ay,az,bx,by,bz)
  155.     local cx = ay*bz-az*by
  156.     local cy = az*bx-ax*bz
  157.     local cz = ax*by-ay*bx
  158.     return cx,cy,cz
  159. end
  160.  
  161. local function dotProduct(ax,ay,az,bx,by,bz)
  162.     return ax*bx + ay*by + az*bz
  163. end
  164.  
  165. --Takes in an entire object and returns transformed vertices and a cullFlag list
  166. --Need to switch to making a MVP and Camera(?)World(?) mat then multiplying
  167. local function screenTransform(objectData,display,camera,projMat)
  168.     local xF = display.x*0.5 --X and Y factors for scaling to screen
  169.     local yF = display.y*0.5
  170.  
  171.     local iL = objectData.indexList
  172.     local cL = objectData.colorList
  173.  
  174.     local scale =    makeScale(objectData.scale)
  175.     local rotMat =   makeRotation(objectData.rot)
  176.     local transMat = makeTranslation(objectData.loc)
  177.  
  178.     --projMat = makeIdentity()
  179.         --Transforms the entire object
  180.     local result = multiplyVerts(transMat, multiplyVerts(rotMat, multiplyVerts(scale, objectData.vertices)))
  181.     result = multiplyVerts(projMat, result)
  182.         --Do backface culling test. If passed then load triangle into finalVectors{} table
  183.     local finalVectors = { colorList = {} }
  184.     for i = 1, #iL, 3 do
  185.         --backface culling test here
  186.         local i1,i2 = i+1, i+2
  187.         local cx,cy,cz = crossProduct(result[iL[i2]],result[iL[i2]+1],result[iL[i2]+2],result[iL[i1]],result[iL[i1]+1],result[iL[i1]+2])
  188.         if dotProduct(cx,cy,cz,result[iL[i]],result[iL[i]+1],result[iL[i]+2]) >= 0 then
  189.             local len = #finalVectors
  190.                 --Centers drawings, divides by W, aspect ratio correction
  191.             finalVectors[len+1],finalVectors[len+2],finalVectors[len+3],finalVectors[len+4]    = processTriangle(result[iL[i]],  result[iL[i]+1],  result[iL[i]+2],  result[iL[i]+3],  xF, yF)
  192.             finalVectors[len+5],finalVectors[len+6],finalVectors[len+7],finalVectors[len+8]    = processTriangle(result[iL[i1]], result[iL[i1]+1], result[iL[i1]+2], result[iL[i1]+3], xF, yF)
  193.             finalVectors[len+9],finalVectors[len+10],finalVectors[len+11],finalVectors[len+12] = processTriangle(result[iL[i2]], result[iL[i2]+1], result[iL[i2]+2], result[iL[i2]+3], xF, yF)
  194.                 --X,Y,Z,W of points in order that make up a triangle
  195.             --local vec1 = vector.new( result[iL[i]],  result[iL[i]+1],  result[iL[i]+2],  result[iL[i]+3]  )
  196.             --local vec2 = vector.new( result[iL[i1]], result[iL[i1]+1], result[iL[i1]+2], result[iL[i1]+3] )
  197.             --local vec3 = vector.new( result[iL[i2]], result[iL[i2]+1], result[iL[i2]+2], result[iL[i2]+3] )
  198.                 --Assign colors
  199.             finalVectors.colorList[ #finalVectors.colorList+1 ] = cL[(i+2)/3]
  200.         end
  201.     end
  202.     return finalVectors
  203. end
  204.  
  205. --expose library functions
  206. return
  207. {
  208.     makeProjectionMat = makeProjectionMat,
  209.     screenTransform = screenTransform,
  210.     newCube = newCube,
  211. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement