first commit
This commit is contained in:
commit
5c7d1905a9
25 changed files with 4034 additions and 0 deletions
129
include/math3d.hpp
Normal file
129
include/math3d.hpp
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* @file math3d.hpp
|
||||
* @brief Minimal 3D math library for render pipeline visualization
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
constexpr float PI = 3.14159265358979323846f;
|
||||
|
||||
struct Vec3 {
|
||||
float x = 0, y = 0, z = 0;
|
||||
Vec3 operator+(Vec3 o) const { return {x+o.x, y+o.y, z+o.z}; }
|
||||
Vec3 operator-(Vec3 o) const { return {x-o.x, y-o.y, z-o.z}; }
|
||||
Vec3 operator*(float s) const { return {x*s, y*s, z*s}; }
|
||||
float dot(Vec3 o) const { return x*o.x + y*o.y + z*o.z; }
|
||||
Vec3 cross(Vec3 o) const { return {y*o.z - z*o.y, z*o.x - x*o.z, x*o.y - y*o.x}; }
|
||||
float length() const { return std::sqrt(x*x + y*y + z*z); }
|
||||
Vec3 normalized() const {
|
||||
float l = length();
|
||||
return l > 0 ? Vec3{x/l, y/l, z/l} : Vec3{0, 0, 0};
|
||||
}
|
||||
};
|
||||
|
||||
inline Vec3 lerp(Vec3 a, Vec3 b, float t) {
|
||||
return {a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t};
|
||||
}
|
||||
|
||||
inline float smoothstep(float t) {
|
||||
return t * t * (3.0f - 2.0f * t);
|
||||
}
|
||||
|
||||
struct Vec4 {
|
||||
float x = 0, y = 0, z = 0, w = 1;
|
||||
Vec3 xyz() const { return {x, y, z}; }
|
||||
Vec3 perspDiv() const {
|
||||
return w != 0 ? Vec3{x/w, y/w, z/w} : Vec3{x, y, z};
|
||||
}
|
||||
};
|
||||
|
||||
struct Mat4 {
|
||||
float m[4][4] = {};
|
||||
|
||||
static Mat4 identity() {
|
||||
Mat4 r;
|
||||
r.m[0][0] = r.m[1][1] = r.m[2][2] = r.m[3][3] = 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
Vec4 operator*(Vec4 v) const {
|
||||
return {
|
||||
m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3]*v.w,
|
||||
m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3]*v.w,
|
||||
m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3]*v.w,
|
||||
m[3][0]*v.x + m[3][1]*v.y + m[3][2]*v.z + m[3][3]*v.w,
|
||||
};
|
||||
}
|
||||
|
||||
Mat4 operator*(const Mat4& o) const {
|
||||
Mat4 r;
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
for (int k = 0; k < 4; k++)
|
||||
r.m[i][j] += m[i][k] * o.m[k][j];
|
||||
return r;
|
||||
}
|
||||
|
||||
static Mat4 translate(float x, float y, float z) {
|
||||
Mat4 r = identity();
|
||||
r.m[0][3] = x; r.m[1][3] = y; r.m[2][3] = z;
|
||||
return r;
|
||||
}
|
||||
|
||||
static Mat4 scale(float sx, float sy, float sz) {
|
||||
Mat4 r = identity();
|
||||
r.m[0][0] = sx; r.m[1][1] = sy; r.m[2][2] = sz;
|
||||
return r;
|
||||
}
|
||||
|
||||
static Mat4 rotateX(float angle) {
|
||||
float c = std::cos(angle), s = std::sin(angle);
|
||||
Mat4 r = identity();
|
||||
r.m[1][1] = c; r.m[1][2] = -s;
|
||||
r.m[2][1] = s; r.m[2][2] = c;
|
||||
return r;
|
||||
}
|
||||
|
||||
static Mat4 rotateY(float angle) {
|
||||
float c = std::cos(angle), s = std::sin(angle);
|
||||
Mat4 r = identity();
|
||||
r.m[0][0] = c; r.m[0][2] = s;
|
||||
r.m[2][0] = -s; r.m[2][2] = c;
|
||||
return r;
|
||||
}
|
||||
|
||||
static Mat4 rotateZ(float angle) {
|
||||
float c = std::cos(angle), s = std::sin(angle);
|
||||
Mat4 r = identity();
|
||||
r.m[0][0] = c; r.m[0][1] = -s;
|
||||
r.m[1][0] = s; r.m[1][1] = c;
|
||||
return r;
|
||||
}
|
||||
|
||||
// Standard OpenGL-style perspective (right-handed, -Z forward)
|
||||
static Mat4 perspective(float fov, float aspect, float near, float far) {
|
||||
float t = std::tan(fov * 0.5f);
|
||||
Mat4 r;
|
||||
r.m[0][0] = 1.0f / (aspect * t);
|
||||
r.m[1][1] = 1.0f / t;
|
||||
r.m[2][2] = -(far + near) / (far - near);
|
||||
r.m[2][3] = -(2.0f * far * near) / (far - near);
|
||||
r.m[3][2] = -1.0f;
|
||||
return r;
|
||||
}
|
||||
|
||||
// Standard lookAt (right-handed)
|
||||
static Mat4 lookAt(Vec3 eye, Vec3 target, Vec3 up) {
|
||||
Vec3 f = (target - eye).normalized();
|
||||
Vec3 r = f.cross(up).normalized();
|
||||
Vec3 u = r.cross(f);
|
||||
Mat4 mat = identity();
|
||||
mat.m[0][0] = r.x; mat.m[0][1] = r.y; mat.m[0][2] = r.z; mat.m[0][3] = -r.dot(eye);
|
||||
mat.m[1][0] = u.x; mat.m[1][1] = u.y; mat.m[1][2] = u.z; mat.m[1][3] = -u.dot(eye);
|
||||
mat.m[2][0] = -f.x; mat.m[2][1] = -f.y; mat.m[2][2] = -f.z; mat.m[2][3] = f.dot(eye);
|
||||
return mat;
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue