Home Rumble Youtube Twitter/X Kofi Contact / Crypto

 

Matrixes in c3dlas only come in single-precision floats. Yes, "matrixes". English has some dumb historical irregularities and it behooves us to right them. There are structs for 2x2, 3x3, 4x4, 4x3, and 3x4 matrixes but only 4x4 has a full set of functions as the others only have niche uses in 3D games.

This documentation is intentionally written for an audience with minimal mathematical knowledge. Matrixes can be used to represent transformations on vectors such as translation (movement), rotation, skewing, and scaling. These operations can be combined together through matrix multiplication, allowing you to apply a great number of operations all at once to a vector instead of having to do them all sequentially.

Matrixes are stored in column major order, which is to say that the first four floats in memory of a 4x4 matrix correspond to the values of the first (leftmost) column when written down, from top to bottom. The next four elements are the second row, top to bottom, and so forth. The type is a union consisting of a flat array of floats called m and an array of vectors called cols.

typedef union { float m[16]; vec4 cols[4]; } mat4; typedef union { float m[12]; vec3 cols[4]; } mat4x3;

The long struct names, to avoid clobbering other libraries, have the form MatrixC for symmetric matrixes and MatrixCxR for asymmetric matrixes where C and R are the number of columns and rows. Shorter typedefs found in short_macros.h are used in this documention. By default functions use mat4.

vec3 vMatrixMul3(vec3 in, mat4* m) void vMatrixMul3p(vec3* in, mat4* m, vec3* out) void vMatrixMulf3p(float x, float y, float z, mat* m, vec3* out) vec4 vMatrixMul4(vec4 in, mat4* m)
Multiplies the input vector by the matrix, applying the transformations to it.
vec3 vMatrixMulProjectedMagic3(vec3 in, mat* m)
Multiplies the input vector by the matrix, but has some extra logic to give the expected locations "behind" a perspective camera.
void mIdent(mat4* m)
Sets m to the identity matrix, which is a matrix that makes no changes to a vector.
void mMul(mat4* l, mat4* r, mat4* out)
Multiplies l by r and stores the result in out. out cannot alias (point to) l or r as temporary results are accumulated there. Use mMul instead.
void mMul(mat4* a, mat4* out)
Multiplies a into out, using temporary memory to prevent clobbering the original values of out before the multiplication is done.
void mBlend(mat4* in, float t, mat4* out)
Multiplies every element of in by t then adds the result into out
void mPrint(mat4* m, void* arg)
Prints the matrix in a pretty, square format using the function set by the macro C3DLAS_fprintf, using arg as the first argument (file handle). By default this is fprintf.

Transformations

void mTransv(vec3* v, mat4* out) void mTrans3f(float x, float y, float z, mat4* out)
Applies a translation to the matrix in out which moves (adds) any applied vector by in. This moves a mesh or vector around in space. These functions accumulates the operation into out..
void mScalev(vec3* v, mat4* out) void mScale3f(float x, float y, float z, mat4* out)
Applies scaling to the matrix in out which scales (multiplies) any applied vector by in. This makes a mesh bigger or smaller. Asymmetric scaling factors (where the values of each dimension are not equal) may create problems in some algorithms that cause more costly operations to be needed. These functions accumulates the operation into out..
void mRotv(vec3* v, float theta, mat4* out) void mRot3f(float x, float y, float z, float theta, mat4* out) void mRotX(float theta, mat4* out) void mRotY(float theta, mat4* out) void mRotZ(float theta, mat4* out)
Applies a rotation to the matrix in out which rotates (does a bunch of trig on) any applied vector by in. This rotates a mesh or vector about the origin in space. Note that the order of applied rotations matters. These functions accumulates the operation into out..
void mTranspose(mat4* in, mat4* out)
Transposes in to temporary memory then copies it to out. In and out can point to the same memory. For affine matrixes, the transpose is equivalent to the inverse but much faster to calculate. .
void mTransposeFast(mat4* in, mat4* out)
Transposes in and copies it directly to out. In and out must not point to the same memory. For affine matrixes, the transpose is equivalent to the inverse but much faster to calculate..
void mRotationOnly(mat4* in, mat4* out)
Extracts just the rotational component of in. Used for rotating normals without scaling or translating them..
void mDecompose(mat4* mat, vec3* trans, quat* rot, vec3* scale)
Extracts the individual translation, rotation (as a quaternion), and scaling components from a matrix that has only those components.
void mRecompose(vec3* trans, quat* rot, vec3* scale, mat4* out)
Reconstructs a matrix containing the translation, rotation (as a quaternion), and scale, applied in the correct order.

Camera Utilities

