aboutsummaryrefslogtreecommitdiffstats
path: root/linmath.h
diff options
context:
space:
mode:
Diffstat (limited to 'linmath.h')
-rw-r--r--linmath.h95
1 files changed, 95 insertions, 0 deletions
diff --git a/linmath.h b/linmath.h
index deb5837..b0f9c8f 100644
--- a/linmath.h
+++ b/linmath.h
@@ -167,6 +167,16 @@ static inline void mat4x4_translate(mat4x4 T, float x, float y, float z)
T[3][1] = y;
T[3][2] = z;
}
+static inline void mat4x4_translate_in_place(mat4x4 m, float x, float y, float z)
+{
+ /* Adapted from Android's OpenGL Matrix.java. */
+ int i;
+ for (i = 0; i < 4; ++i) {
+ m[3][i] += m[0][i] * x
+ + m[1][i] * y
+ + m[2][i] * z;
+ }
+}
static inline void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 a, vec3 b)
{
int i, j;
@@ -321,6 +331,91 @@ static inline void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, fl
M[3][2] = -(f+n)/(f-n);
M[3][3] = 1.;
}
+static inline void mat4x4_perspective(mat4x4 m, float y_fov_in_degrees, float aspect, float n, float f)
+{
+ /* Adapted from Android's OpenGL Matrix.java. */
+ const float angle_in_radians = (float) (y_fov_in_degrees * M_PI / 180.0);
+ const float a = (float) (1.0 / tan(angle_in_radians / 2.0));
+
+ m[0][0] = a / aspect;
+ m[1][0] = 0.0f;
+ m[2][0] = 0.0f;
+ m[3][0] = 0.0f;
+
+ m[1][0] = 0.0f;
+ m[1][1] = a;
+ m[1][2] = 0.0f;
+ m[1][3] = 0.0f;
+
+ m[2][0] = 0.0f;
+ m[2][1] = 0.0f;
+ m[2][2] = -((f + n) / (f - n));
+ m[2][3] = -1.0f;
+
+ m[3][0] = 0.0f;
+ m[3][1] = 0.0f;
+ m[3][2] = -((2.0f * f * n) / (f - n));
+ m[3][3] = 0.0f;
+}
+static inline void mat4x4_look_at(mat4x4 m,
+ float eyeX, float eyeY, float eyeZ,
+ float centerX, float centerY, float centerZ,
+ float upX, float upY, float upZ)
+{
+ /* Adapted from Android's OpenGL Matrix.java. */
+ // See the OpenGL GLUT documentation for gluLookAt for a description
+ // of the algorithm. We implement it in a straightforward way:
+
+ float fx = centerX - eyeX;
+ float fy = centerY - eyeY;
+ float fz = centerZ - eyeZ;
+
+ // Normalize f
+ vec3 f_vec = {fx, fy, fz};
+ float rlf = 1.0f / vec3_len(f_vec);
+ fx *= rlf;
+ fy *= rlf;
+ fz *= rlf;
+
+ // compute s = f x up (x means "cross product")
+ float sx = fy * upZ - fz * upY;
+ float sy = fz * upX - fx * upZ;
+ float sz = fx * upY - fy * upX;
+
+ // and normalize s
+ vec3 s_vec = {sx, sy, sz};
+ float rls = 1.0f / vec3_len(s_vec);
+ sx *= rls;
+ sy *= rls;
+ sz *= rls;
+
+ // compute u = s x f
+ float ux = sy * fz - sz * fy;
+ float uy = sz * fx - sx * fz;
+ float uz = sx * fy - sy * fx;
+
+ m[0][0] = sx;
+ m[0][1] = ux;
+ m[0][2] = -fx;
+ m[0][3] = 0.0f;
+
+ m[1][0] = sy;
+ m[1][1] = uy;
+ m[1][2] = -fy;
+ m[1][3] = 0.0f;
+
+ m[2][0] = sz;
+ m[2][1] = uz;
+ m[2][2] = -fz;
+ m[2][3] = 0.0f;
+
+ m[3][0] = 0.0f;
+ m[3][1] = 0.0f;
+ m[3][2] = 0.0f;
+ m[3][3] = 1.0f;
+
+ mat4x4_translate_in_place(m, -eyeX, -eyeY, -eyeZ);
+}
typedef float quat[4];
static inline void quat_identity(quat q)