101#ifndef MATH_3D_HEADER
102#define MATH_3D_HEADER
109#define M_PI 3.14159265358979323846
124static inline vec3_t vec3(
float x,
float y,
float z) {
return (
vec3_t){x, y, z };}
126static inline vec3_t v3_adds (
vec3_t a,
float s) {
return (
vec3_t){a.x + s, a.y + s, a.z + s };}
128static inline vec3_t v3_subs (
vec3_t a,
float s) {
return (
vec3_t){a.x - s, a.y - s, a.z - s };}
130static inline vec3_t v3_muls (
vec3_t a,
float s) {
return (
vec3_t){a.x * s, a.y * s, a.z * s };}
132static inline vec3_t v3_divs (
vec3_t a,
float s) {
return (
vec3_t){a.x / s, a.y / s, a.z / s };}
133static inline float v3_length(
vec3_t v) {
return sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);}
135static inline float v3_dot (
vec3_t a,
vec3_t b) {
return a.x * b.x + a.y * b.y + a.z * b.z;}
138static inline float v3_angle_between(
vec3_t a,
vec3_t b);
187 float m00, m01, m02, m03;
188 float m10, m11, m12, m13;
189 float m20, m21, m22, m23;
190 float m30, m31, m32, m33;
195 float m00,
float m10,
float m20,
float m30,
196 float m01,
float m11,
float m21,
float m31,
197 float m02,
float m12,
float m22,
float m32,
198 float m03,
float m13,
float m23,
float m33
201static inline mat4_t m4_identity ();
204static inline mat4_t m4_rotation_x (
float angle_in_rad);
205static inline mat4_t m4_rotation_y (
float angle_in_rad);
206static inline mat4_t m4_rotation_z (
float angle_in_rad);
210 mat4_t m4_ortho_RH (
float left,
float right,
float bottom,
float top,
float back,
float front);
211 mat4_t m4_perspective_RH (
float vertical_field_of_view_in_deg,
float aspect_ratio,
float near_view_distance,
float far_view_distance);
219 mat4_t m4_frustum (
float left,
float right,
float bottom,
float top,
float near,
float far);
227 void m4_print (
mat4_t matrix);
228 void m4_printp (
mat4_t matrix,
int width,
int precision);
229 void m4_fprint (FILE* stream,
mat4_t matrix);
230 void m4_fprintp (FILE* stream,
mat4_t matrix,
int width,
int precision);
233 void m4_print2 (
mat4_t matrix,
const char *line_start);
234 void m4_printp2 (
mat4_t matrix,
int width,
int precision,
const char *line_start);
235 void m4_fprint2 (FILE* stream,
mat4_t matrix,
const char *line_start);
236 void m4_fprintp2 (FILE* stream,
mat4_t matrix,
int width,
int precision,
const char *line_start);
245 float len = v3_length(v);
247 return (
vec3_t){v.x / len, v.y / len, v.z / len};
255 return v3_muls(onto, v3_dot(v, onto) / v3_dot(onto, onto));
261 a.y * b.z - a.z * b.y,
262 a.z * b.x - a.x * b.z,
263 a.x * b.y - a.y * b.x
269 return acosf(v3_dot(a, b) / (v3_length(a) * v3_length(b)));
277 float m00,
float m10,
float m20,
float m30,
278 float m01,
float m11,
float m21,
float m31,
279 float m02,
float m12,
float m22,
float m32,
280 float m03,
float m13,
float m23,
float m33
284 .m[0][0] = m00, .m[1][0] = m10, .m[2][0] = m20, .m[3][0] = m30,
285 .m[0][1] = m01, .m[1][1] = m11, .m[2][1] = m21, .m[3][1] = m31,
286 .m[0][2] = m02, .m[1][2] = m12, .m[2][2] = m22, .m[3][2] = m32,
287 .m[0][3] = m03, .m[1][3] = m13, .m[2][3] = m23, .m[3][3] = m33
291static inline mat4_t m4_identity()
313 float x = scale.x, y = scale.y, z = scale.z;
322static inline mat4_t m4_rotation_x(
float angle_in_rad)
324 float s = sinf(angle_in_rad), c = cosf(angle_in_rad);
333static inline mat4_t m4_rotation_y(
float angle_in_rad)
335 float s = sinf(angle_in_rad), c = cosf(angle_in_rad);
344static inline mat4_t m4_rotation_z(
float angle_in_rad)
346 float s = sinf(angle_in_rad), c = cosf(angle_in_rad);
358 matrix.m00, matrix.m01, matrix.m02, matrix.m03,
359 matrix.m10, matrix.m11, matrix.m12, matrix.m13,
360 matrix.m20, matrix.m21, matrix.m22, matrix.m23,
361 matrix.m30, matrix.m31, matrix.m32, matrix.m33
380 for (i = 0; i < 4; i++) {
381 for (j = 0; j < 4; j++) {
383 for (k = 0; k < 4; k++) {
384 sum += a.m[k][j] * b.m[i][k];
386 result.m[i][j] = sum;
396#ifdef MATH_3D_IMPLEMENTATION
414 vec3_t normalized_axis = v3_norm(axis);
415 float x = normalized_axis.x, y = normalized_axis.y, z = normalized_axis.z;
416 float c = cosf(angle_in_rad), s = sinf(angle_in_rad);
419 c + x * x * (1 - c), x * y * (1 - c) - z * s, x * z * (1 - c) + y * s, 0,
420 y * x * (1 - c) + z * s, c + y * y * (1 - c), y * z * (1 - c) - x * s, 0,
421 z * x * (1 - c) - y * s, z * y * (1 - c) + x * s, c + z * z * (1 - c), 0,
453mat4_t m4_ortho_RH(
float left,
float right,
float bottom,
float top,
float back,
float front)
455 float l = left, r = right, b = bottom, t = top, n = front, f = back;
456 float tx = -(r + l) / (r - l);
457 float ty = -(t + b) / (t - b);
458 float tz = -(f + n) / (f - n);
461 2 / (r - l), 0, 0, tx,
462 0, 2 / (t - b), 0, ty,
463 0, 0, 2 / (f - n), tz,
488mat4_t m4_perspective_RH(
float vertical_field_of_view_in_deg,
float aspect_ratio,
float near_view_distance,
float far_view_distance)
490 float fovy_in_rad = vertical_field_of_view_in_deg / 180 * M_PI;
491 float f = 1.0f / tanf(fovy_in_rad / 2.0f);
492 float ar = aspect_ratio;
493 float nd = near_view_distance, fd = far_view_distance;
498 0, 0, (fd + nd) / (nd - fd), (2 * fd * nd) / (nd - fd),
541 vec3_t z = v3_muls(v3_norm(v3_sub(to, from)), -1);
542 vec3_t x = v3_norm(v3_cross(up, z));
543 vec3_t y = v3_cross(z, x);
546 x.x, x.y, x.z, -v3_dot(from, x),
547 y.x, y.y, y.z, -v3_dot(from, y),
548 z.x, z.y, z.z, -v3_dot(from, z),
562mat4_t m4_frustum(
float left,
float right,
float bottom,
float top,
float near,
float far)
565 if (fabs(left - right) < LG_FLOAT_EPSILON) {
566 INFO_ERR(
"left == right\n")
567 }
else if (fabs(bottom - top) < LG_FLOAT_EPSILON) {
568 INFO_ERR(
"bottom == top\n")
569 }
else if (far <= near) {
570 INFO_ERR(
"far <= near\n")
571 }
else if (near <= 0.0f) {
572 INFO_ERR(
"near <= 0.0f\n")
573 }
else if (far <= 0.0f) {
574 INFO_ERR(
"far <= 0.0f\n")
577 float width = right - left;
578 float height = top - bottom;
579 float depth = far - near;
580 float x = (2.0 * near) / width;
581 float y = (2.0 * near) / height;
582 float A = (right + left) / width;
583 float B = (top + bottom) / height;
584 float C = - (far + near) / depth;
585 float D = - (2.0 * far * near) / depth;
629 float m00 = matrix.m00, m10 = matrix.m10, m20 = matrix.m20, m30 = matrix.m30;
630 float m01 = matrix.m01, m11 = matrix.m11, m21 = matrix.m21, m31 = matrix.m31;
631 float m02 = matrix.m02, m12 = matrix.m12, m22 = matrix.m22, m32 = matrix.m32;
637 float c00 = m11 * m22 - m12 * m21, c10 = -(m01 * m22 - m02 * m21), c20 = m01 * m12 - m02 * m11;
638 float c01 = -(m10 * m22 - m12 * m20), c11 = m00 * m22 - m02 * m20, c21 = -(m00 * m12 - m02 * m10);
639 float c02 = m10 * m21 - m11 * m20, c12 = -(m00 * m21 - m01 * m20), c22 = m00 * m11 - m01 * m10;
644 float det = m00 * c00 + m10 * c10 + m20 * c20;
645 if (fabsf(det) < 0.00001) {
646 return m4_identity();
651 float i00 = c00 / det, i10 = c01 / det, i20 = c02 / det;
652 float i01 = c10 / det, i11 = c11 / det, i21 = c12 / det;
653 float i02 = c20 / det, i12 = c21 / det, i22 = c22 / det;
657 i00, i10, i20, -(i00 * m30 + i10 * m31 + i20 * m32),
658 i01, i11, i21, -(i01 * m30 + i11 * m31 + i21 * m32),
659 i02, i12, i22, -(i02 * m30 + i12 * m31 + i22 * m32),
674 matrix.m00 * position.x + matrix.m10 * position.y + matrix.m20 * position.z + matrix.m30,
675 matrix.m01 * position.x + matrix.m11 * position.y + matrix.m21 * position.z + matrix.m31,
676 matrix.m02 * position.x + matrix.m12 * position.y + matrix.m22 * position.z + matrix.m32
679 float w = matrix.m03 * position.x + matrix.m13 * position.y + matrix.m23 * position.z + matrix.m33;
680 if (w != 0 && w != 1) {
681 return vec3(result.x / w, result.y / w, result.z / w);
701 matrix.m00 * direction.x + matrix.m10 * direction.y + matrix.m20 * direction.z,
702 matrix.m01 * direction.x + matrix.m11 * direction.y + matrix.m21 * direction.z,
703 matrix.m02 * direction.x + matrix.m12 * direction.y + matrix.m22 * direction.z
706 float w = matrix.m03 * direction.x + matrix.m13 * direction.y + matrix.m23 * direction.z;
707 if (w != 0 && w != 1) {
708 return vec3(result.x / w, result.y / w, result.z / w);
714void m4_print(
mat4_t matrix)
716 m4_fprintp(STD_OUT, matrix, 6, 2);
719void m4_printp(
mat4_t matrix,
int width,
int precision)
721 m4_fprintp(STD_OUT, matrix, width, precision);
724void m4_fprint(FILE* stream,
mat4_t matrix)
726 m4_fprintp(stream, matrix, 6, 2);
729void m4_fprintp(FILE* stream,
mat4_t matrix,
int width,
int precision)
732 int w = width, p = precision, r;
734 for (r = 0; r < 4; r++) {
735 fprintf(stream,
"| %*.*f %*.*f %*.*f %*.*f |\n",
736 w, p, m.m[0][r], w, p, m.m[1][r], w, p, m.m[2][r], w, p, m.m[3][r]
742void m4_print2(
mat4_t matrix,
const char *line_start)
744 m4_fprintp2(STD_OUT, matrix, 6, 2, line_start);
747void m4_printp2(
mat4_t matrix,
int width,
int precision,
const char *line_start)
749 m4_fprintp2(STD_OUT, matrix, width, precision, line_start);
752void m4_fprint2(FILE* stream,
mat4_t matrix,
const char *line_start)
754 m4_fprintp2(stream, matrix, 6, 2, line_start);
756void m4_fprintp2(FILE* stream,
mat4_t matrix,
int width,
int precision,
const char *line_start)
759 int w = width, p = precision, r;
761 for (r = 0; r < 4; r++) {
762 fprintf(stream,
"%s| %*.*f %*.*f %*.*f %*.*f |\n",
763 line_start, w, p, m.m[0][r], w, p, m.m[1][r], w, p, m.m[2][r], w, p, m.m[3][r]