incinirate

Matrix4f

Jun 2nd, 2016
107
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --Matrix4f = {}
  2. do
  3.   local Matrix4f = {} --_G.Matrix4f
  4.  
  5.   function Matrix4f.__init__()
  6.     local self = {}
  7.     self.m = {[0]={0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}
  8.     setmetatable(self, {__index=Matrix4f})
  9.     return self
  10.   end
  11.  
  12.   setmetatable(Matrix4f,{__call=Matrix4f.__init__})
  13.  
  14.   function Matrix4f:InitIdentity()
  15.     local m = self.m
  16.    
  17.     m[0][0] = 1;    m[0][1] = 0;    m[0][2] = 0;    m[0][3] = 0;
  18.         m[1][0] = 0;    m[1][1] = 1;    m[1][2] = 0;    m[1][3] = 0;
  19.         m[2][0] = 0;    m[2][1] = 0;    m[2][2] = 1;    m[2][3] = 0;
  20.         m[3][0] = 0;    m[3][1] = 0;    m[3][2] = 0;    m[3][3] = 1;
  21.    
  22.     return self
  23.   end
  24.  
  25.   function Matrix4f:InitScreenSpaceTransform(halfWidth, halfHeight)
  26.     local m = self.m
  27.    
  28.     m[0][0] = halfWidth;    m[0][1] = 0;    m[0][2] = 0;    m[0][3] = halfWidth;
  29.         m[1][0] = 0;    m[1][1] = -halfHeight;  m[1][2] = 0;    m[1][3] = halfHeight;
  30.         m[2][0] = 0;    m[2][1] = 0;    m[2][2] = 1;    m[2][3] = 0;
  31.         m[3][0] = 0;    m[3][1] = 0;    m[3][2] = 0;    m[3][3] = 1;
  32.    
  33.     return self
  34.   end
  35.  
  36.   function Matrix4f:InitTranslation(x,y,z)
  37.     local m = self.m
  38.    
  39.     m[0][0] = 1;    m[0][1] = 0;    m[0][2] = 0;    m[0][3] = x;
  40.         m[1][0] = 0;    m[1][1] = 1;    m[1][2] = 0;    m[1][3] = y;
  41.         m[2][0] = 0;    m[2][1] = 0;    m[2][2] = 1;    m[2][3] = z;
  42.         m[3][0] = 0;    m[3][1] = 0;    m[3][2] = 0;    m[3][3] = 1;
  43.    
  44.     return self
  45.   end
  46.  
  47.   function Matrix4f:InitRotation(x,y,z,angle)
  48.    
  49.     if type(x) == "number" then
  50.       if angle then
  51.         local m = self.m
  52.         local sin = math.sin(angle)
  53.         local cos = math.cos(angle)
  54.        
  55.         m[0][0] = cos+x*x*(1-cos); m[0][1] = x*y*(1-cos)-z*sin; m[0][2] = x*z*(1-cos)+y*sin; m[0][3] = 0;
  56.         m[1][0] = y*x*(1-cos)+z*sin; m[1][1] = cos+y*y*(1-cos); m[1][2] = y*z*(1-cos)-x*sin; m[1][3] = 0;
  57.         m[2][0] = z*x*(1-cos)-y*sin; m[2][1] = z*y*(1-cos)+x*sin; m[2][2] = cos+z*z*(1-cos); m[2][3] = 0;
  58.         m[3][0] = 0;    m[3][1] = 0;    m[3][2] = 0;    m[3][3] = 1;
  59.        
  60.         return self
  61.       else
  62.         local rx = Matrix4f()
  63.         local ry = Matrix4f()
  64.         local rz = Matrix4f()
  65.        
  66.         local math = math
  67.        
  68.         rz.m[0][0] = math.cos(z);rz.m[0][1] = -math.sin(z);rz.m[0][2] = 0;              rz.m[0][3] = 0;
  69.         rz.m[1][0] = math.sin(z);rz.m[1][1] = math.cos(z);rz.m[1][2] = 0;                   rz.m[1][3] = 0;
  70.         rz.m[2][0] = 0;                 rz.m[2][1] = 0;                 rz.m[2][2] = 1;                 rz.m[2][3] = 0;
  71.         rz.m[3][0] = 0;                 rz.m[3][1] = 0;                 rz.m[3][2] = 0;                 rz.m[3][3] = 1;
  72.  
  73.         rx.m[0][0] = 1;                 rx.m[0][1] = 0;                 rx.m[0][2] = 0;                 rx.m[0][3] = 0;
  74.         rx.m[1][0] = 0;                 rx.m[1][1] = math.cos(x);rx.m[1][2] = -math.sin(x);rx.m[1][3] = 0;
  75.         rx.m[2][0] = 0;                 rx.m[2][1] = math.sin(x);rx.m[2][2] = math.cos(x);rx.m[2][3] = 0;
  76.         rx.m[3][0] = 0;                 rx.m[3][1] = 0;                 rx.m[3][2] = 0;                 rx.m[3][3] = 1;
  77.  
  78.         ry.m[0][0] = math.cos(y);ry.m[0][1] = 0;                    ry.m[0][2] = -math.sin(y);ry.m[0][3] = 0;
  79.         ry.m[1][0] = 0;                 ry.m[1][1] = 1;                 ry.m[1][2] = 0;                 ry.m[1][3] = 0;
  80.         ry.m[2][0] = math.sin(y);ry.m[2][1] = 0;                    ry.m[2][2] = math.cos(y);ry.m[2][3] = 0;
  81.         ry.m[3][0] = 0;                 ry.m[3][1] = 0;                 ry.m[3][2] = 0;                 ry.m[3][3] = 1;
  82.  
  83.         self.m = rz:Mul(ry:Mul(rx)):GetM();
  84.        
  85.         return self
  86.       end
  87.     else
  88.       local forward = x
  89.       local up = y
  90.       local right = z
  91.       if right then
  92.         local m = self.m
  93.        
  94.         local f = forward
  95.         local r = right
  96.         local u = up
  97.        
  98.         m[0][0] = r:GetX(); m[0][1] = r:GetY(); m[0][2] = r:GetZ(); m[0][3] = 0;
  99.         m[1][0] = u:GetX(); m[1][1] = u:GetY(); m[1][2] = u:GetZ(); m[1][3] = 0;
  100.         m[2][0] = f:GetX(); m[2][1] = f:GetY(); m[2][2] = f:GetZ(); m[2][3] = 0;
  101.         m[3][0] = 0;        m[3][1] = 0;        m[3][2] = 0;        m[3][3] = 1;
  102.        
  103.         return self
  104.       else
  105.         local f = forward:Normalized()
  106.        
  107.         local r = up:Normalized()
  108.         r = r:Cross(f)
  109.        
  110.         local u = f:Cross(r)
  111.        
  112.         return self:InitRotation(f, u, r)
  113.       end
  114.     end
  115.   end
  116.  
  117.   function Matrix4f:InitScale(x,y,z)
  118.     local m = self.m
  119.    
  120.     m[0][0] = x;    m[0][1] = 0;    m[0][2] = 0;    m[0][3] = 0;
  121.         m[1][0] = 0;    m[1][1] = y;    m[1][2] = 0;    m[1][3] = 0;
  122.         m[2][0] = 0;    m[2][1] = 0;    m[2][2] = z;    m[2][3] = 0;
  123.         m[3][0] = 0;    m[3][1] = 0;    m[3][2] = 0;    m[3][3] = 1;
  124.    
  125.     return self
  126.   end
  127.  
  128.   function Matrix4f:InitPerspective(fov, aspectRatio, zNear, zFar)
  129.     local tanHalfFOV = math.tan(fov/2)
  130.     local zRange = zNear - zFar
  131.    
  132.     local m = self.m
  133.    
  134.     m[0][0] = 1.0f / (tanHalfFOV * aspectRatio);    m[0][1] = 0;                    m[0][2] = 0;    m[0][3] = 0;
  135.         m[1][0] = 0;                        m[1][1] = 1.0f / tanHalfFOV;    m[1][2] = 0;    m[1][3] = 0;
  136.         m[2][0] = 0;                        m[2][1] = 0;                    m[2][2] = (-zNear -zFar)/zRange;    m[2][3] = 2 * zFar * zNear / zRange;
  137.         m[3][0] = 0;                        m[3][1] = 0;                    m[3][2] = 1;    m[3][3] = 0;
  138.    
  139.     return self
  140.   end
  141.  
  142.   function Matrix4f:InitOrthographic(left, right, bottom, top, near, far)
  143.     local width = right - left
  144.     local height = top - bottom
  145.     local depth = far - near
  146.    
  147.     local m = self.m
  148.    
  149.     m[0][0] = 2/width;m[0][1] = 0;  m[0][2] = 0;    m[0][3] = -(right + left)/width;
  150.         m[1][0] = 0;    m[1][1] = 2/height;m[1][2] = 0; m[1][3] = -(top + bottom)/height;
  151.         m[2][0] = 0;    m[2][1] = 0;    m[2][2] = -2/depth;m[2][3] = -(far + near)/depth;
  152.         m[3][0] = 0;    m[3][1] = 0;    m[3][2] = 0;    m[3][3] = 1;
  153.    
  154.     return self
  155.   end
  156.  
  157.   function Matrix4f:Transform(r)
  158.     local m = self.m
  159.     return Vector4f(m[0][0] * r:GetX() + m[0][1] * r:GetY() + m[0][2] * r:GetZ() + m[0][3] * r:GetW(),
  160.                             m[1][0] * r:GetX() + m[1][1] * r:GetY() + m[1][2] * r:GetZ() + m[1][3] * r:GetW(),
  161.                             m[2][0] * r:GetX() + m[2][1] * r:GetY() + m[2][2] * r:GetZ() + m[2][3] * r:GetW(),
  162.                             m[3][0] * r:GetX() + m[3][1] * r:GetY() + m[3][2] * r:GetZ() + m[3][3] * r:GetW());
  163.   end
  164.  
  165.   function Matrix4f:Mul(r)
  166.     local res = Matrix4f()
  167.     local m = self.m
  168.    
  169.     for i=0,3 do
  170.       for j=0,3 do
  171.         res:Set(i, j, m[i][0] * r:Get(0, j) +
  172.                         m[i][1] * r:Get(1, j) +
  173.                         m[i][2] * r:Get(2, j) +
  174.                         m[i][3] * r:Get(3, j));
  175.       end
  176.     end
  177.    
  178.     return res
  179.   end
  180.  
  181.   function Matrix4f:GetM()
  182.     local res = {[0]={0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}
  183.     local m = self.m
  184.    
  185.     for i=0,3 do
  186.       for j=0,3 do
  187.         res[i][j] = m[i][j]
  188.       end
  189.     end
  190.    
  191.     return res
  192.   end
  193.  
  194.   function Matrix4f:Get(x,y)
  195.     return self.m[x][y]
  196.   end
  197.  
  198.   function Matrix4f:SetM(m)
  199.     self.m = m
  200.   end
  201.  
  202.   function Matrix4f:Set(x,y,value)
  203.     self.m[x][y]=value
  204.   end
  205.  
  206.   return Matrix4f
  207. end
RAW Paste Data