-- Add MGL loader.
-- pattern: Lua pattern
-- callback(...): called when an undefined field is accessed with the specified pattern
--- ...: pattern captures (returned by string.match)
--- should return the field value
mgl.addLoader(pattern, callback)
-- Generate function.
-- name: identify the generated function for debug
mgl.genfunc(code, name)
-- Initialize operation multifunctions.
-- ...: list of identifiers
mgl.initmfs(...)
__tostring |
tostring |
__unm |
unm |
__add |
xtype add |
__sub |
xtype sub |
__mul |
xtype mul |
__div |
xtype div |
__mod |
xtype mod |
__pow |
xtype pow |
__eq |
xtype eq |
__lt |
xtype lt |
__le |
xtype le |
Types can have specialized metamethods; for example, to implement accessors.
ℹ️
|
Accessors are implemented as simple as possible, they are check free. |
Generic vector type of dimension D
, stored as an array/list of scalars (table).
-- Require vec(D) vector type.
-- D: (optional) dimension
-- return vec(D) or vec xtype
mgl.require_vec(D)
-- Loader pattern.
mgl.vecD
-- Accessors.
-- vec.x / vec.r (vec[1])
-- vec.y / vec.g (vec[2])
-- vec.z / vec.b (vec[3])
-- vec.w / vec.a (vec[4])
#vec -- dimension
Generic matrix type of dimension N x M
, stored as an array/list of row-major ordered scalars (table). Columns are vectors.
ℹ️
|
The choice of the row-major order is about reading/writing a matrix content as we read/write text/code in English/Lua (left to right, top to bottom). The choice of columns as vectors is about following mathematical conventions ( M*v to transform a vector).
|
-- Require mat(N)(M)/mat(N) vector type.
-- Matrix values are stored as a row-major ordered list; columns are vectors.
-- N: (optional) columns
-- M: (optional) rows (default: N)
-- return mat(N)(M)/mat(N) or mat xtype
mgl.require_mat(N, M)
-- Loader patterns.
mgl.matNxM
mgl.matN -- square
-- Vector accessor (get/set column vector).
-- idx: column index
-- vec: (optional) vec(M), set column
mat:v(idx, vec)
Binary operators are implemented through xtype op multifunctions.
(vec(D): a, vec(D): b): vec(D)
-
Component-wise multiplication.
(vec(D): a, number: b): vec(D)
-
-
(number: a, vec(D): b): vec(D)
-
-
(mat(N)x(M): a, mat(O)x(N) or vec(N): b): mat(O)x(M) or vec(M)
-
Matrix/vector general multiplication. Will return a vector if the result has a single column.
(mat(N)x(M): a, number: b): mat(N)x(M)
-
-
(number: a, mat(N)x(M): b): mat(N)x(M)
-
-
Operations are xtype multifunctions.
Vector constructor.
(number: scalar): vec(D)
-
Scalar constructor.
(table: list): vec(D)
-
List constructor.
#list >= D
(number or vec(D): …): vec(D)
-
Composed constructor. Any combination of scalars and vectors matching the result vector size.
(vec(D+x): v): vec(D)
-
Truncate constructor.
Matrix constructor.
(number: scalar): mat(N)x(M)
-
Scalar constructor. Create matrix with
scalar
along the identity diagonal. (table: list): mat(N)x(M)
-
List constructor.
#list >= N*M
(vec(M): columns…): mat(N)x(M)
-
Column vectors constructor.
#columns… == N
(mat(Na, Ma): a): mat(N)x(M)
-
Generic matrix constructor. Copy/extend/truncate a same/smaller/bigger matrix (fill with identity when extending).
(mat2: a): mat2, number
-
Compute inverse matrix. Also returns determinant.
(mat3: a): mat3, number
-
Compute inverse matrix. Also returns determinant.
(mat4: a): mat4, number
-
Compute inverse matrix. Also returns determinant.
(vec2: a): mat3
-
Translate identity (2D homogeneous).
(vec3: a): mat4
-
Translate identity (3D homogeneous).
(number: theta): mat3
-
Rotate identity (2D homogeneous).
theta
is in radians. (vec3: axis, number: theta): mat4
-
Rotate identity (3D homogeneous).
axis
is a unit vector;theta
is in radians.
(vec2: a): mat3
-
Scale identity (2D homogeneous).
(vec3: a): mat4
-
Scale identity (3D homogeneous).
Orthographic projection.
(number: left, number: right, number: bottom, number: top, number: near, number: far): mat4
-
Build GL compatible orthographic projection.
💡
|
An operator/operation definition can be retrieved and cached with multifunction:resolve(…) when optimizations are needed.
|
Here are some comparisons with other libraries (only aims to give clues about MGL performances).
See compare/benchmark.lua.
-
Measures are made on a
x86_64 i5-6500 3.6GHz 16Go DDR4
machine. -
The minimum time and the maximum memory of 3 measures is kept.
-
Allocation of entities is measured, but should be negligible.
name | wtime (s) [1] | utime (s) [2] | mem (kB) [3] | ~ ms/tick | ~ frame % | code |
---|---|---|---|---|---|---|
GLM GCC -O2 |
0.98 |
0.98 |
3456 |
0.817 |
5 |
|
MGL LuaJIT (JIT on) |
2.56 |
2.51 |
11032 |
2.133 |
13 |
|
CPML LuaJIT (JIT on) |
4.25 |
4.24 |
9780 |
3.542 |
21 |
|
CPML LuaJIT (JIT off) |
27.59 |
27.57 |
14396 |
22.992 |
138 |
|
MGL LuaJIT (JIT off) |
27.8 |
27.77 |
9972 |
23.167 |
139 |
MGL is around 2-3x slower than GLM in this benchmark. It seems fine considering that MGL works on raw tables with a straightforward API (thanks to LuaJIT optimizations like Allocation Sinking).