These functions perform the necessary series of transformations to orient the camera in the given way without you having to work out what all those operations are and what order to do them in.
void mLookAt(vec3 eye, vec3 center, vec3 up, mat4* out)
Points the camera at another point. Analgous to gluLookAt(). Eye is the eye position, center is the point being looked at, and up is the direction of up from the camera&$39;s point of view. Up is not required to be orthogonal to anything, so long as it's not parallel to anything.
void mLookDir(vec3 eye, vec3 dir, vec3 up, mat4* out)
Points the camera in a certain direction. Eye is the eye position, dir is the direciton to look, and up is the direction of up from the camera&$39;s point of view. Up is not required to be orthogonal to anything, so long as it's not parallel to anything.

Projection Matrix Utilities

These functions are used to create projection matrixes for 3D rendering. A projection matrix transforms a point in view space to normalized device coordinates, the specification of which varies depending on your rendering system. As such, there are several versions of some functions corresponding to OpenGL (GL), Vulkan (VK), reverse depth buffers (RDepth), and "Z-up" world spaces (ZUp).

// analogous to glFrustum // no div/0 checking here for right == left etc. just don't be an idiot. void mFrustum(float left, float right, float top, float bottom, float near, float far, mat4* out); // analogous to gluPerspective // same div/0 warnings apply. if you get an FP exception you deserve it. // https://www.opengl.org/archives/resources/faq/technical/transformations.htm // https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml void mPerspective(float fov, float aspect, float near, float far, mat4* out); // analogous to gluPerspective // same div/0 warnings apply. if you get an FP exception you deserve it. void mPerspectiveVK(float fov, float aspect, float near, float far, mat4* out); void mPerspectiveVK_ZUp(float fov, float aspect, float near, float far, mat4* out); // extract the near and far planes from a prespective mat void mPerspExtractNF(mat4* m, double* near, double* far); // set the near and far planes for an existing prespective mat void mPerspSetNF(mat4* m, float near, float far); void mPerspSetNFVK(mat4* m, float near, float far); void mPerspSetNF_ZUp(mat4* m, float near, float far); void mPerspSetNF_ZUp_RDepth(mat4* m, float near, float far); void mPerspSetNFVK_ZUp(mat4* m, float near, float far); void mPerspSetNFVK_ZUp_RDepth(mat4* m, float near, float far); // orthographic projection. use this for a "2D" look. // same div/0 warnings. void mOrtho(float left, float right, float top, float bottom, float near, float far, mat4* out); // orthographic projection. use this for a "2D" look. void mOrthoVK(float left, float right, float top, float bottom, float near, float far, mat4* out); // calculates a cubical orthographic mat with a side length of 2*r void mOrthoFromRadius(float r, mat4* out); // calculates a cubical orthographic mat with a side length of 2*r void mOrthoFromRadiusVK(float r, mat4* out); // calculates an orthographic mat that encloses the sphere, looking from eyePos void mOrthoFromSphere(Sphere s, vec3 eyePos, vec3 up, mat4* out); // calculates an orthographic mat that encloses the sphere, looking from eyePos void mOrthoFromSphereVK(Sphere s, vec3 eyePos, vec3 up, mat4* out); // extract the planes from an orthographic projection mat. void mOrthoExtractPlanes( mat4* m, float* left, float* right, float* top, float* bottom, float* near, float* far ); // extract the planes from an orthographic projection mat. void mOrthoExtractPlanesVK( mat4* m, float* left, float* right, float* top, float* bottom, float* near, float* far ); void mOrthoSetNF(mat4* m, float near, float far); void mOrthoSetNFVK(mat4* m, float near, float far);

Math Operations

float mDeterminate(mat4* m)
Calculates the determinate of the matrix, which is useful in some other mathematical operations. The determinate has no exact physical meaning for an arbitrary matrix but it does represent the "degree" or "magnitude" of the complete transformation inside the matrix. For a pure translation matrix, the determinate is the distance of the transformation. For a symmetric pure scaling matrix, it's the amount of scaling..
int mInverse(mat4* in, mat4* out)
Calculates the inverse of the matrix, which does the reverse operation. Multiplying a matrix with its inverse results in the identity matrix..
float mTrace(mat4* m)
Returns the trace of the matrix, which is the sum of the diagonal elements..
void mAdd(mat4* a, mat4* b, mat4* out)
Simple element-wise addition of a and b into out. This is an uncommon operation with no general physical meaning..
void mScalarMul(mat4* a, float f, mat4* out)
Multiply every element of a by f and store into out. This is an uncommon operation with no general physical meaning..

Functions In Other Dimensions

There are sporadic functions on the other sizes of matrixes. One day I'll fill them all in. Check the source in the meantime.