Skip to content

Instantly share code, notes, and snippets.

@ConnorBP
Created September 28, 2024 02:11
Show Gist options
  • Save ConnorBP/0ff4c1af10cba34c04a6a81f381ad577 to your computer and use it in GitHub Desktop.
Save ConnorBP/0ff4c1af10cba34c04a6a81f381ad577 to your computer and use it in GitHub Desktop.
My minimal modern c++ (20+latest) math class
#pragma once
struct Vector2 {
float x, y;
Vector2 operator-(Vector2 other) {
x -= other.x;
y -= other.y;
return *this;
}
Vector2 operator+(Vector2 other) {
x += other.x;
y += other.y;
return *this;
}
};
typedef Vector2 * PVector2;
struct Vector3 {
float x, y, z;
Vector3 operator-(Vector3 other) {
x -= other.x;
y -= other.y;
z -= other.z;
return *this;
}
Vector3 operator+(Vector3 other) {
x += other.x;
y += other.y;
z += other.z;
return *this;
}
Vector3 operator*(float scalar) const {
return Vector3(x * scalar, y * scalar, z * scalar);
}
};
typedef Vector3 *PVector3;
inline Vector3 Lerp3(const Vector3& a, const Vector3& b, float t) {
return a * (1 - t) + b * t;
}
typedef struct _Vector4 {
float x, y, z, w;
} Vector4, * PVector4;
// row major
inline bool WorldToScreenR(Vector3 pos, Vector2& screen, float matrix[16], int windowWidth, int windowHeight)
{
//Matrix-vector Product, multiplying world(eye) coordinates by projection matrix = clipCoords
Vector4 clipCoords;
clipCoords.x = pos.x * matrix[0] + pos.y * matrix[1] + pos.z * matrix[2] + matrix[3];
clipCoords.y = pos.x * matrix[4] + pos.y * matrix[5] + pos.z * matrix[6] + matrix[7];
clipCoords.z = pos.x * matrix[8] + pos.y * matrix[9] + pos.z * matrix[10] + matrix[11];
clipCoords.w = pos.x * matrix[12] + pos.y * matrix[13] + pos.z * matrix[14] + matrix[15];
if (clipCoords.w < 0.1f)
return false;
//perspective division, dividing by clip.W = Normalized Device Coordinates
Vector3 NDC;
NDC.x = clipCoords.x / clipCoords.w;
NDC.y = clipCoords.y / clipCoords.w;
NDC.z = clipCoords.z / clipCoords.w;
screen.x = (windowWidth / 2 * NDC.x) + (NDC.x + windowWidth / 2);
screen.y = -(windowHeight / 2 * NDC.y) + (NDC.y + windowHeight / 2);
return true;
}
// column major
inline bool WorldToScreenC(Vector3 pos, Vector2& screen, float matrix[16], int windowWidth, int windowHeight)
{
//Matrix-vector Product, multiplying world(eye) coordinates by projection matrix = clipCoords
Vector4 clipCoords;
clipCoords.x = pos.x * matrix[0] + pos.y * matrix[4] + pos.z * matrix[8] + matrix[12];
clipCoords.y = pos.x * matrix[1] + pos.y * matrix[5] + pos.z * matrix[9] + matrix[13];
clipCoords.z = pos.x * matrix[2] + pos.y * matrix[6] + pos.z * matrix[10] + matrix[14];
clipCoords.w = pos.x * matrix[3] + pos.y * matrix[7] + pos.z * matrix[11] + matrix[15];
if (clipCoords.w < 0.1f)
return false;
//perspective division, dividing by clip.W = Normalized Device Coordinates
Vector3 NDC;
NDC.x = clipCoords.x / clipCoords.w;
NDC.y = clipCoords.y / clipCoords.w;
NDC.z = clipCoords.z / clipCoords.w;
//Transform to window coordinates
screen.x = (windowWidth / 2 * NDC.x) + (NDC.x + windowWidth / 2);
screen.y = -(windowHeight / 2 * NDC.y) + (NDC.y + windowHeight / 2);
//screen.z = NDC.z;
return true;
}
inline void model_to_world(Vector3 model_coords, Vector3& world_coords, float model_matrix[16])
{
world_coords.x = model_coords.x * model_matrix[0] + model_coords.y * model_matrix[4] + model_coords.z * model_matrix[8] + model_matrix[12];
world_coords.y = model_coords.x * model_matrix[1] + model_coords.y * model_matrix[5] + model_coords.z * model_matrix[9] + model_matrix[13];
world_coords.z = model_coords.x * model_matrix[2] + model_coords.y * model_matrix[6] + model_coords.z * model_matrix[10] + model_matrix[14];
}
inline Vector2 norm(Vector2 vec) {
auto new_vec = vec;
auto mag = sqrtf(pow(new_vec.x, 2.0) + pow(new_vec.y, 2.0));
new_vec = Vector2{ new_vec.x / mag, new_vec.y / mag };
return new_vec;
}
inline float magnitude(Vector3 &vec) {
return sqrtf(pow(vec.x, 2.0) + pow(vec.y, 2.0) + pow(vec.z, 2.0));
}
inline float magnitude(Vector2 &vec) {
return sqrtf(pow(vec.x, 2.0) + pow(vec.y, 2.0));
}
inline float GetDistance(Vector3 &from, Vector3 &to) {
Vector3 vec = Vector3{ to.x - from.x, to.y - from.y, to.z - from.z };
return magnitude(vec);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment