CapsAdmin

Untitled

Nov 30th, 2013
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.90 KB | None | 0 0
  1. -- ported from https://github.com/evanw/lightgl.js/blob/master/src/matrix.js
  2.  
  3. -- Represents a 4x4 matrix stored in row-major order that uses Float32Arrays
  4. -- when available. Matrix operations can either be done using convenient
  5. -- methods that return a new matrix for the result or optimized methods
  6. -- that store the result in an existing matrix to avoid generating garbage.
  7.  
  8. -- ### .transformPoint(point)
  9. --
  10. -- Transforms the vector as a point with a w coordinate of 1. This
  11. -- means translations will have an effect, for example.
  12. local function matrix_transform_point(matrix, v)
  13.     local m = matrix.m;
  14.    
  15.     return Vec3(
  16.         m[0] * v.x + m[1] * v.y + m[2] * v.z + m[3],
  17.         m[4] * v.x + m[5] * v.y + m[6] * v.z + m[7],
  18.         m[8] * v.x + m[9] * v.y + m[10] * v.z + m[11]
  19.     ) / (m[12] * v.x + m[13] * v.y + m[14] * v.z + m[15]);
  20. end
  21.  
  22. -- ### .transformPoint(vector)
  23. --
  24. -- Transforms the vector as a vector with a w coordinate of 0. This
  25. -- means translations will have no effect, for example.
  26. local function matrix_transform_vector(matrix, v)
  27.     local m = matrix.m;
  28.    
  29.     return Vec3(
  30.         m[0] * v.x + m[1] * v.y + m[2] * v.z,
  31.         m[4] * v.x + m[5] * v.y + m[6] * v.z,
  32.         m[8] * v.x + m[9] * v.y + m[10] * v.z
  33.     );
  34. end
  35.  
  36. -- ### GL.Matrix.inverse(matrix[, result])
  37. --
  38. -- Returns the matrix that when multiplied with `matrix` results in the
  39. -- identity matrix. You can optionally pass an existing matrix in `result`
  40. -- to avoid allocating a new matrix. This implementation is from the Mesa
  41. -- OpenGL function `__gluInvertMatrixd()` found in `project.c`.
  42. local function matrix_inverse(matrix, result)
  43.     result = result or Matrix44();
  44.     local m = matrix.m
  45.     local r = result.m
  46.  
  47.     r[0] = m[5]*m[10]*m[15] - m[5]*m[14]*m[11] - m[6]*m[9]*m[15] + m[6]*m[13]*m[11] + m[7]*m[9]*m[14] - m[7]*m[13]*m[10];
  48.     r[1] = -m[1]*m[10]*m[15] + m[1]*m[14]*m[11] + m[2]*m[9]*m[15] - m[2]*m[13]*m[11] - m[3]*m[9]*m[14] + m[3]*m[13]*m[10];
  49.     r[2] = m[1]*m[6]*m[15] - m[1]*m[14]*m[7] - m[2]*m[5]*m[15] + m[2]*m[13]*m[7] + m[3]*m[5]*m[14] - m[3]*m[13]*m[6];
  50.     r[3] = -m[1]*m[6]*m[11] + m[1]*m[10]*m[7] + m[2]*m[5]*m[11] - m[2]*m[9]*m[7] - m[3]*m[5]*m[10] + m[3]*m[9]*m[6];
  51.  
  52.     r[4] = -m[4]*m[10]*m[15] + m[4]*m[14]*m[11] + m[6]*m[8]*m[15] - m[6]*m[12]*m[11] - m[7]*m[8]*m[14] + m[7]*m[12]*m[10];
  53.     r[5] = m[0]*m[10]*m[15] - m[0]*m[14]*m[11] - m[2]*m[8]*m[15] + m[2]*m[12]*m[11] + m[3]*m[8]*m[14] - m[3]*m[12]*m[10];
  54.     r[6] = -m[0]*m[6]*m[15] + m[0]*m[14]*m[7] + m[2]*m[4]*m[15] - m[2]*m[12]*m[7] - m[3]*m[4]*m[14] + m[3]*m[12]*m[6];
  55.     r[7] = m[0]*m[6]*m[11] - m[0]*m[10]*m[7] - m[2]*m[4]*m[11] + m[2]*m[8]*m[7] + m[3]*m[4]*m[10] - m[3]*m[8]*m[6];
  56.  
  57.     r[8] = m[4]*m[9]*m[15] - m[4]*m[13]*m[11] - m[5]*m[8]*m[15] + m[5]*m[12]*m[11] + m[7]*m[8]*m[13] - m[7]*m[12]*m[9];
  58.     r[9] = -m[0]*m[9]*m[15] + m[0]*m[13]*m[11] + m[1]*m[8]*m[15] - m[1]*m[12]*m[11] - m[3]*m[8]*m[13] + m[3]*m[12]*m[9];
  59.     r[10] = m[0]*m[5]*m[15] - m[0]*m[13]*m[7] - m[1]*m[4]*m[15] + m[1]*m[12]*m[7] + m[3]*m[4]*m[13] - m[3]*m[12]*m[5];
  60.     r[11] = -m[0]*m[5]*m[11] + m[0]*m[9]*m[7] + m[1]*m[4]*m[11] - m[1]*m[8]*m[7] - m[3]*m[4]*m[9] + m[3]*m[8]*m[5];
  61.  
  62.     r[12] = -m[4]*m[9]*m[14] + m[4]*m[13]*m[10] + m[5]*m[8]*m[14] - m[5]*m[12]*m[10] - m[6]*m[8]*m[13] + m[6]*m[12]*m[9];
  63.     r[13] = m[0]*m[9]*m[14] - m[0]*m[13]*m[10] - m[1]*m[8]*m[14] + m[1]*m[12]*m[10] + m[2]*m[8]*m[13] - m[2]*m[12]*m[9];
  64.     r[14] = -m[0]*m[5]*m[14] + m[0]*m[13]*m[6] + m[1]*m[4]*m[14] - m[1]*m[12]*m[6] - m[2]*m[4]*m[13] + m[2]*m[12]*m[5];
  65.     r[15] = m[0]*m[5]*m[10] - m[0]*m[9]*m[6] - m[1]*m[4]*m[10] + m[1]*m[8]*m[6] + m[2]*m[4]*m[9] - m[2]*m[8]*m[5];
  66.  
  67.     local det = m[0]*r[0] + m[1]*r[4] + m[2]*r[8] + m[3]*r[12];
  68.     for i = 0, 15 do r[i] = r[i] / det end
  69.     return result;
  70. end
  71.  
  72. -- ### GL.Matrix.transpose(matrix[, result])
  73. --
  74. -- Returns `matrix`, exchanging columns for rows. You can optionally pass an
  75. -- existing matrix in `result` to avoid allocating a new matrix.
  76. local function matrix_transpose(matrix, result)
  77.     result = result or Matrix44();
  78.     local m = matrix.m
  79.     local r = result.m;
  80.    
  81.     r[0] = m[0]; r[1] = m[4]; r[2] = m[8]; r[3] = m[12];
  82.     r[4] = m[1]; r[5] = m[5]; r[6] = m[9]; r[7] = m[13];
  83.     r[8] = m[2]; r[9] = m[6]; r[10] = m[10]; r[11] = m[14];
  84.     r[12] = m[3]; r[13] = m[7]; r[14] = m[11]; r[15] = m[15];
  85.     return result;
  86. end
  87.  
  88. -- ### GL.Matrix.multiply(left, right[, result])
  89. --
  90. -- Returns the concatenation of the transforms for `left` and `right`. You can
  91. -- optionally pass an existing matrix in `result` to avoid allocating a new
  92. -- matrix. This emulates the OpenGL function `glMultMatrix()`.
  93. local function matrix_multiply(left, right, result)
  94.     result = result or Matrix44();
  95.     local a = left.m
  96.     local b = right.m
  97.     local r = result.m;
  98.  
  99.     r[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12];
  100.     r[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13];
  101.     r[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14];
  102.     r[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15];
  103.  
  104.     r[4] = a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12];
  105.     r[5] = a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13];
  106.     r[6] = a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14];
  107.     r[7] = a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15];
  108.  
  109.     r[8] = a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12];
  110.     r[9] = a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13];
  111.     r[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14];
  112.     r[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15];
  113.  
  114.     r[12] = a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12];
  115.     r[13] = a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13];
  116.     r[14] = a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14];
  117.     r[15] = a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15];
  118.  
  119.     return result;
  120. end
  121.  
  122. -- ### GL.Matrix.identity([result])
  123. --
  124. -- Returns an identity matrix. You can optionally pass an existing matrix in
  125. -- `result` to avoid allocating a new matrix. This emulates the OpenGL function
  126. -- `glLoadIdentity()`.
  127. local function matrix_identity(result)
  128.     result = result or Matrix44();
  129.     local m = result.m;
  130.    
  131.     m[0] = 1
  132.     m[5] = 1
  133.     m[10] = 1
  134.     m[15] = 1
  135.    
  136.     m[1] = 0
  137.     m[2] = 0
  138.     m[3] = 0
  139.     m[4] = 0
  140.     m[6] = 0
  141.     m[7] = 0
  142.     m[8] = 0
  143.     m[9] = 0
  144.     m[11] = 0
  145.     m[12] = 0
  146.     m[13] = 0
  147.     m[14] = 0
  148.    
  149.     return result;
  150. end
  151.  
  152. -- ### GL.Matrix.frustum(left, right, bottom, top, near, far[, result])
  153. --
  154. -- Sets up a viewing frustum, which is shaped like a truncated pyramid with the
  155. -- camera where the point of the pyramid would be. You can optionally pass an
  156. -- existing matrix in `result` to avoid allocating a new matrix. This emulates
  157. -- the OpenGL function `glFrustum()`.
  158. local function matrix_frustum(l, r, b, t, n, f, result)
  159.     result = result or Matrix44();
  160.     local m = result.m;
  161.        
  162.     local temp = 2.0 * n;
  163.     local temp2 = r - l;
  164.     local temp3 = t - b;
  165.     local temp4 = f - n;
  166.    
  167.     m[0] = temp / temp2;
  168.     m[1] = 0.0;
  169.     m[2] = 0.0;
  170.     m[3] = 0.0;
  171.     m[4] = 0.0;
  172.     m[5] = temp / temp3;
  173.     m[6] = 0.0;
  174.     m[7] = 0.0;
  175.     m[8] = (r + l) / temp2;
  176.     m[9] = (t + b) / temp3;
  177.     m[10] = (-f - n) / temp4;
  178.     m[11] = -1.0;
  179.     m[12] = 0.0;
  180.     m[13] = 0.0;
  181.     m[14] = (-temp * f) / temp4;
  182.     m[15] = 0.0;
  183.    
  184.     return result;
  185. end
  186.  
  187. -- ### GL.Matrix.perspective(fov, aspect, near, far[, result])
  188. --
  189. -- Returns a perspective transform matrix, which makes far away objects appear
  190. -- smaller than nearby objects. The `aspect` argument should be the width
  191. -- divided by the height of your viewport and `fov` is the top-to-bottom angle
  192. -- of the field of view in degrees. You can optionally pass an existing matrix
  193. -- in `result` to avoid allocating a new matrix. This emulates the OpenGL
  194. -- function `gluPerspective()`.
  195. local function matrix_perspective(fov, aspect, near, far, result)
  196.     result = result or Matrix44();
  197.    
  198.     local yScale = 1.0 / math.tan(math.rad(fov) / 2)
  199.     local xScale = yScale / aspect
  200.     local nearmfar = near - far
  201.    
  202.     local m = result.m
  203.    
  204.     m[0] = xScale
  205.     m[1] = 0
  206.     m[2] = 0
  207.     m[3] = 0
  208.     m[4] = 0
  209.     m[5] = yScale
  210.     m[6] = 0
  211.     m[7] = 0
  212.     m[8] = 0
  213.     m[9] = 0
  214.     m[10] = (far + near) / nearmfar
  215.     m[11] = -1
  216.     m[12] = 0
  217.     m[13] = 0
  218.     m[14] = 2*far*near / nearmfar
  219.     m[15] = 0
  220.    
  221.     return result
  222. end
  223.  
  224. -- ### GL.Matrix.ortho(left, right, bottom, top, near, far[, result])
  225. --
  226. -- Returns an orthographic projection, in which objects are the same size no
  227. -- matter how far away or nearby they are. You can optionally pass an existing
  228. -- matrix in `result` to avoid allocating a new matrix. This emulates the OpenGL
  229. -- function `glOrtho()`.
  230.  
  231. local function matrix_ortho(left, right, bottom, top, near, far, result)
  232.     result = result or Matrix44()
  233.    
  234.     local m = result.m
  235.    
  236.     m[0*4] = 2 / (right - left)
  237.     --m[1*4] = 0
  238.     --m[2*4] = 0
  239.     m[3*4] = -(right + left) / (right - left)
  240.  
  241. --  m[0*4+1] = 0
  242.     m[1*4+1] = 2 / (top - bottom)
  243. --  m[2*4+1] = 0
  244.     m[3*4+1] = -(top + bottom) / (top - bottom)
  245.  
  246. --  m[0*4+2] = 0
  247. --  m[1*4+2] = 0
  248.     m[2*4+2] = -2 / (far - near)
  249.     m[3*4+2] = -(far + near) / (far - near)
  250.  
  251. --  m[0*4+3] = 0
  252. --  m[1*4+3] = 0
  253. --  m[2*4+3] = 0
  254. --  m[3*4+3] = 1
  255.                
  256.     return result
  257. end
  258.  
  259. -- ### GL.Matrix.scale(x, y, z[, result])
  260. --
  261. -- This emulates the OpenGL function `glScale()`. You can optionally pass an
  262. -- existing matrix in `result` to avoid allocating a new matrix.
  263. local function matrix_scale(x, y, z, result)
  264.     result = result or Matrix44();
  265.  
  266.     if x == 1 and y == 1 and z == 1 then return result end
  267.    
  268.     local m = result.m;
  269.  
  270.     m[0] = m[0] * x
  271.     m[4] = m[4] * y
  272.     m[8] = m[8] * z
  273.    
  274.     m[1] = m[1] * x
  275.     m[5] = m[5] * y
  276.     m[9] = m[9] * z
  277.    
  278.     m[2] = m[2] * x
  279.     m[6] = m[6] * y
  280.     m[10] = m[10] * z
  281.    
  282.     m[3] = m[3] * x
  283.     m[7] = m[7] * y
  284.     m[11] = m[11] * z
  285.  
  286.     return result;
  287. end
  288.  
  289. -- ### GL.Matrix.translate(x, y, z[, result])
  290. --
  291. -- This emulates the OpenGL function `glTranslate()`. You can optionally pass
  292. -- an existing matrix in `result` to avoid allocating a new matrix.
  293. local function matrix_translate(x, y, z, result)
  294.     result = result or Matrix44();
  295.    
  296.     if x == 0 and y == 0 and (z == 0 or not z) then return result end
  297.  
  298.     local m = result.m;
  299.  
  300.     m[12] = m[0] * x + m[4] * y + m[8]  * z + m[12];
  301.     m[13] = m[1] * x + m[5] * y + m[9]  * z + m[13];
  302.     m[14] = m[2] * x + m[6] * y + m[10] * z + m[14];
  303.     m[15] = m[3] * x + m[7] * y + m[11] * z + m[15];
  304.  
  305.     return result;
  306. end
  307.  
  308. -- ### GL.Matrix.rotate(a, x, y, z[, result])
  309. --
  310. -- Returns a matrix that rotates by `a` degrees around the vector `x, y, z`.
  311. -- You can optionally pass an existing matrix in `result` to avoid allocating
  312. -- a new matrix. This emulates the OpenGL function `glRotate()`.
  313. local function matrix_rotate(a, x, y, z, result)
  314.     if not a or (not x and not y and not z) then
  315.         return matrix_identity(result)
  316.     end
  317.        
  318.     result = result or Matrix44();
  319.    
  320.     if a == 0 then return result end
  321.  
  322.     local m = result.m
  323.  
  324.     local xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c;
  325.     local optimized = false
  326.  
  327.     local s = math.sin(math.rad(a))
  328.     local c = math.cos(math.rad(a))
  329.  
  330.     if x == 0 then
  331.         if y == 0 then
  332.             if z ~= 0 then
  333.                 optimized = true
  334.  
  335.                 m[0*4+0] = c
  336.                 m[1*4+1] = c
  337.  
  338.                 if z < 0 then
  339.                     m[1*4+0] = s
  340.                     m[0*4+1] = -s
  341.                 else
  342.                     m[1*4+0] = -s
  343.                     m[0*4+1] = s
  344.                 end
  345.             elseif z == 0 then
  346.                 optimized = true;
  347.  
  348.                 m[0*4+0] = c
  349.                 m[2*4+2] = c
  350.  
  351.                 if y < 0 then
  352.                     m[2*4+0] = -s
  353.                     m[0*4+2] = s
  354.                 else
  355.                     m[2*4+0] = s
  356.                     m[0*4+2] = -s
  357.                 end
  358.             end
  359.         end
  360.     elseif y == 0 then
  361.         if z == 0 then
  362.             optimized = true
  363.  
  364.             m[1*4+1] = c
  365.             m[2*4+2] = c
  366.  
  367.             if x < 0 then
  368.                 m[2*4+1] = s
  369.                 m[1*4+2] = -s
  370.             else
  371.                 m[2*4+1] = -s;
  372.                 m[1*4+2] = s;
  373.             end
  374.         end
  375.     end
  376.  
  377.     if not optimized then
  378.         local mag = math.sqrt(x * x + y * y + z * z)
  379.  
  380.         if mag <= 1.0e-4 then
  381.             return
  382.         end
  383.  
  384.         x = x / mag;
  385.         y = y / mag;
  386.         z = z / mag;
  387.  
  388.         xx = x * x
  389.         yy = y * y
  390.         zz = z * z
  391.         xy = x * y
  392.         yz = y * z
  393.         zx = z * x
  394.         xs = x * s
  395.         ys = y * s
  396.         zs = z * s
  397.         one_c = 1 - c
  398.  
  399.         m[0*4+0] = (one_c * xx) + c;
  400.         m[1*4+0] = (one_c * xy) - zs;
  401.         m[2*4+0] = (one_c * zx) + ys;
  402.  
  403.         m[0*4+1] = (one_c * xy) + zs;
  404.         m[1*4+1] = (one_c * yy) + c;
  405.         m[2*4+1] = (one_c * yz) - xs;
  406.  
  407.         m[0*4+2] = (one_c * zx) - ys;
  408.         m[1*4+2] = (one_c * yz) + xs;
  409.         m[2*4+2] = (one_c * zz) + c;
  410.  
  411.     end
  412.  
  413.     return result
  414. end
  415.  
  416. -- ### GL.Matrix.lookAt(ex, ey, ez, cx, cy, cz, ux, uy, uz[, result])
  417. --
  418. -- Returns a matrix that puts the camera at the eye point `ex, ey, ez` looking
  419. -- toward the center point `cx, cy, cz` with an up direction of `ux, uy, uz`.
  420. -- You can optionally pass an existing matrix in `result` to avoid allocating
  421. -- a new matrix. This emulates the OpenGL function `gluLookAt()`.
  422. local function matrix_look_at(ex, ey, ez, cx, cy, cz, ux, uy, uz, result)
  423.     result = result or Matrix44();
  424.     local m = result.m;
  425.  
  426.     local e = Vec3(ex, ey, ez);
  427.     local c = Vec3(cx, cy, cz);
  428.     local u = Vec3(ux, uy, uz);
  429.     local f = (e - c):GetNormalized()
  430.     local s = u:Cross(f):GetNormalized()
  431.     local t = f:Cross(s):GetNormalized()
  432.  
  433.     m[0] = s.x;
  434.     m[1] = s.y;
  435.     m[2] = s.z;
  436.     m[3] = -s:GetDot(e);
  437.  
  438.     m[4] = t.x;
  439.     m[5] = t.y;
  440.     m[6] = t.z;
  441.     m[7] = -t:GetDot(e);
  442.  
  443.     m[8] = f.x;
  444.     m[9] = f.y;
  445.     m[10] = f.z;
  446.     m[11] = -f:GetDot(e);
  447.  
  448.     m[12] = 0;
  449.     m[13] = 0;
  450.     m[14] = 0;
  451.     m[15] = 1;
  452.  
  453.     return result;
  454. end
  455.  
  456. local MAT_SX = 0
  457. local MAT_SY = 5
  458. local MAT_SZ = 10
  459. local MAT_TX = 12
  460. local MAT_TY = 13
  461. local MAT_TZ = 14
  462.  
  463. local function matrix_viewport(x, y, width, height, z_near, z_far, depth_max, result)
  464.     result = result or Matrix44();
  465.     local m = result.m;
  466.    
  467.     m[MAT_SX] = width / 2
  468.     m[MAT_TX] = m[MAT_SX] + x
  469.     m[MAT_SY] = height / 2 
  470.     m[MAT_TY] = m[MAT_SY] + y
  471.    
  472.     if depth_max and z_far and z_near then
  473.         m[MAT_SZ] = depth_max * ((z_far - z_near) / 2)
  474.         m[MAT_TZ] = depth_max * ((z_far - z_near) / 2 + z_near)
  475.     end
  476.    
  477.     return result
  478. end
  479.  
  480. local META = {}
  481.  
  482. META.Type = "matrix44"
  483.  
  484. function META:OpenGLFunc(func, ...)
  485.     func = gl[func] or glu[func]
  486.     local old = ffi.new("GLint[1]")
  487.     gl.GetIntegerv(e.GL_MATRIX_MODE, old)
  488.     gl.MatrixMode(e.GL_MODELVIEW)
  489.    
  490.     gl.PushMatrix()
  491.     gl.LoadIdentity()
  492.     func(...)
  493.     gl.GetFloatv(e.GL_MODELVIEW_MATRIX, self.m)
  494.     gl.PopMatrix()
  495.    
  496.     gl.MatrixMode(old[0])
  497.    
  498.     return self
  499. end
  500.  
  501. function META:Identity()
  502.     matrix_identity(self)
  503.    
  504.     return self
  505. end
  506.  
  507. META.LoadIdentity = META.Identity
  508.  
  509. function META:GetInverse()
  510.     return matrix_inverse(self, Matrix44())
  511. end
  512.  
  513. function META:GetTranspose()
  514.     return matrix_transpose(self, Matrix44())
  515. end
  516.  
  517. function META:__mul(b)
  518.     return matrix_multiply(self, b, Matrix44())
  519. end
  520.  
  521. function META:Multiply(b)
  522.     return matrix_multiply(self, b, Matrix44())
  523. end
  524.  
  525. function META:TransformPoint(v)
  526.     return matrix_transform_point(self, v)
  527. end
  528.  
  529. function META:TransformVector(v)
  530.     return matrix_transform_vector(self, v)
  531. end
  532.  
  533. function META:Perspective(fov, aspect, near, far)
  534.     return matrix_perspective(fov, aspect, near, far, self)
  535. end
  536.  
  537. function META:Frustum(l, r, b, t, n, f)
  538.     return matrix_frustum(l, r, b, t, n, f, self)
  539. end
  540.  
  541. function META:Ortho(left, right, bottom, top, near, far)
  542.     return matrix_ortho(left, right, bottom, top, near, far, self)
  543. end
  544.  
  545. function META:Viewport(x, y, width, height, z_near, z_far, depth_max, result)
  546.     return matrix_viewport(x, y, width, height, z_near, z_far, depth_max, result)
  547. end
  548.  
  549. function META:LookAt(ex, ey, ez, cx, cy, cz, ux, uy, uz)
  550.     return matrix_look_at(ex, ey, ez, cx, cy, cz, ux, uy, uz, self)
  551. end
  552.  
  553. function META:__index(key)
  554.     return META[key] or self.m[key]
  555. end
  556.  
  557. function META:Scale(x, y, z)
  558.     return matrix_scale(x, y, z, self)
  559. end
  560.  
  561. function META:Translate(x, y, z)
  562.     return matrix_translate(x, y, z, self)
  563. end
  564.  
  565. function META:Rotate(a, x, y, z)
  566.     return matrix_rotate(a, x, y, z, self)
  567. end
  568.  
  569. function META:__tostring()
  570.     local args = {}
  571.     for i = 0, 15 do args[i+1] = self[i] end
  572.     return string.format("matrix44[%p]:\n" .. ("%f %f %f %f\n"):rep(4), self.m, unpack(args))
  573. end
  574.  
  575. function Matrix44(m)
  576.     local self = setmetatable({}, META)
  577.    
  578.     if m then
  579.         self.m = m
  580.     else
  581.         self.m = ffi.new("float[16]")
  582.         matrix_identity(self)  
  583.     end
  584.    
  585.     return self
  586. end
Advertisement
Add Comment
Please, Sign In to add comment