101 #ifndef MATH_3D_HEADER
102 #define MATH_3D_HEADER
109 #define M_PI 3.14159265358979323846
124 static inline vec3_t vec3(
float x,
float y,
float z) {
return (
vec3_t){x, y, z };}
126 static inline vec3_t v3_adds (
vec3_t a,
float s) {
return (
vec3_t){a.x + s, a.y + s, a.z + s };}
128 static inline vec3_t v3_subs (
vec3_t a,
float s) {
return (
vec3_t){a.x - s, a.y - s, a.z - s };}
130 static inline vec3_t v3_muls (
vec3_t a,
float s) {
return (
vec3_t){a.x * s, a.y * s, a.z * s };}
132 static inline vec3_t v3_divs (
vec3_t a,
float s) {
return (
vec3_t){a.x / s, a.y / s, a.z / s };}
133 static inline float v3_length(
vec3_t v) {
return sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);}
135 static inline float v3_dot (
vec3_t a,
vec3_t b) {
return a.x * b.x + a.y * b.y + a.z * b.z;}
138 static 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;
194 static inline mat4_t mat4(
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
201 static inline mat4_t m4_identity ();
204 static inline mat4_t m4_rotation_x (
float angle_in_rad);
205 static inline mat4_t m4_rotation_y (
float angle_in_rad);
206 static 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
267 static inline float v3_angle_between(
vec3_t a,
vec3_t b)
269 return acosf(v3_dot(a, b) / (v3_length(a) * v3_length(b)));
276 static inline mat4_t mat4(
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
291 static inline mat4_t m4_identity()
313 float x = scale.x, y = scale.y, z = scale.z;
322 static inline mat4_t m4_rotation_x(
float angle_in_rad)
324 float s = sinf(angle_in_rad), c = cosf(angle_in_rad);
333 static inline mat4_t m4_rotation_y(
float angle_in_rad)
335 float s = sinf(angle_in_rad), c = cosf(angle_in_rad);
344 static 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;
393 #endif // MATH_3D_HEADER
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,
453 mat4_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,
488 mat4_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),
562 mat4_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);
714 void m4_print(
mat4_t matrix)
716 m4_fprintp(STD_OUT, matrix, 6, 2);
719 void m4_printp(
mat4_t matrix,
int width,
int precision)
721 m4_fprintp(STD_OUT, matrix, width, precision);
724 void m4_fprint(FILE* stream,
mat4_t matrix)
726 m4_fprintp(stream, matrix, 6, 2);
729 void 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]
742 void m4_print2(
mat4_t matrix,
const char *line_start)
744 m4_fprintp2(STD_OUT, matrix, 6, 2, line_start);
747 void m4_printp2(
mat4_t matrix,
int width,
int precision,
const char *line_start)
749 m4_fprintp2(STD_OUT, matrix, width, precision, line_start);
752 void m4_fprint2(FILE* stream,
mat4_t matrix,
const char *line_start)
754 m4_fprintp2(stream, matrix, 6, 2, line_start);
756 void 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]
768 #endif // MATH_3D_IMPLEMENTATION