1
0
Fork 0
2022-untitled-game/code/src/engine/math.c

286 lines
5.3 KiB
C

#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);
}