162 lines
2.6 KiB
C
162 lines
2.6 KiB
C
#pragma once
|
|
|
|
#include "math.h"
|
|
#include "float.h"
|
|
|
|
struct tuple {
|
|
union {
|
|
struct {
|
|
float x;
|
|
float y;
|
|
float z;
|
|
float w;
|
|
};
|
|
struct {
|
|
float r;
|
|
float g;
|
|
float b;
|
|
float a;
|
|
};
|
|
struct {
|
|
float e[4];
|
|
};
|
|
};
|
|
};
|
|
|
|
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 tuple(x, y, z, 1.0f);
|
|
}
|
|
|
|
inline static struct tuple vector(float x, float y, float z)
|
|
{
|
|
return tuple(x, y, z, 0.0f);
|
|
}
|
|
|
|
inline static struct tuple color(float r, float g, float b)
|
|
{
|
|
return tuple(r, g, b, 0.0f);
|
|
}
|
|
|
|
inline static struct tuple tuple_add(struct tuple a, struct tuple b)
|
|
{
|
|
return 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 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 tuple(
|
|
-a.x,
|
|
-a.y,
|
|
-a.z,
|
|
-a.w
|
|
);
|
|
}
|
|
|
|
inline static struct tuple tuple_mul(struct tuple a, float s)
|
|
{
|
|
return 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 tuple(
|
|
a.x / s,
|
|
a.y / s,
|
|
a.z / s,
|
|
a.w / s
|
|
);
|
|
}
|
|
|
|
inline static float tuple_magnitude(struct tuple a)
|
|
{
|
|
return 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 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
|
|
);
|
|
}
|
|
|
|
inline static struct tuple hadmard_product(struct tuple c1, struct tuple c2)
|
|
{
|
|
return tuple(
|
|
c1.r * c2.r,
|
|
c1.g * c2.g,
|
|
c1.b * c2.b,
|
|
0.0f
|
|
);
|
|
}
|
|
|
|
inline static struct tuple tuple_reflect(struct tuple in, struct tuple normal)
|
|
{
|
|
float dot = tuple_dot(in, normal);
|
|
return tuple_sub(in, tuple_mul(tuple_mul(normal, 2.0f), dot));
|
|
}
|