From f3b5a84428033a0007e58a72fa8ab49c20ae509f Mon Sep 17 00:00:00 2001 From: VDm Date: Wed, 28 May 2025 23:51:54 +0400 Subject: [PATCH] feat(vector): add C3Vector methods --- tempest/vector/C2Vector.cpp | 13 ++- tempest/vector/C3Vector.cpp | 218 +++++++++++++++++++++++++++++++++++- tempest/vector/C3Vector.hpp | 73 ++++++++++-- 3 files changed, 283 insertions(+), 21 deletions(-) diff --git a/tempest/vector/C2Vector.cpp b/tempest/vector/C2Vector.cpp index f9ad583..cfbffb9 100644 --- a/tempest/vector/C2Vector.cpp +++ b/tempest/vector/C2Vector.cpp @@ -7,25 +7,26 @@ C2Vector C2Vector::FromAxisAngle(float axang, float mag) { float x = mag * CMath::cos(axang); float y = mag * CMath::sin(axang); - return C2Vector(x, y); + return { x, y }; } C2Vector C2Vector::Min(const C2Vector& a, const C2Vector& b) { float x = std::fmin(a.x, b.x); float y = std::fmin(a.y, b.y); - return C2Vector(x, y); + return { x, y }; } C2Vector C2Vector::Max(const C2Vector& a, const C2Vector& b) { float x = std::fmax(a.x, b.x); float y = std::fmax(a.y, b.y); - return C2Vector(x, y); + return { x, y }; } C2Vector C2Vector::Lerp(const C2Vector& a, const C2Vector& l, const C2Vector& h) { - return C2Vector( + return { l.x + (h.x - l.x) * a.x, - l.y + (h.y - h.y) * a.y); + l.y + (h.y - l.y) * a.y + }; } float C2Vector::Dot(const C2Vector& l, const C2Vector& r) { @@ -94,7 +95,7 @@ C2Vector& C2Vector::operator/=(const C2Vector& a) { } C2Vector C2Vector::operator-() { - return C2Vector(-this->x, -this->y); + return { -this->x, -this->y }; } float& C2Vector::operator[](uint32_t sub) { diff --git a/tempest/vector/C3Vector.cpp b/tempest/vector/C3Vector.cpp index 0e6053b..ff2193b 100644 --- a/tempest/vector/C3Vector.cpp +++ b/tempest/vector/C3Vector.cpp @@ -2,24 +2,212 @@ #include "tempest/Math.hpp" #include "tempest/Matrix.hpp" +#include + + +C3Vector C3Vector::Min(const C3Vector& a, const C3Vector& b) { + float x = std::fmin(a.x, b.x); + float y = std::fmin(a.y, b.y); + float z = std::fmin(a.z, b.z); + return { x, y, z }; +} + +C3Vector C3Vector::Max(const C3Vector& a, const C3Vector& b) { + float x = std::fmax(a.x, b.x); + float y = std::fmax(a.y, b.y); + float z = std::fmax(a.z, b.z); + return { x, y, z }; +} + +C3Vector C3Vector::Lerp(const C3Vector& a, const C3Vector& l, const C3Vector& h) { + return { + l.x + (h.x - l.x) * a.x, + l.y + (h.y - l.y) * a.y, + l.z + (h.z - l.z) * a.z + }; +} + +float C3Vector::Dot(const C3Vector& l, const C3Vector& r) { + return (l.x * r.x) + (l.y * r.y) + (l.z * r.z); +} + +C3Vector C3Vector::Cross(const C3Vector& l, const C3Vector& r) { + return { + (l.y * r.z) - (l.z * r.y), + (l.z * r.x) - (l.x * r.z), + (l.x * r.y) - (l.y * r.x) + }; +} + +C3Vector C3Vector::ProjectionOnPlane(const C3Vector& v, const C3Vector& normal) { + return v - (C3Vector::Dot(v, normal) * normal); +} + +C3Vector C3Vector::NearestOnPlane(const C3Vector& p, const C3Vector& onplane, const C3Vector& normal) { + return onplane + C3Vector::ProjectionOnPlane(p - onplane, normal); +} + +void C3Vector::Get(float& ox, float& oy, float& oz) const { + ox = this->x; + oy = this->y; + oz = this->z; +} +void C3Vector::Set(float nx, float ny, float nz) { + this->x = nx; + this->y = ny; + this->z = nz; +} + +C3Vector& C3Vector::operator+=(float a) { + this->x += a; + this->y += a; + this->z += a; + return *this; +} + +C3Vector& C3Vector::operator+=(const C3Vector& a) { + this->x += a.x; + this->y += a.y; + this->z += a.z; + return *this; +} + +C3Vector& C3Vector::operator-=(float a) { + this->x -= a; + this->y -= a; + this->z -= a; + return *this; +} + +C3Vector& C3Vector::operator-=(const C3Vector& a) { + this->x -= a.x; + this->y -= a.y; + this->z -= a.z; + return *this; +} + C3Vector& C3Vector::operator*=(float a) { this->x *= a; this->y *= a; this->z *= a; - return *this; } +C3Vector& C3Vector::operator*=(const C3Vector& a) { + this->x *= a.x; + this->y *= a.y; + this->z *= a.z; + return *this; +} + +C3Vector& C3Vector::operator/=(float a) { + this->x /= a; + this->y /= a; + this->z /= a; + return *this; +} + +C3Vector& C3Vector::operator/=(const C3Vector& a) { + this->x /= a.x; + this->y /= a.y; + this->z /= a.z; + return *this; +} + +C3Vector C3Vector::operator-() { + return { -this->x, -this->y, -this->z }; +} + +float& C3Vector::operator[](uint32_t sub) { + STORM_ASSERT(sub < C3Vector::eComponents); + switch (sub) { + case C3AXIS_Z: + return this->z; + case C3AXIS_Y: + return this->y; + case C3AXIS_X: + default: + return this->x; + } +} + +const float& C3Vector::operator[](uint32_t sub) const { + STORM_ASSERT(sub < C3Vector::eComponents); + switch (sub) { + case C3AXIS_Z: + return this->z; + case C3AXIS_Y: + return this->y; + case C3AXIS_X: + default: + return this->x; + } +} + +float C3Vector::SquaredMag() const { + return this->x * this->x + this->y * this->y + this->z * this->z; +} + float C3Vector::Mag() const { return CMath::sqrt(this->SquaredMag()); } -void C3Vector::Normalize() { - this->operator*=(1.0f / this->Mag()); +float C3Vector::SumC() const { + return this->x + this->y + this->z; } -float C3Vector::SquaredMag() const { - return this->x * this->x + this->y * this->y + this->z * this->z; +bool C3Vector::IsUnit() const { + return CMath::fequalz(this->SquaredMag(), 1.0f, 0.001f); +} + +void C3Vector::Normalize() { + float mag = this->Mag(); + STORM_ASSERT(mag > 0.0f); + mag = 1.0f / mag; + this->x *= mag; + this->y *= mag; + this->z *= mag; +} + +void C3Vector::Scale(float a) { + float mag = this->Mag(); + STORM_ASSERT(mag > 0.0f); + mag = a * 1.0f / mag; + this->x *= mag; + this->y *= mag; + this->z *= mag; +} + +C3Vector::EAxis C3Vector::MajorAxis() const { + float fx = CMath::fabs(this->x); + float fy = CMath::fabs(this->y); + float fz = CMath::fabs(this->z); + + if (fx <= fy) { + if (fy > fz) { + return C3AXIS_Y; + } + } else if (fx > fz) { + return C3AXIS_X; + } + return C3AXIS_Z; +} + +C3Vector::EAxis C3Vector::MinorAxis() const { + float fx = CMath::fabs(this->x); + float fy = CMath::fabs(this->y); + float fz = CMath::fabs(this->z); + + if (fx >= fy) { + if (fz > fy) { + return C3AXIS_Y; + } + } else if (fx >= fz) { + return C3AXIS_Z; + } else { + return C3AXIS_X; + } + return C3AXIS_Z; } C3Vector operator+(const C3Vector& l, const C3Vector& r) { @@ -30,6 +218,22 @@ C3Vector operator+(const C3Vector& l, const C3Vector& r) { return { x, y, z }; } +C3Vector operator-(const C3Vector& l, const C3Vector& r) { + float x = l.x - r.x; + float y = l.y - r.y; + float z = l.z - r.z; + + return { x, y, z }; +} + +C3Vector operator*(const C3Vector& l, float r) { + return { l.x * r, l.y * r, l.z * r }; +} + +C3Vector operator*(float l, const C3Vector& r) { + return { l * r.x, l * r.y, l * r.z }; +} + C3Vector operator*(const C3Vector& l, const C44Matrix& r) { float x = r.c0 * l.z + r.b0 * l.y + r.a0 * l.x + r.d0; float y = r.c1 * l.z + r.b1 * l.y + r.a1 * l.x + r.d1; @@ -38,6 +242,10 @@ C3Vector operator*(const C3Vector& l, const C44Matrix& r) { return { x, y, z }; } +bool operator==(const C3Vector& l, const C3Vector& r) { + return l.x == r.x && l.y == r.y && l.z == r.z; +} + bool operator!=(const C3Vector& l, const C3Vector& r) { return l.x != r.x || l.y != r.y || l.z != r.z; } diff --git a/tempest/vector/C3Vector.hpp b/tempest/vector/C3Vector.hpp index 59121ad..2f0c395 100644 --- a/tempest/vector/C3Vector.hpp +++ b/tempest/vector/C3Vector.hpp @@ -1,6 +1,7 @@ #ifndef TEMPEST_VECTOR_C_3VECTOR_HPP #define TEMPEST_VECTOR_C_3VECTOR_HPP +#include "tempest/vector/C2Vector.hpp" #include "tempest/vector/CImVector.hpp" class C44Matrix; @@ -12,30 +13,82 @@ class C3Vector { float y = 0.0f; float z = 0.0f; + enum : uint32_t { + eComponents = 3 + }; + + enum EAxis { + C3AXIS_X = 0, + C3AXIS_Y = 1, + C3AXIS_Z = 2 + }; + + // Static functions + static C3Vector Min(const C3Vector& a, const C3Vector& b); + static C3Vector Max(const C3Vector& a, const C3Vector& b); + static C3Vector Lerp(const C3Vector& a, const C3Vector& l, const C3Vector& h); + static float Dot(const C3Vector& l, const C3Vector& r); + static C3Vector Cross(const C3Vector& l, const C3Vector& r); + static C3Vector ProjectionOnPlane(const C3Vector& v, const C3Vector& normal); + static C3Vector NearestOnPlane(const C3Vector& p, const C3Vector& onplane, const C3Vector& normal); + + // Member functions C3Vector() = default; - C3Vector(float a) - : x(a) - , y(a) - , z(a) {}; - C3Vector(float x, float y, float z) - : x(x) - , y(y) - , z(z) {}; + C3Vector(const C2Vector& a) + : x(a.x) + , y(a.y) + , z(0.0f) {}; C3Vector(const CImVector& color) : x(color.r / 255.0f) , y(color.g / 255.0f) , z(color.b / 255.0f) {}; + C3Vector(float x, float y, float z) + : x(x) + , y(y) + , z(z) {}; + C3Vector(float a) + : x(a) + , y(a) + , z(a) {}; + + void Get(float& ox, float& oy, float& oz) const; + void Set(float nx, float ny, float nz); + + C3Vector& operator+=(float a); + C3Vector& operator+=(const C3Vector& a); + C3Vector& operator-=(float a); + C3Vector& operator-=(const C3Vector& a); C3Vector& operator*=(float a); - float Mag() const; - void Normalize(); + C3Vector& operator*=(const C3Vector& a); + C3Vector& operator/=(float a); + C3Vector& operator/=(const C3Vector& a); + + C3Vector operator-(); + + float& operator[](uint32_t sub); + const float& operator[](uint32_t sub) const; + float SquaredMag() const; + float Mag() const; + float SumC() const; + bool IsUnit() const; + + void Normalize(); + void Scale(float a); + + EAxis MajorAxis() const; + EAxis MinorAxis() const; }; C3Vector operator+(const C3Vector& l, const C3Vector& r); +C3Vector operator-(const C3Vector& l, const C3Vector& r); +C3Vector operator*(const C3Vector& l, float r); +C3Vector operator*(float l, const C3Vector& r); C3Vector operator*(const C3Vector& l, const C44Matrix& r); +bool operator==(const C3Vector& l, const C3Vector& r); bool operator!=(const C3Vector& l, const C3Vector& r); #endif