jig487

JIG3D_3D_API_v1.0

Sep 30th, 2021 (edited)
1,016
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.84 KB | None | 0 0
  1. -- 3D tools API
  2.  
  3. local function getPlayerData(playerName) --Get a target players position and rotation
  4.     local result = { rot = {}, loc = {} }
  5.    
  6.     local _, rot = commands.exec("data get entity "..playerName.." Rotation")
  7.     for i in string.gmatch(rot[1], "%-?%d+%.%d+") do
  8.         result.rot[ #result.rot + 1 ] = i
  9.     end
  10.  
  11.     local _, loc = commands.exec("data get entity "..playerName.." Pos")
  12.     for i in string.gmatch(loc[1], "%-?%d+%.%d+") do
  13.         result.loc[ #result.loc + 1 ] = i
  14.     end
  15.     local playerData = {}
  16.         --I put them into vector format with {x= , y= , z= } because that's what our matrices use
  17.         --Offset by 1.62 because minecraft gets location based on feet, and camera is 1.62 blocks high
  18.     playerData.loc = vector.new(result.loc[1],result.loc[2]+1.62,result.loc[3])
  19.         --Rotation X / Y are swapped because minecraft returns Y, X instead of X, Y
  20.     playerData.rot = vector.new(result.rot[2],result.rot[1],0)
  21.     return playerData
  22. end
  23.  
  24. --Math functions
  25.  
  26. --Multiply a given matrix by every vertice in given verts table
  27. local function multiplyVerts(mat, vert) --m == matrix, v == vertice list
  28.     if #mat ~= 16 then
  29.         error("Matrix must have length of 16 (4x4 matrix)")
  30.     end
  31.     local result = {}
  32.     for i = 1, #vert, 4 do --Iterate through each vertice
  33.         for k = 1, 4 do --Multiply said vertice by the given matrix. result[1 -> 4] are equal to a 4x1 matrix.
  34.             result[i+k-1] =
  35.               ( mat[k*4-3] * vert[i]   )
  36.             + ( mat[k*4-2] * vert[i+1] )
  37.             + ( mat[k*4-1] * vert[i+2] )
  38.             + ( mat[k*4]   * vert[i+3] )
  39.         end
  40.     end
  41.     return result
  42. end
  43.  
  44. local function getVecNeg(vec)
  45.     return {
  46.         x = -vec.x,
  47.         y = -vec.y,
  48.         z = -vec.z,
  49.     }
  50. end
  51.  
  52. --Makes an empty depth buffer using display size. Use this ONCE PER DISPLAY, BEFORE your main loop.
  53.     --Then set another var in the loop to this so you aren't constantly re-making it, just grabbing an empty copy
  54. local function makeDepthBuffer(display)
  55.     local depthBuffer = { size = { x = display.x, y = display.y } }
  56.     for y = 1, display.y do
  57.         for w = 1, display.x do
  58.             depthBuffer[((y*display.x) + w)] = math.huge
  59.         end
  60.     end
  61.     return depthBuffer
  62. end
  63.  
  64. --Special matrix generators
  65.  
  66. local function makeIdentity()
  67.     return {
  68.         1, 0, 0, 0,
  69.         0, 1, 0, 0,
  70.         0, 0, 1, 0,
  71.         0, 0, 0, 1, }
  72. end
  73.  
  74. local function makeProjectionMat(fov,n,f)
  75.     local s = 1/(math.tan((fov/2)*(3.14/180)))
  76.     return {
  77.         s, 0, 0, 0,
  78.         0, s, 0, 0,
  79.         0, 0, -f/(f-n), -1,
  80.         0, 0, -f*n/(f-n), 0
  81.     }
  82. end
  83.  
  84. --[[
  85. local function makeProjectionMat(n,f,t,b,l,r)
  86.     return {
  87.         2*n/(r-l), 0, (r+l)/(r-l), 0,
  88.         0, 2*n/(t-b), (t+b)/(t-b), 0,
  89.         0, 0, -((f+n)/(f-n)), -(2*f*n/(f-n)),
  90.         0, 0, -1, 0 }
  91. end
  92. ]]
  93.  
  94. local function makeRotation(eulers)
  95.     local x = math.rad(eulers.x)
  96.     local y = math.rad(eulers.y)
  97.     local z = math.rad(eulers.z)
  98.  
  99.     local sx = math.sin(x)
  100.     local sy = math.sin(y)
  101.     local sz = math.sin(z)
  102.    
  103.     local cx = math.cos(x)
  104.     local cy = math.cos(y)
  105.     local cz = math.cos(z)
  106.          
  107.     return
  108.     {
  109.         cy * cz, -cy * sz, sy, 0,
  110.         (sx * sy * cz) + (cx * sz), (-sx * sy * sz) + (cx * cz), -sx * cy, 0,
  111.         (-cx * sy * cz) + (sx * sz), (cx * sy * sz) + (sx * cz), cx * cy, 0,
  112.         0, 0, 0, 1, }
  113. end
  114.  
  115. local function makeTranslation(translation)
  116.     return
  117.     {
  118.         1, 0, 0, translation.x,
  119.         0, 1, 0, translation.y,
  120.         0, 0, 1, translation.z,
  121.         0, 0, 0, 1, }
  122. end
  123.  
  124. local function makeScale(scale)
  125.     return
  126.     {
  127.         scale.x, 0, 0, 0,
  128.         0, scale.y, 0, 0,
  129.         0, 0, scale.z, 0,
  130.         0, 0, 0, 1 }        
  131. end
  132.  
  133. --Makes a camera matrix for matrix multiplication. Not a camera that is used by the player
  134. local function makeCamera(cam)
  135.     local up = vector.new(0,1,0)
  136.     local p = getVecNeg(cam.loc) --position
  137.     p.z = -p.z
  138.  
  139.     local pitch = math.rad(cam.rot.x)
  140.     local yaw = math.rad(cam.rot.y)
  141.  
  142.     local x = -math.sin(yaw) * math.cos(pitch)
  143.     local z = math.cos(yaw) * math.cos(pitch)
  144.     local y = -math.sin(pitch)
  145.  
  146.     local f = (vector.new(x,y,z)):normalize() --forward
  147.  
  148.     local r = (up:cross(f)):normalize()
  149.  
  150.     --[[
  151.     return {
  152.         r.x, r.y, r.z, 0,
  153.         0, 1, 0, 0,
  154.         f.x, f.y, f.z, 0,
  155.         p.x, p.y, p.z, 1,
  156.     }
  157.     ]]
  158.     return {
  159.         r.x, 0, f.x, p.x,
  160.         r.y, 1, f.y, p.y,
  161.         r.z, 0, f.z, p.z,
  162.         0, 0, 0, 1,
  163.     }
  164.    
  165. end
  166.  
  167. --Returns data of default cube
  168. local function newCube()
  169.     local objData = {
  170.             --Matrix values
  171.         scale = vector.new(1,1,1), --Scale of model
  172.         loc = vector.new(0,0,0),   --Location of model
  173.         rot = vector.new(0,0,0),   --Rotation of model
  174.             --define the colors of each triangle in hexidecimal
  175.         colorList = {
  176.             0xBA1F33, 0xCD5D67,
  177.             0xF2A65A, 0xEEC170,
  178.  
  179.             0x46B1C9, 0x84C0C6,
  180.             0xBFACB5, 0xE5D0CC,
  181.  
  182.             0xF564A9, 0xFAA4BD,
  183.             0x8CD790, 0xAAFCB8,
  184.         },
  185.         indexList = {
  186.                 --1 face, composed of 2 triangles, each defined by 3 points.
  187.                 --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
  188.             1,3,2, 3,4,2,
  189.             2,4,6, 4,8,6,
  190.  
  191.             3,7,4, 7,8,4,
  192.             6,8,5, 8,7,5,
  193.  
  194.             5,7,1, 7,3,1,
  195.             5,1,6, 1,2,6, },
  196.             --Each possible vertice for the indexList to point to
  197.         vertices = { --4x1 matrix structure for each vertex.
  198.             -0.5, -0.5, -0.5, 1,
  199.              0.5, -0.5, -0.5, 1,
  200.             -0.5,  0.5, -0.5, 1,
  201.              0.5,  0.5, -0.5, 1,
  202.  
  203.             -0.5, -0.5, 0.5, 1,
  204.              0.5, -0.5, 0.5, 1,
  205.             -0.5,  0.5, 0.5, 1,  
  206.              0.5,  0.5, 0.5, 1, }
  207.         }
  208.         for i,val in ipairs(objData.indexList) do
  209.             objData.indexList[i] = val*4-3
  210.         end
  211.     return objData
  212. end
  213.     --Returns data of default square
  214. local function newSqr() --Refer to newCube() for comments
  215.     local objData = {
  216.         scale = vector.new(1,1,1),
  217.         loc = vector.new(0,0,0),
  218.         rot = vector.new(0,0,0),
  219.         colorList = { 0xE56399, 0x7F96FF, },
  220.         indexList = { 1,3,2, 3,4,2, },
  221.         vertices = {
  222.             -0.5, -0.5, -0.5, 1,
  223.              0.5, -0.5, -0.5, 1,
  224.             -0.5,  0.5, -0.5, 1,
  225.              0.5,  0.5, -0.5, 1, } }
  226.         for i,val in ipairs(objData.indexList) do
  227.             objData.indexList[i] = val*4-3
  228.         end
  229.     return objData
  230. end
  231.  
  232.     --Centers drawings, divides by Z, multiplies X by aspect ratio
  233.     --takes in a vector (v) with 4 values (x,y,z,w) and info about the display (x,y)
  234. local function processTriangle(v,display)
  235.         --Geometry shader here
  236.  
  237.         --Post process stuff here
  238.     local xFactor = display.y*0.5  --half height
  239.     local yFactor = display.x*0.5  --half width
  240.     v.w = v.z
  241.     v.w = (1/v.w)
  242.  
  243.     v.x = (v.x * v.w  +1) * xFactor
  244.     v.y = (-v.y * v.w +1) * yFactor
  245.     v.z = v.z * v.w
  246.     return v
  247. end
  248.  
  249.     --Takes in an entire object and returns transformed vertices and a cullFlag list
  250.         --Need to switch to making a MVP and Camera(?)World(?) mat then multiplying
  251. local function screenTransform(objectData,display,camera,projMat)
  252.     local iL = objectData.indexList
  253.     local cL = objectData.colorList
  254.  
  255.     local scale =    makeScale(objectData.scale)
  256.     local rotMat =   makeRotation(objectData.rot)
  257.     local transMat = makeTranslation(objectData.loc)
  258.  
  259.     --projMat = makeIdentity()
  260.  
  261.     --local cam = makeCamera(camera)
  262.  
  263.         --We get the negative of the vectors b/c they need to move/rotatate the world opposite of them
  264.     --camera.loc.z = camera.loc.z
  265.     --camera.loc.y = -camera.loc.y
  266.     local camRot = makeRotation(    getVecNeg(camera.rot) )
  267.     local camLoc = makeTranslation( getVecNeg(camera.loc) )
  268.    
  269.         --Transforms the entire object
  270.     local result = multiplyVerts(transMat, multiplyVerts(rotMat, multiplyVerts(scale, objectData.vertices)))
  271.     result = multiplyVerts(camRot, multiplyVerts(camLoc, result))
  272.     result = multiplyVerts(projMat, result)
  273.     --result = multiplyVerts(cam, result)
  274.         --Do backface culling test. If passed then load triangle into finalVectors{} table
  275.     local finalVectors = { colorList = {} }
  276.     for i = 1, #iL, 3 do
  277.         local i1,i2 = i+1, i+2
  278.         local vec1 = vector.new(result[iL[i]],  result[iL[i]+1],  result[iL[i]+2])
  279.         local vec2 = vector.new(result[iL[i1]], result[iL[i1]+1], result[iL[i1]+2])
  280.         local vec3 = vector.new(result[iL[i2]], result[iL[i2]+1], result[iL[i2]+2])
  281.             --backface culling test here
  282.         if (vec3:cross(vec2)):dot(vec1) >= 0 then
  283.             local len = #finalVectors
  284.                 --Assign W values
  285.             vec1.w = result[iL[i]+3]
  286.             vec2.w = result[iL[i1]+3]
  287.             vec3.w = result[iL[i2]+3]
  288.                 --Centers drawings, divides by W, aspect ratio correction
  289.             finalVectors[len+1] = processTriangle(vec1, display)
  290.             finalVectors[len+2] = processTriangle(vec2, display)
  291.             finalVectors[len+3] = processTriangle(vec3, display)
  292.            
  293.                 --Assign colors
  294.             finalVectors.colorList[ #finalVectors.colorList+1 ] = cL[(i+2)/3]
  295.             print(textutils.serialize(vec1))
  296.             print(textutils.serialize(vec2))
  297.             print(textutils.serialize(vec3))
  298.         end
  299.     end
  300.     return finalVectors
  301. end
  302.  
  303.     -- expose library functions
  304. return
  305. {
  306.     makeProjectionMat = makeProjectionMat,
  307.     screenTransform = screenTransform,
  308.     newCube = newCube,
  309.     newSqr = newSqr,
  310.     getPlayerData = getPlayerData,
  311.     makeDepthBuffer = makeDepthBuffer,
  312. }
Add Comment
Please, Sign In to add comment