131 lines
2.2 KiB
C
131 lines
2.2 KiB
C
#pragma once
|
|
|
|
struct tuple {
|
|
float x;
|
|
float y;
|
|
float z;
|
|
float w;
|
|
};
|
|
|
|
inline static bool float_equal(float a, float b)
|
|
{
|
|
const float epsilon = 0.00001;
|
|
return __builtin_fabs(a - b) < epsilon;
|
|
}
|
|
|
|
inline static struct tuple tuple(float x, float y, float z, float w)
|
|
{
|
|
return (struct tuple){ x, y, z, w };
|
|
}
|
|
|
|
inline static bool tuple_is_point(struct tuple t)
|
|
{
|
|
return t.w == 1.0f;
|
|
}
|
|
|
|
inline static bool tuple_is_vector(struct tuple t)
|
|
{
|
|
return t.w == 0.0f;
|
|
}
|
|
|
|
inline static bool tuple_equal(struct tuple a, struct tuple b)
|
|
{
|
|
return
|
|
float_equal(a.x, b.x) &&
|
|
float_equal(a.y, b.y) &&
|
|
float_equal(a.z, b.z) &&
|
|
float_equal(a.w, b.w);
|
|
}
|
|
|
|
inline static struct tuple point(float x, float y, float z)
|
|
{
|
|
return (struct tuple){x, y, z, 1.0f};
|
|
}
|
|
|
|
inline static struct tuple vector(float x, float y, float z)
|
|
{
|
|
return (struct tuple){x, y, z, 0.0f};
|
|
}
|
|
|
|
inline static struct tuple tuple_add(struct tuple a, struct tuple b)
|
|
{
|
|
return (struct tuple){
|
|
a.x + b.x,
|
|
a.y + b.y,
|
|
a.z + b.z,
|
|
a.w + b.w
|
|
};
|
|
}
|
|
|
|
inline static struct tuple tuple_sub(struct tuple a, struct tuple b)
|
|
{
|
|
return (struct tuple){
|
|
a.x - b.x,
|
|
a.y - b.y,
|
|
a.z - b.z,
|
|
a.w - b.w
|
|
};
|
|
}
|
|
|
|
inline static struct tuple tuple_neg(struct tuple a)
|
|
{
|
|
return (struct tuple){
|
|
-a.x,
|
|
-a.y,
|
|
-a.z,
|
|
-a.w
|
|
};
|
|
}
|
|
|
|
inline static struct tuple tuple_mul(struct tuple a, float s)
|
|
{
|
|
return (struct tuple){
|
|
a.x * s,
|
|
a.y * s,
|
|
a.z * s,
|
|
a.w * s
|
|
};
|
|
}
|
|
|
|
inline static struct tuple tuple_div(struct tuple a, float s)
|
|
{
|
|
return (struct tuple){
|
|
a.x / s,
|
|
a.y / s,
|
|
a.z / s,
|
|
a.w / s
|
|
};
|
|
}
|
|
|
|
inline static float tuple_magnitude(struct tuple a)
|
|
{
|
|
return __builtin_sqrtf(a.x * a.x +
|
|
a.y * a.y +
|
|
a.z * a.z +
|
|
a.w * a.w);
|
|
}
|
|
|
|
inline static struct tuple tuple_normalize(struct tuple a)
|
|
{
|
|
float magnitude = tuple_magnitude(a);
|
|
return tuple_div(a, magnitude);
|
|
}
|
|
|
|
inline static float tuple_dot(struct tuple a, struct tuple b)
|
|
{
|
|
return
|
|
a.x * b.x +
|
|
a.y * b.y +
|
|
a.z * b.z;
|
|
}
|
|
|
|
inline static struct tuple tuple_cross(struct tuple a, struct tuple b)
|
|
{
|
|
return (struct tuple){
|
|
a.y * b.z - a.z * b.y,
|
|
a.z * b.x - a.x * b.z,
|
|
a.x * b.y - a.y * b.x,
|
|
0.0f
|
|
};
|
|
}
|