#define DEG_TO_RAD(deg) ((deg) * 0.01745329251f) #define RAD_TO_DEG(rad) ((rad) * 57.29578f) const float PI_DIV_2 = 1.570796f; typedef struct { float x; float y; } vec2; typedef struct { float x; float y; float z; } vec3; typedef struct { float x; float y; float z; float w; } vec4; typedef struct { float e00; float e01; float e02; float e03; float e10; float e11; float e12; float e13; float e20; float e21; float e22; float e23; float e30; float e31; float e32; float e33; } mat4; typedef struct aabb { vec3 origin; vec3 extents; } aabb_t; typedef struct ray { vec3 origin; vec3 direction; } ray_t; float vec3_length(vec3 v) { float result; result = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); return result; } vec3 vec3_normalize(vec3 v) { vec3 result = v; float length = vec3_length(v); if (length > 0.0f) { length = 1.0f / length; result.x *= length; result.y *= length; result.z *= length; } return result; } vec3 vec3_negate(vec3 v) { vec3 result = { .x = -v.x, .y = -v.y, .z = -v.z}; return result; } vec3 vec3_add(vec3 a, vec3 b) { vec3 result; result.x = a.x + b.x; result.y = a.y + b.y; result.z = a.z + b.z; return result; } vec3 vec3_sub(vec3 a, vec3 b) { vec3 result; result.x = a.x - b.x; result.y = a.y - b.y; result.z = a.z - b.z; return result; } float vec3_dot(vec3 a, vec3 b) { float result; result = a.x*b.x + a.y*b.y + a.z*b.z; return result; } vec3 vec3_cross(vec3 a, vec3 b) { vec3 result; result.x = a.y*b.z - a.z*b.y; result.y = a.z*b.x - a.x*b.z; result.z = a.x*b.y - a.y*b.x; return result; } vec3 vec3_mult(vec3 v, float f) { vec3 result; result.x = v.x * f; result.y = v.y * f; result.z = v.z * f; return result; } mat4 mat4_identity(void) { mat4 result = {0}; result.e00 = 1.0f; result.e11 = 1.0f; result.e22 = 1.0f; result.e33 = 1.0f; return result; } mat4 mat4_multm(mat4 m0, mat4 m1) { mat4 result; result.e00 = m0.e00*m1.e00 + m0.e01*m1.e10 + m0.e02*m1.e20 + m0.e03*m1.e30; result.e01 = m0.e00*m1.e01 + m0.e01*m1.e11 + m0.e02*m1.e21 + m0.e03*m1.e31; result.e02 = m0.e00*m1.e02 + m0.e01*m1.e12 + m0.e02*m1.e22 + m0.e03*m1.e32; result.e03 = m0.e00*m1.e03 + m0.e01*m1.e13 + m0.e02*m1.e23 + m0.e03*m1.e33; result.e10 = m0.e10*m1.e00 + m0.e11*m1.e10 + m0.e12*m1.e20 + m0.e13*m1.e30; result.e11 = m0.e10*m1.e01 + m0.e11*m1.e11 + m0.e12*m1.e21 + m0.e13*m1.e31; result.e12 = m0.e10*m1.e02 + m0.e11*m1.e12 + m0.e12*m1.e22 + m0.e13*m1.e32; result.e13 = m0.e10*m1.e03 + m0.e11*m1.e13 + m0.e12*m1.e23 + m0.e13*m1.e33; result.e20 = m0.e20*m1.e00 + m0.e21*m1.e10 + m0.e22*m1.e20 + m0.e23*m1.e30; result.e21 = m0.e20*m1.e01 + m0.e21*m1.e11 + m0.e22*m1.e21 + m0.e23*m1.e31; result.e22 = m0.e20*m1.e02 + m0.e21*m1.e12 + m0.e22*m1.e22 + m0.e23*m1.e32; result.e23 = m0.e20*m1.e03 + m0.e21*m1.e13 + m0.e22*m1.e23 + m0.e23*m1.e33; result.e30 = m0.e30*m1.e00 + m0.e31*m1.e10 + m0.e32*m1.e20 + m0.e33*m1.e30; result.e31 = m0.e30*m1.e01 + m0.e31*m1.e11 + m0.e32*m1.e21 + m0.e33*m1.e31; result.e32 = m0.e30*m1.e02 + m0.e31*m1.e12 + m0.e32*m1.e22 + m0.e33*m1.e32; result.e33 = m0.e30*m1.e03 + m0.e31*m1.e13 + m0.e32*m1.e23 + m0.e33*m1.e33; return result; } vec4 mat4_multv(mat4 m, vec4 v) { vec4 result; result.x = v.x*m.e00 + v.y*m.e01 + v.z*m.e02 + v.w*m.e03; result.y = v.x*m.e10 + v.y*m.e11 + v.z*m.e12 + v.w*m.e13; result.z = v.x*m.e20 + v.y*m.e21 + v.z*m.e22 + v.w*m.e23; result.w = v.x*m.e30 + v.y*m.e31 + v.z*m.e32 + v.w*m.e33; return result; } bool aabb_check(aabb_t a, aabb_t b) { float a_left = a.origin.x - a.extents.x; float a_right = a.origin.x + a.extents.x; float a_top = a.origin.y + a.extents.y; float a_bottom = a.origin.y - a.extents.y; float b_left = b.origin.x - b.extents.x; float b_right = b.origin.x + b.extents.x; float b_top = b.origin.y + b.extents.y; float b_bottom = b.origin.y - b.extents.y; if (a_top <= b_bottom) { return false; } if (a_bottom >= b_top) { return false; } if (a_left >= b_right) { return false; } if (a_right <= b_left) { return false; } return true; } float periodic_value(float min, float max, float freq, float time) { float amp = (max-min)/2.0f; float offset = min+amp; float result = amp * sinf(freq*time) + offset; return result; } bool ray_aabb_intersect(aabb_t aabb, ray_t ray) { float s_max = 0.0f; float t_min = FLT_MAX; float min_x = aabb.origin.x - aabb.extents.x; float max_x = aabb.origin.x + aabb.extents.x; float min_y = aabb.origin.y - aabb.extents.y; float max_y = aabb.origin.y + aabb.extents.y; float s, t; float x_recip = 1.0f / ray.direction.x; if (x_recip >= 0.0f) { s = (min_x - ray.origin.x)*x_recip; t = (max_x - ray.origin.x)*x_recip; } else { s = (max_x - ray.origin.x)*x_recip; t = (min_x - ray.origin.x)*x_recip; } if (s > s_max) { s_max = s; } if (t < t_min) { t_min = t; } if (s_max > t_min) { return false; } float y_recip = 1.0f / ray.direction.y; if (y_recip >= 0.0f) { s = (min_y - ray.origin.y)*y_recip; t = (max_y - ray.origin.y)*y_recip; } else { s = (max_y - ray.origin.y)*y_recip; t = (min_y - ray.origin.y)*y_recip; } if (s > s_max) { s_max = s; } if (t < t_min) { t_min = t; } if (s_max > t_min) { return false; } return true; } float lerp(float a, float b, float t) { return (1.0f - t) * a + t * b; } float normalize(float val, float min, float max) { if (val < min) { return 0.0f; } if (val > max) { return 1.0f; } return (val - min) / (max - min); }