116#define M_PI 3.14159265358979323846
140static inline float v3_length(
vec3_t v) {
return sqrtf(
v.x*
v.x +
v.y*
v.y +
v.z*
v.z); }
150static inline vec4_t vec4(
float w,
float x,
float y,
float z) {
return (
vec4_t){ w,
x,
y,
z }; }
159static inline float v4_length(
vec4_t v) {
return sqrtf(
v.w*
v.w +
v.x*
v.x +
v.y*
v.y +
v.z*
v.z); }
216 float m00,
float m10,
float m20,
float m30,
217 float m01,
float m11,
float m21,
float m31,
218 float m02,
float m12,
float m22,
float m32,
219 float m03,
float m13,
float m23,
float m33
222static inline mat4_t m4_identity ();
225static inline mat4_t m4_rotation_x (
float angle_in_rad);
226static inline mat4_t m4_rotation_y (
float angle_in_rad);
227static inline mat4_t m4_rotation_z (
float angle_in_rad);
236static inline mat4_t m4_ortho (
float left,
float right,
float bottom,
float top,
float back,
float front);
237static inline mat4_t m4_perspective (
float vertical_field_of_view_in_deg,
float aspect_ratio,
float near_view_distance,
float far_view_distance);
238static inline mat4_t m4_frustum (
float left,
float right,
float bottom,
float top,
float front,
float back);
251static inline void m4_print (
mat4_t matrix);
252static inline void m4_printp (
mat4_t matrix,
int width,
int precision);
253static inline void m4_fprint (FILE* stream,
mat4_t matrix);
254static inline void m4_fprintp (FILE* stream,
mat4_t matrix,
int width,
int precision);
263 float len = v3_length(v);
265 return (
vec3_t){
v.x / len,
v.y / len,
v.z / len };
267 return (
vec3_t){ 0, 0, 0};
271 return v3_muls(onto, v3_dot(v, onto) / v3_dot(onto, onto));
276 a.
y *
b.z -
a.z *
b.y,
277 a.z *
b.x -
a.x *
b.z,
278 a.x *
b.y -
a.y *
b.x
283 return acosf( v3_dot(
a,
b) / (v3_length(
a) * v3_length(
b)) );
291 float len = v4_length(v);
293 return (
vec4_t){
v.w / len,
v.x / len,
v.y / len ,
v.z / len};
295 return (
vec4_t){ 0, 0, 0, 0};
300 a.
z *
b.w +
a.w *
b.z +
a.x *
b.y -
a.y *
b.x,
301 a.z *
b.x +
a.x *
b.z +
a.y *
b.w -
a.w *
b.y,
302 a.z *
b.y +
a.y *
b.z +
a.w *
b.x -
a.x *
b.w,
303 a.z *
b.z - (
a.w *
b.w +
a.x *
b.x +
a.y *
b.y)};
312 float m00,
float m10,
float m20,
float m30,
313 float m01,
float m11,
float m21,
float m31,
314 float m02,
float m12,
float m22,
float m32,
315 float m03,
float m13,
float m23,
float m33
318 .
m[0][0] = m00, .m[1][0] = m10, .m[2][0] = m20, .m[3][0] = m30,
319 .m[0][1] = m01, .m[1][1] = m11, .m[2][1] = m21, .m[3][1] = m31,
320 .m[0][2] = m02, .m[1][2] = m12, .m[2][2] = m22, .m[3][2] = m32,
321 .m[0][3] = m03, .m[1][3] = m13, .m[2][3] = m23, .m[3][3] = m33
325static inline mat4_t m4_identity() {
353static inline mat4_t m4_rotation_x(
float angle_in_rad) {
354 float s = sinf(angle_in_rad),
c = cosf(angle_in_rad);
363static inline mat4_t m4_rotation_y(
float angle_in_rad) {
364 float s = sinf(angle_in_rad),
c = cosf(angle_in_rad);
373static inline mat4_t m4_rotation_z(
float angle_in_rad) {
374 float s = sinf(angle_in_rad),
c = cosf(angle_in_rad);
405 for(i = 0;
i < 4;
i++) {
406 for(j = 0;
j < 4;
j++) {
408 for(k = 0;
k < 4;
k++) {
409 sum +=
a.m[
k][
j] *
b.m[
i][
k];
411 result.
m[
i][
j] = sum;
421 for(i = 0;
i < 4;
i++) {
422 for(j = 0;
j < 3;
j++) {
424 for(k = 0;
k < 4;
k++) {
425 sum +=
a.m[
k][
j] *
b.m[
i][
k];
427 result.
m[
i][
j] = sum;
431 result.
m03 = result.
m13 = result.
m23 = result.
m33 = 0.0;
438#ifndef MATH_3D_IMPLEMENTATION
440#define MATH_3D_IMPLEMENTATION
452 float x = normalized_axis.
x,
y = normalized_axis.
y,
z = normalized_axis.
z;
453 float c = cosf(angle_in_rad), s = sinf(angle_in_rad);
467static inline mat4_t m4_rotation_anti_xyz (
float alpha,
float beta,
float gamma) {
468 mat4_t rot = m4_identity ();
470 double pi = 3.141592653589793238462643383279502884197;
472 ax[0] = vec3(1.0,0.0,0.0);
473 ax[1] = vec3(0.0,1.0,0.0);
474 ax[2] = vec3(0.0,0.0,1.0);
475 qr = axis_to_quat (
ax[2], - gamma*
pi/90.0);
476 rot = m4_mul (rot, m4_quat_rotation (qr));
477 qr = axis_to_quat (
ax[1], - beta*
pi/90.0);
478 rot = m4_mul (rot, m4_quat_rotation (qr));
479 qr = axis_to_quat (
ax[0], - alpha*
pi/90.0);
480 rot = m4_mul (rot, m4_quat_rotation (qr));
484static inline mat4_t m4_rotation_xyz (
float alpha,
float beta,
float gamma) {
485 mat4_t rot = m4_identity ();
487 double pi = 3.141592653589793238462643383279502884197;
489 ax[0] = vec3(1.0,0.0,0.0);
490 ax[1] = vec3(0.0,1.0,0.0);
491 ax[2] = vec3(0.0,0.0,1.0);
492 qr = axis_to_quat (
ax[0], alpha*
pi/90.0);
493 rot = m4_mul (rot, m4_quat_rotation (qr));
494 qr = axis_to_quat (
ax[1], beta*
pi/90.0);
495 rot = m4_mul (rot, m4_quat_rotation (qr));
496 qr = axis_to_quat (
ax[2], gamma*
pi/90.0);
497 rot = m4_mul (rot, m4_quat_rotation (qr));
507 float half_angle = angle_in_rad/2.0;
508 float n = sinf(half_angle)/v3_length(
axis);
512 qr.
z = cosf(half_angle);
519 float in[4] = {vec.
w, vec.
x, vec.
y, vec.
z};
522 out[
i] = in[0] * mat.
m[0][
i] + in[1] * mat.
m[1][
i] + in[2] * mat.
m[2][
i] + in[3] * mat.
m[3][
i];
524 return vec4(out[0], out[1], out[2], out[3]);
531 1.0 - 2.0 * (q.
x * q.
x + q.
y * q.
y), 2.0 * (q.
w * q.
x + q.
y * q.
z), 2.0 * (q.
y * q.
w - q.
x * q.
z), 0,
532 2.0 * (q.
w * q.
x - q.
y * q.
z), 1.0 - 2.0 * (q.
y * q.
y + q.
w * q.
w), 2.0 * (q.
x * q.
y + q.
w * q.
z), 0,
533 2.0 * (q.
y * q.
w + q.
x * q.
z), 2.0 * (q.
x * q.
y - q.
w * q.
z), 1.0 - 2.0 * (q.
x * q.
x + q.
w * q.
w), 0,
540 mat4_t mod = m4_mul(projection, m4_translation(worldpos));
541 vec4_t out = m4_mul_v4 (mod, vec4(0.0, 0.0, 0.0, 1.0));
545 out.
w = out.
z * out.
w + 1.0;
546 out.
x = out.
z * out.
x + 1.0;
547 out.
y = out.
z * out.
y + 1.0;
548 return vec3(out.
w*viewport.
y + viewport.
w, out.
x*viewport.
z + viewport.
x, out.
y);
552 return vec3 (0.0, 0.0, -1.0);
558 vec3_t in = vec3 (2.0*(winpos.
x-viewport.
w)/viewport.
y - 1.0,
559 2.0*((viewport.
z-winpos.
y)-viewport.
x)/viewport.
z - 1.0,
561 return m4_mul_pos (m4_invert_affine(projection), in);
592static inline mat4_t m4_ortho(
float left,
float right,
float bottom,
float top,
float back,
float front) {
593 float l = left,
r = right,
b = bottom,
t = top,
n = front, f = back;
594 float tx = -(
r +
l) / (r - l);
595 float ty = -(
t +
b) / (t -
b);
596 float tz = -(f +
n) / (f - n);
598 2 / (r - l), 0, 0, tx,
599 0, 2 / (t -
b), 0, ty,
600 0, 0, 2 / (f - n), tz,
625static inline mat4_t m4_perspective(
float vertical_field_of_view_in_deg,
float aspect_ratio,
float near_view_distance,
float far_view_distance) {
626 float fovy_in_rad = vertical_field_of_view_in_deg / 180 *
M_PI;
627 float f = 1.0f / tanf(fovy_in_rad / 2.0f);
628 float ar = aspect_ratio;
629 float nd = near_view_distance, fd = far_view_distance;
634 0, 0, (fd+nd)/(nd-fd), (2*fd*nd)/(nd-fd),
644static inline mat4_t m4_frustum (
float left,
float right,
float bottom,
float top,
float front,
float back) {
645 float n = 2.0f * front;
646 float l = right - left;
647 float p = top - bottom;
648 float a = (right + left) / l;
649 float b = (top + bottom) / p;
650 float c = -(back + front) / (back - front);
651 float d = - back *
n / (back - front);
699 vec3_t z = v3_muls(v3_norm(v3_sub(to, from)), -1);
704 x.x,
x.y,
x.z, -v3_dot(from,
x),
705 y.x,
y.y,
y.z, -v3_dot(from,
y),
706 z.x,
z.y,
z.z, -v3_dot(from,
z),
744 float m00 = matrix.
m00, m10 = matrix.
m10, m20 = matrix.
m20, m30 = matrix.
m30;
745 float m01 = matrix.
m01, m11 = matrix.
m11, m21 = matrix.
m21, m31 = matrix.
m31;
746 float m02 = matrix.
m02, m12 = matrix.
m12, m22 = matrix.
m22, m32 = matrix.
m32;
752 float c00 = m11*m22 - m12*m21, c10 = -(m01*m22 - m02*m21), c20 = m01*m12 - m02*m11;
753 float c01 = -(m10*m22 - m12*m20), c11 = m00*m22 - m02*m20, c21 = -(m00*m12 - m02*m10);
754 float c02 = m10*m21 - m11*m20, c12 = -(m00*m21 - m01*m20), c22 = m00*m11 - m01*m10;
759 float det = m00*c00 + m10*c10 + m20 * c20;
760 if (fabsf(det) == 0.0000)
761 return m4_identity();
765 float i00 = c00 / det, i10 = c01 / det, i20 = c02 / det;
766 float i01 = c10 / det, i11 = c11 / det, i21 = c12 / det;
767 float i02 = c20 / det, i12 = c21 / det, i22 = c22 / det;
771 i00, i10, i20, -(i00*m30 + i10*m31 + i20*m32),
772 i01, i11, i21, -(i01*m30 + i11*m31 + i21*m32),
773 i02, i12, i22, -(i02*m30 + i12*m31 + i22*m32),
781 matrix.
m00, matrix.
m10, matrix.
m20, matrix.
m30 + translation.
x,
782 matrix.
m01, matrix.
m11, matrix.
m21, matrix.
m31 + translation.
y,
783 matrix.
m02, matrix.
m12, matrix.
m22, matrix.
m32 + translation.
z,
803 if (w != 0.0)
return vec3(result.
x / w, result.
y / w, result.
z / w);
817 matrix.
m00 * direction.
x + matrix.
m10 * direction.
y + matrix.
m20 * direction.
z,
818 matrix.
m01 * direction.
x + matrix.
m11 * direction.
y + matrix.
m21 * direction.
z,
819 matrix.
m02 * direction.
x + matrix.
m12 * direction.
y + matrix.
m22 * direction.
z
837 matrix.
m00 * direction.
x + matrix.
m10 * direction.
y + matrix.
m20 * direction.
z,
838 matrix.
m01 * direction.
x + matrix.
m11 * direction.
y + matrix.
m21 * direction.
z,
839 matrix.
m02 * direction.
x + matrix.
m12 * direction.
y + matrix.
m22 * direction.
z
842 float w = matrix.
m03 * direction.
x + matrix.
m13 * direction.
y + matrix.
m23 * direction.
z;
843 if (w != 0.0)
return vec3(result.
x / w, result.
y / w, result.
z / w);
847static inline void m4_print(
mat4_t matrix) {
848 m4_fprintp(stdout, matrix, 6, 4);
851static inline void m4_printp(
mat4_t matrix,
int width,
int precision) {
852 m4_fprintp(stdout, matrix, width, precision);
855static inline void m4_fprint(FILE* stream,
mat4_t matrix) {
856 m4_fprintp(stream, matrix, 6, 2);
859static inline void m4_fprintp(FILE* stream,
mat4_t matrix,
int width,
int precision) {
861 int w = width,
p = precision;
863 for(r = 0;
r < 4;
r++) {
864 fprintf(stream,
"| %*.*f %*.*f %*.*f %*.*f |\n",
865 w, p,
m.m[0][r], w, p,
m.m[1][r], w, p,
m.m[2][r], w, p,
m.m[3][r]
double scale(double axe)
find appropriate major tick spacing based on axis length
double precision, dimension(:), allocatable s