Advertisement
MarkFergus

terminal glasses (3D)

Aug 24th, 2023 (edited)
1,175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.37 KB | None | 0 0
  1. -- Main program
  2.  
  3. local p = peripheral.find("openperipheral_bridge")
  4. local s = peripheral.find("openperipheral_sensor")
  5.  
  6. function vec3d(x,y,z,w)
  7.   if w == nil then w=1 end
  8.   T = {}
  9.   T.x, T.y, T.z, T.w = x,y,z,w
  10.   return T
  11. end
  12.  
  13. function triangle(a,b,c)
  14.   T = {}
  15.   T[1], T[2], T[3] = a,b,c
  16.   return T
  17. end
  18.  
  19. function mat4x4()
  20.   M = {}
  21.   for i=1,4 do
  22.     M[i] = {0,0,0,0}
  23.   end
  24.   return M
  25. end
  26.  
  27. function Vector_Add(vec1,vec2)
  28.   return vec3d(vec1.x + vec2.x , vec1.y + vec2.y, vec1.z + vec2.z)
  29. end
  30.  
  31. function Vector_Sub(vec1,vec2)
  32.   return vec3d(vec1.x - vec2.x , vec1.y - vec2.y, vec1.z - vec2.z)
  33. end
  34.  
  35. function Vector_Mul(f,vec1)
  36.   return vec3d(f*vec1.x,f*vec1.y,f*vec1.z)
  37. end
  38.  
  39. function Vector_Div(vec1,f)
  40.   return vec3d(vec1.x/f,vec1.y/f,vec1.z/f)
  41. end
  42.  
  43. function Vector_DotProduct(v1,v2)
  44.   return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z
  45. end
  46.  
  47. function Vector_Length(v)
  48.   return math.sqrt(Vector_DotProduct(v,v))
  49. end
  50.  
  51. function Vector_Normalise(v)
  52.   local l = Vector_Length(v)
  53.   if l ~= 0 then
  54.     return vec3d(v.x/l, v.y/l, v.z/l)
  55.   else
  56.     return v
  57.   end
  58. end
  59.  
  60. function Vector_CrossProduct(line1,line2)
  61.     return vec3d(line1.y*line2.z - line1.z*line2.y,
  62.                  line1.z*line2.x - line1.x*line2.z,
  63.                  line1.x*line2.y - line1.y*line2.x)
  64. end
  65.  
  66. function Matrix_MakeIdentity()
  67.   matrix = mat4x4()
  68.   for i=1,4 do
  69.     matrix[i][i] = 1
  70.   end
  71.   return matrix
  72. end
  73.  
  74. function Matrix_MakeProjection(fFovDegrees, fAspectRatio, fNear, fFar)
  75.   local fFovRad = 1 / math.tan(math.rad(fFovDegrees) * 0.5)
  76.   local matrix = mat4x4()
  77.   matrix[1][1] = fAspectRatio * fFovRad
  78.   matrix[2][2] = fFovRad
  79.   matrix[3][3] = fFar / (fFar - fNear)
  80.   matrix[4][3] = (-fFar * fNear) / (fFar - fNear)
  81.   matrix[3][4] = 1
  82.   matrix[4][4] = 0
  83.   return matrix
  84. end
  85.  
  86. local chars = {'x','y','z'}
  87.  
  88. function Matrix_MultiplyVector(i,m)
  89.   v = vec3d(0,0,0,0)
  90.   v.x = i.x * m[1][1] + i.y * m[2][1] + i.z * m[3][1] + i.w * m[4][1]
  91.   v.y = i.x * m[1][2] + i.y * m[2][2] + i.z * m[3][2] + i.w * m[4][2]
  92.   v.z = i.x * m[1][3] + i.y * m[2][3] + i.z * m[3][3] + i.w * m[4][3]
  93.   v.w = i.x * m[1][4] + i.y * m[2][4] + i.z * m[3][4] + i.w * m[4][4]
  94.   return v
  95. end
  96.  
  97. function Matrix_MakeRotationZ(theta)
  98.   matrix = mat4x4()
  99.   matrix[1][1] = math.cos(theta)
  100.   matrix[1][2] = math.sin(theta)
  101.   matrix[2][1] = -math.sin(theta)
  102.   matrix[2][2] = math.cos(theta)
  103.   matrix[3][3] = 1
  104.   matrix[4][4] = 1
  105.   return matrix
  106. end
  107.  
  108. function Matrix_MakeRotationY(theta)
  109.   local matrix = mat4x4()
  110.   matrix[1][1] = math.cos(theta)
  111.   matrix[1][3] = math.sin(theta)
  112.   matrix[2][2] = 1
  113.   matrix[3][1] = -math.sin(theta)
  114.   matrix[3][3] = math.cos(theta)
  115.   matrix[4][4] = 1
  116.   return matrix
  117. end
  118.  
  119.  
  120. function Matrix_MakeRotationX(theta)
  121.   local matrix = mat4x4()
  122.   matrix[1][1] = 1
  123.   matrix[2][2] = math.cos(theta)
  124.   matrix[2][3] = math.sin(theta)
  125.   matrix[3][2] = -math.sin(theta)
  126.   matrix[3][3] = math.cos(theta)
  127.   matrix[4][4] = 1
  128.   return matrix
  129. end
  130.  
  131. function Matrix_Add(m1,m2)
  132.   m = mat4x4()
  133.   for c=1,4 do
  134.     for r=1,4 do
  135.       m[r][c] = m1[r][c] + m2[r][c]
  136.     end
  137.   end
  138. end
  139.  
  140. function Matrix_MultiplyMatrix(m1,m2)
  141.   matrix = mat4x4()
  142.   for c=1,4 do
  143.     for r=1,4 do
  144.       matrix[r][c] = m1[r][1] * m2[1][c] + m1[r][2] * m2[2][c] + m1[r][3] * m2[3][c] + m1[r][4] * m2[4][c]
  145.     end
  146.   end
  147.   return matrix
  148. end
  149.  
  150. function Matrix_PointAt(pos,target,up)
  151.   -- Calculate a new forward direction
  152.   newForward = Vector_Sub(target,pos)
  153.   newForward = Vector_Normalise(newForward)
  154.  
  155.   -- Calculate a new Up direction
  156.   a = Vector_Mul(Vector_DotProduct(up,newForward), newForward)
  157.   newUp = Vector_Sub(up,a)
  158.   newUp = Vector_Normalise(newUp)
  159.  
  160.   -- New right direction is easy, it's just a crossproduct from up and forward directions
  161.   newRight = Vector_CrossProduct(newUp,(newForward))
  162.   local matrix = mat4x4()
  163.   matrix[1][1] = newRight.x   matrix[1][2] = newRight.y   matrix[1][3] = newRight.z   matrix[1][4] = 0
  164.   matrix[2][1] = newUp.x      matrix[2][2] = newUp.y      matrix[2][3] = newUp.z      matrix[2][4] = 0
  165.   matrix[3][1] = newForward.x matrix[3][2] = newForward.y matrix[3][3] = newForward.z matrix[3][4] = 0
  166.   matrix[4][1] = pos.x        matrix[4][2] = pos.y        matrix[4][3] = pos.z        matrix[4][4] = 1
  167.   return matrix
  168. end
  169.  
  170. function Matrix_QuickInverse(m)
  171.   local matrix = mat4x4()
  172.   matrix[1][1] = m[1][1] matrix[1][2] = m[2][1] matrix[1][3] = m[3][1] matrix[1][4] = 0
  173.   matrix[2][1] = m[1][2] matrix[2][2] = m[2][2] matrix[2][3] = m[3][2] matrix[2][4] = 0
  174.   matrix[3][1] = m[1][3] matrix[3][2] = m[2][3] matrix[3][3] = m[3][3] matrix[3][4] = 0
  175.   matrix[4][1] = -(m[4][1] * matrix[1][1] + m[4][2] * matrix[2][1] + m[4][3] * matrix[3][1])
  176.   matrix[4][2] = -(m[4][1] * matrix[1][2] + m[4][2] * matrix[2][2] + m[4][3] * matrix[3][2])
  177.   matrix[4][3] = -(m[4][1] * matrix[1][3] + m[4][2] * matrix[2][3] + m[4][3] * matrix[3][3])
  178.   matrix[4][4] = 1
  179.   return matrix
  180. end
  181.  
  182. function Matrix_MakeTranslation(x,y,z)
  183.   local matrix = Matrix_MakeIdentity()
  184.   matrix[4][1] = x
  185.   matrix[4][2] = y
  186.   matrix[4][3] = z
  187.   return matrix
  188. end
  189.  
  190. function projectCube(theta)
  191.   matRotX = Matrix_MakeRotationX(theta)
  192.   matRotY = Matrix_MakeRotationY(0)
  193.   matRotZ = Matrix_MakeRotationZ(theta*0.5)
  194.  
  195.   matCenterTrans = Matrix_MakeTranslation(-0.5,-0.5,-0.5)
  196.   matTrans = Matrix_MakeTranslation(0,0,16)
  197.  
  198.   matWorld = Matrix_MakeIdentity()
  199.   matWorld = Matrix_MultiplyMatrix(matRotZ,matRotX)
  200.   matWorld = Matrix_MultiplyMatrix(matWorld,matTrans)
  201.  
  202.   vUp = vec3d(0,1,0)
  203.   vTarget = vec3d(0,0,1)
  204.   matCameraRot = Matrix_MakeRotationY(math.rad(fYaw))
  205.   vLookDir = Matrix_MultiplyVector(vTarget,matCameraRot)
  206.   vTarget = Vector_Add(vCamera, vLookDir)
  207.  
  208.   matCamera = Matrix_PointAt(vCamera,vTarget,vUp)
  209.  
  210.   -- Make View matrix for camera
  211.   matView = Matrix_QuickInverse(matCamera)
  212.  
  213.   matProj = Matrix_MakeProjection(120,1,1,1000)
  214.  
  215.   for i=1,#meshCube do
  216.     triTransformed = triangle(vec3d(0,0,0),vec3d(0,0,0),vec3d(0,0,0))
  217.     triProjected =   triangle(vec3d(0,0,0),vec3d(0,0,0),vec3d(0,0,0))
  218.     triViewed =      triangle(vec3d(0,0,0),vec3d(0,0,0),vec3d(0,0,0))
  219.     pack = {}
  220.  
  221.     -- Ajustement au centre de rotation, transformation et projection
  222.     triTransformed[1] = Matrix_MultiplyVector(meshCube[i][1],matCenterTrans)
  223.     triTransformed[2] = Matrix_MultiplyVector(meshCube[i][2],matCenterTrans)
  224.     triTransformed[3] = Matrix_MultiplyVector(meshCube[i][3],matCenterTrans)
  225.     triTransformed[1] = Matrix_MultiplyVector(triTransformed[1],matWorld)
  226.     triTransformed[2] = Matrix_MultiplyVector(triTransformed[2],matWorld)
  227.     triTransformed[3] = Matrix_MultiplyVector(triTransformed[3],matWorld)
  228.    
  229.     -- Determine le vecteur normale au triangle
  230.     line1,line2,normal = vec3d(0,0,0),vec3d(0,0,0),vec3d(0,0,0)
  231.     line1 = Vector_Sub(triTransformed[2], triTransformed[1])
  232.     line2 = Vector_Sub(triTransformed[3], triTransformed[1])
  233.     normal = Vector_CrossProduct(line1,line2)
  234.     normal = Vector_Normalise(normal)
  235.  
  236.     -- Get Ray from Triangle to camera
  237.     vCameraRay = Vector_Sub(triTransformed[1], vCamera)
  238.  
  239.     if (Vector_DotProduct(normal,vCameraRay) < 0) then
  240.       -- Illumination
  241.       light_direction = vec3d(0,0,-1)
  242.       light_direction = Vector_Normalise(light_direction)
  243.  
  244.       -- How "aligned" are light direction and triangle surface normal ?
  245.       dp = Vector_DotProduct(light_direction,normal)
  246.      
  247.       -- Convert World Space --> View Space
  248.       triViewed[1] = Matrix_MultiplyVector(triTransformed[1],matView)
  249.       triViewed[2] = Matrix_MultiplyVector(triTransformed[2],matView)
  250.       triViewed[3] = Matrix_MultiplyVector(triTransformed[3],matView)
  251.  
  252.       -- Projection triangles from 3D --> 2D
  253.       triProjected[1] = Matrix_MultiplyVector(triViewed[1],matProj)
  254.       triProjected[2] = Matrix_MultiplyVector(triViewed[2],matProj)
  255.       triProjected[3] = Matrix_MultiplyVector(triViewed[3],matProj)
  256.       triProjected[1] = Vector_Div(triProjected[1], triProjected[1].w)
  257.       triProjected[2] = Vector_Div(triProjected[2], triProjected[2].w)
  258.       triProjected[3] = Vector_Div(triProjected[3], triProjected[3].w)
  259.  
  260.       -- Mise a l'echelle
  261.       for i=1,3 do
  262.         pack[i] = {}
  263.         pack[i].x = math.ceil((triProjected[i].x + 1) * 0.5*width) - 10
  264.         pack[i].y = math.ceil((triProjected[i].y + 1) * 0.5*height) - 315
  265.       end
  266.  
  267.       -- Affichage
  268.       p.addPolygon(0xFFFFFF,dp,pack[1],pack[2],pack[3])
  269.     end
  270.   end
  271.   p.sync()
  272. end
  273. meshCube = {
  274.   -- SOUTH
  275.   triangle(vec3d(0,0,0),vec3d(0,1,0),vec3d(1,1,0)),
  276.   triangle(vec3d(0,0,0),vec3d(1,1,0),vec3d(1,0,0)),
  277.   -- EAST
  278.   triangle(vec3d(1,0,0),vec3d(1,1,0),vec3d(1,1,1)),
  279.   triangle(vec3d(1,0,0),vec3d(1,1,1),vec3d(1,0,1)),
  280.   -- NORTH
  281.   triangle(vec3d(1,0,1),vec3d(1,1,1),vec3d(0,1,1)),
  282.   triangle(vec3d(1,0,1),vec3d(0,1,1),vec3d(0,0,1)),
  283.   -- WEST
  284.   triangle(vec3d(0,0,1),vec3d(0,1,1),vec3d(0,1,0)),
  285.   triangle(vec3d(0,0,1),vec3d(0,1,0),vec3d(0,0,0)),
  286.   -- TOP
  287.   triangle(vec3d(0,1,0),vec3d(0,1,1),vec3d(1,1,1)),
  288.   triangle(vec3d(0,1,0),vec3d(1,1,1),vec3d(1,1,0)),
  289.   -- BOTTOM
  290.   triangle(vec3d(1,0,1),vec3d(0,0,1),vec3d(0,0,0)),
  291.   triangle(vec3d(1,0,1),vec3d(0,0,0),vec3d(1,0,0))
  292. }
  293.  
  294. vCamera = vec3d(0,0,0)
  295. width =   1300
  296. height =  1300
  297. fYaw = 0
  298. theta = 0
  299.  
  300. while true do
  301.   if cube ~= nil then
  302.     cube.delete()
  303.   end
  304.   player = s.getPlayerByName("MarkFergus")
  305.   data = player.all()
  306.   fYaw = data.living.yaw
  307.   p.clear()
  308.   --theta = theta+0.05
  309.   cube = projectCube(theta)
  310.   sleep(0.02)
  311. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement