Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- 3D tools API
- local function getPlayerData(playerName) --Get a target players position and rotation
- local result = { rot = {}, loc = {} }
- local _, rot = commands.exec("data get entity "..playerName.." Rotation")
- for i in string.gmatch(rot[1], "%-?%d+%.%d+") do
- result.rot[ #result.rot + 1 ] = i
- end
- local _, loc = commands.exec("data get entity "..playerName.." Pos")
- for i in string.gmatch(loc[1], "%-?%d+%.%d+") do
- result.loc[ #result.loc + 1 ] = i
- end
- local playerData = {}
- --I put them into vector format with {x= , y= , z= } because that's what our matrices use
- --Offset by 1.62 because minecraft gets location based on feet, and camera is 1.62 blocks high
- playerData.loc = vector.new(result.loc[1],result.loc[2]+1.62,result.loc[3])
- --Rotation X / Y are swapped because minecraft returns Y, X instead of X, Y
- playerData.rot = vector.new(result.rot[2],result.rot[1],0)
- return playerData
- end
- --Math functions
- --Multiply a given matrix by every vertice in given verts table
- local function multiplyVerts(mat, vert) --m == matrix, v == vertice list
- if #mat ~= 16 then
- error("Matrix must have length of 16 (4x4 matrix)")
- end
- local result = {}
- for i = 1, #vert, 4 do --Iterate through each vertice
- for k = 1, 4 do --Multiply said vertice by the given matrix. result[1 -> 4] are equal to a 4x1 matrix.
- 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] )
- end
- end
- return result
- end
- local function getVecNeg(vec)
- return {
- x = -vec.x,
- y = -vec.y,
- z = -vec.z,
- }
- end
- --Makes an empty depth buffer using display size. Use this ONCE PER DISPLAY, BEFORE your main loop.
- --Then set another var in the loop to this so you aren't constantly re-making it, just grabbing an empty copy
- local function makeDepthBuffer(display)
- local depthBuffer = { size = { x = display.x, y = display.y } }
- for y = 1, display.y do
- for w = 1, display.x do
- depthBuffer[((y*display.x) + w)] = math.huge
- end
- end
- return depthBuffer
- end
- --Special matrix generators
- local function makeIdentity()
- return {
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1, }
- end
- local function makeProjectionMat(fov,n,f)
- local s = 1/(math.tan((fov/2)*(3.14/180)))
- return {
- s, 0, 0, 0,
- 0, s, 0, 0,
- 0, 0, -f/(f-n), -1,
- 0, 0, -f*n/(f-n), 0
- }
- end
- --[[
- local function makeProjectionMat(n,f,t,b,l,r)
- return {
- 2*n/(r-l), 0, (r+l)/(r-l), 0,
- 0, 2*n/(t-b), (t+b)/(t-b), 0,
- 0, 0, -((f+n)/(f-n)), -(2*f*n/(f-n)),
- 0, 0, -1, 0 }
- end
- ]]
- local function makeRotation(eulers)
- local x = math.rad(eulers.x)
- local y = math.rad(eulers.y)
- local z = math.rad(eulers.z)
- local sx = math.sin(x)
- local sy = math.sin(y)
- local sz = math.sin(z)
- local cx = math.cos(x)
- local cy = math.cos(y)
- local cz = math.cos(z)
- return
- {
- cy * cz, -cy * sz, sy, 0,
- (sx * sy * cz) + (cx * sz), (-sx * sy * sz) + (cx * cz), -sx * cy, 0,
- (-cx * sy * cz) + (sx * sz), (cx * sy * sz) + (sx * cz), cx * cy, 0,
- 0, 0, 0, 1, }
- end
- local function makeTranslation(translation)
- return
- {
- 1, 0, 0, translation.x,
- 0, 1, 0, translation.y,
- 0, 0, 1, translation.z,
- 0, 0, 0, 1, }
- end
- local function makeScale(scale)
- return
- {
- scale.x, 0, 0, 0,
- 0, scale.y, 0, 0,
- 0, 0, scale.z, 0,
- 0, 0, 0, 1 }
- end
- --Makes a camera matrix for matrix multiplication. Not a camera that is used by the player
- local function makeCamera(cam)
- local up = vector.new(0,1,0)
- local p = getVecNeg(cam.loc) --position
- p.z = -p.z
- local pitch = math.rad(cam.rot.x)
- local yaw = math.rad(cam.rot.y)
- local x = -math.sin(yaw) * math.cos(pitch)
- local z = math.cos(yaw) * math.cos(pitch)
- local y = -math.sin(pitch)
- local f = (vector.new(x,y,z)):normalize() --forward
- local r = (up:cross(f)):normalize()
- --[[
- return {
- r.x, r.y, r.z, 0,
- 0, 1, 0, 0,
- f.x, f.y, f.z, 0,
- p.x, p.y, p.z, 1,
- }
- ]]
- return {
- r.x, 0, f.x, p.x,
- r.y, 1, f.y, p.y,
- r.z, 0, f.z, p.z,
- 0, 0, 0, 1,
- }
- end
- --Returns data of default cube
- local function newCube()
- local objData = {
- --Matrix values
- scale = vector.new(1,1,1), --Scale of model
- loc = vector.new(0,0,0), --Location of model
- rot = vector.new(0,0,0), --Rotation of model
- --define the colors of each triangle in hexidecimal
- colorList = {
- 0xBA1F33, 0xCD5D67,
- 0xF2A65A, 0xEEC170,
- 0x46B1C9, 0x84C0C6,
- 0xBFACB5, 0xE5D0CC,
- 0xF564A9, 0xFAA4BD,
- 0x8CD790, 0xAAFCB8,
- },
- indexList = {
- --1 face, composed of 2 triangles, each defined by 3 points.
- --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
- 1,3,2, 3,4,2,
- 2,4,6, 4,8,6,
- 3,7,4, 7,8,4,
- 6,8,5, 8,7,5,
- 5,7,1, 7,3,1,
- 5,1,6, 1,2,6, },
- --Each possible vertice for the indexList to point to
- vertices = { --4x1 matrix structure for each vertex.
- -0.5, -0.5, -0.5, 1,
- 0.5, -0.5, -0.5, 1,
- -0.5, 0.5, -0.5, 1,
- 0.5, 0.5, -0.5, 1,
- -0.5, -0.5, 0.5, 1,
- 0.5, -0.5, 0.5, 1,
- -0.5, 0.5, 0.5, 1,
- 0.5, 0.5, 0.5, 1, }
- }
- for i,val in ipairs(objData.indexList) do
- objData.indexList[i] = val*4-3
- end
- return objData
- end
- --Returns data of default square
- local function newSqr() --Refer to newCube() for comments
- local objData = {
- scale = vector.new(1,1,1),
- loc = vector.new(0,0,0),
- rot = vector.new(0,0,0),
- colorList = { 0xE56399, 0x7F96FF, },
- indexList = { 1,3,2, 3,4,2, },
- vertices = {
- -0.5, -0.5, -0.5, 1,
- 0.5, -0.5, -0.5, 1,
- -0.5, 0.5, -0.5, 1,
- 0.5, 0.5, -0.5, 1, } }
- for i,val in ipairs(objData.indexList) do
- objData.indexList[i] = val*4-3
- end
- return objData
- end
- --Centers drawings, divides by Z, multiplies X by aspect ratio
- --takes in a vector (v) with 4 values (x,y,z,w) and info about the display (x,y)
- local function processTriangle(v,display)
- --Geometry shader here
- --Post process stuff here
- local xFactor = display.y*0.5 --half height
- local yFactor = display.x*0.5 --half width
- v.w = v.z
- v.w = (1/v.w)
- v.x = (v.x * v.w +1) * xFactor
- v.y = (-v.y * v.w +1) * yFactor
- v.z = v.z * v.w
- return v
- end
- --Takes in an entire object and returns transformed vertices and a cullFlag list
- --Need to switch to making a MVP and Camera(?)World(?) mat then multiplying
- local function screenTransform(objectData,display,camera,projMat)
- local iL = objectData.indexList
- local cL = objectData.colorList
- local scale = makeScale(objectData.scale)
- local rotMat = makeRotation(objectData.rot)
- local transMat = makeTranslation(objectData.loc)
- --projMat = makeIdentity()
- --local cam = makeCamera(camera)
- --We get the negative of the vectors b/c they need to move/rotatate the world opposite of them
- --camera.loc.z = camera.loc.z
- --camera.loc.y = -camera.loc.y
- local camRot = makeRotation( getVecNeg(camera.rot) )
- local camLoc = makeTranslation( getVecNeg(camera.loc) )
- --Transforms the entire object
- local result = multiplyVerts(transMat, multiplyVerts(rotMat, multiplyVerts(scale, objectData.vertices)))
- result = multiplyVerts(camRot, multiplyVerts(camLoc, result))
- result = multiplyVerts(projMat, result)
- --result = multiplyVerts(cam, result)
- --Do backface culling test. If passed then load triangle into finalVectors{} table
- local finalVectors = { colorList = {} }
- for i = 1, #iL, 3 do
- local i1,i2 = i+1, i+2
- local vec1 = vector.new(result[iL[i]], result[iL[i]+1], result[iL[i]+2])
- local vec2 = vector.new(result[iL[i1]], result[iL[i1]+1], result[iL[i1]+2])
- local vec3 = vector.new(result[iL[i2]], result[iL[i2]+1], result[iL[i2]+2])
- --backface culling test here
- if (vec3:cross(vec2)):dot(vec1) >= 0 then
- local len = #finalVectors
- --Assign W values
- vec1.w = result[iL[i]+3]
- vec2.w = result[iL[i1]+3]
- vec3.w = result[iL[i2]+3]
- --Centers drawings, divides by W, aspect ratio correction
- finalVectors[len+1] = processTriangle(vec1, display)
- finalVectors[len+2] = processTriangle(vec2, display)
- finalVectors[len+3] = processTriangle(vec3, display)
- --Assign colors
- finalVectors.colorList[ #finalVectors.colorList+1 ] = cL[(i+2)/3]
- print(textutils.serialize(vec1))
- print(textutils.serialize(vec2))
- print(textutils.serialize(vec3))
- end
- end
- return finalVectors
- end
- -- expose library functions
- return
- {
- makeProjectionMat = makeProjectionMat,
- screenTransform = screenTransform,
- newCube = newCube,
- newSqr = newSqr,
- getPlayerData = getPlayerData,
- makeDepthBuffer = makeDepthBuffer,
- }
Add Comment
Please, Sign In to add comment