Created
September 28, 2024 02:11
-
-
Save ConnorBP/0ff4c1af10cba34c04a6a81f381ad577 to your computer and use it in GitHub Desktop.
My minimal modern c++ (20+latest) math class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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