Several updates.

This commit is contained in:
scorpioblood 2024-05-27 22:03:10 +02:00
parent fb2e6f960d
commit 11ae45b6f2
12 changed files with 951 additions and 877 deletions

View File

@ -67,8 +67,3 @@ namespace Phanes
}
}
int test()
{
}

View File

@ -1,347 +0,0 @@
// ========================== //
// Matrix4 implementation //
// ========================== //
#include "Misc/CommonDefines.h"
#include PHANES_CORE_PCH_DEFAULT_PATH
#include "Math/Matrix4.h"
#include "Math/Vector3.h"
// ================================= //
// Class Methods for easy access //
// ================================= //
float& phanes::core::math::coretypes::Matrix4::operator()(int n, int m)
{
return this->fields[m][n];
}
phanes::core::math::coretypes::Vector4& phanes::core::math::coretypes::Matrix4::operator[](int m)
{
return (*reinterpret_cast<Vector4*>(this->fields[m]));
}
const float& phanes::core::math::coretypes::Matrix4::operator()(int n, int m) const
{
return this->fields[m][n];
}
const phanes::core::math::coretypes::Vector4& phanes::core::math::coretypes::Matrix4::operator[](int m) const
{
return (*reinterpret_cast<const Vector4*>(this->fields[m]));
}
// ================= //
// Constructors //
// ================= //
phanes::core::math::coretypes::Matrix4 phanes::core::math::coretypes::createMatrix(float fields[4][4])
{
Matrix4 a;
std::copy(&fields[0][0], &fields[4][4], &a.fields[0][0]);
return a;
}
phanes::core::math::coretypes::Matrix4 phanes::core::math::coretypes::createMatrix(float f00, float f01, float f02, float f03, float f10, float f11, float f12, float f13, float f20, float f21, float f22, float f23, float f30, float f31, float f32, float f33)
{
Matrix4 a;
a.fields[0][0] = f00; a.fields[1][0] = f01; a.fields[2][0] = f02; a.fields[3][0] = f03;
a.fields[0][1] = f10; a.fields[1][1] = f11; a.fields[2][1] = f12; a.fields[3][1] = f13;
a.fields[0][2] = f20; a.fields[1][2] = f21; a.fields[2][2] = f22; a.fields[3][2] = f23;
a.fields[0][3] = f30; a.fields[1][3] = f31; a.fields[2][3] = f32; a.fields[3][3] = f33;
return a;
}
phanes::core::math::coretypes::Matrix4 phanes::core::math::coretypes::createMatrix(const Vector4& a, const Vector4& b, const Vector4& c, const Vector4& d)
{
Matrix4 m;
m.fields[0][0] = a.x; m.fields[1][0] = b.x; m.fields[2][0] = c.x; m.fields[3][0] = d.x;
m.fields[0][1] = a.y; m.fields[1][1] = b.y; m.fields[2][1] = c.y; m.fields[3][1] = d.y;
m.fields[0][2] = a.z; m.fields[1][2] = b.z; m.fields[2][2] = c.z; m.fields[3][2] = d.z;
m.fields[0][3] = a.w; m.fields[1][3] = b.w; m.fields[2][3] = c.w; m.fields[3][3] = d.w;
return m;
}
// ============= //
// Operators //
// ============= //
void phanes::core::math::coretypes::operator+=(Matrix4& a, float s)
{
a[0] += s;
a[1] += s;
a[2] += s;
a[3] += s;
}
void phanes::core::math::coretypes::operator+=(Matrix4& a, const Matrix4& b)
{
a[0] += b[0];
a[1] += b[1];
a[2] += b[2];
a[3] += b[3];
}
void phanes::core::math::coretypes::operator-=(Matrix4& a, float s)
{
a[0] -= s;
a[1] -= s;
a[2] -= s;
a[3] -= s;
}
void phanes::core::math::coretypes::operator-=(Matrix4& a, const Matrix4& b)
{
a[0] -= b[0];
a[1] -= b[1];
a[2] -= b[2];
a[3] -= b[3];
}
void phanes::core::math::coretypes::operator*=(Matrix4& a, float s)
{
a[0] *= s;
a[1] *= s;
a[2] *= s;
a[3] *= s;
}
void phanes::core::math::coretypes::operator*=(Matrix4& a, const Matrix4& b)
{
Matrix4 c = a;
a(0, 0) = c(0, 0) * b(0, 0) + c(0, 1) * b(1, 0) + c(0, 2) * b(2, 0) + c(0, 3) * b(3, 0);
a(0, 1) = c(0, 0) * b(0, 1) + c(0, 1) * b(1, 1) + c(0, 2) * b(2, 1) + c(0, 3) * b(3, 1);
a(0, 2) = c(0, 0) * b(0, 2) + c(0, 1) * b(1, 2) + c(0, 2) * b(2, 2) + c(0, 3) * b(3, 2);
a(0, 3) = c(0, 0) * b(0, 3) + c(0, 1) * b(1, 3) + c(0, 2) * b(2, 3) + c(0, 3) * b(3, 3);
a(1, 0) = c(1, 0) * b(0, 0) + c(1, 1) * b(1, 0) + c(1, 2) * b(2, 0) + c(1, 3) * b(3, 0);
a(1, 1) = c(1, 0) * b(0, 1) + c(1, 1) * b(1, 1) + c(1, 2) * b(2, 1) + c(1, 3) * b(3, 1);
a(1, 2) = c(1, 0) * b(0, 2) + c(1, 1) * b(1, 2) + c(1, 2) * b(2, 2) + c(1, 3) * b(3, 2);
a(1, 3) = c(1, 0) * b(0, 3) + c(1, 1) * b(1, 3) + c(1, 2) * b(2, 3) + c(1, 3) * b(3, 3);
a(2, 0) = c(2, 0) * b(0, 0) + c(2, 1) * b(1, 0) + c(2, 2) * b(2, 0) + c(2, 3) * b(3, 0);
a(2, 1) = c(2, 0) * b(0, 1) + c(2, 1) * b(1, 1) + c(2, 2) * b(2, 1) + c(2, 3) * b(3, 1);
a(2, 2) = c(2, 0) * b(0, 2) + c(2, 1) * b(1, 2) + c(2, 2) * b(2, 2) + c(2, 3) * b(3, 2);
a(2, 3) = c(2, 0) * b(0, 3) + c(2, 1) * b(1, 3) + c(2, 2) * b(2, 3) + c(2, 3) * b(3, 3);
a(3, 0) = c(3, 0) * b(0, 0) + c(3, 1) * b(1, 0) + c(3, 2) * b(2, 0) + c(3, 3) * b(3, 0);
a(3, 1) = c(3, 0) * b(0, 1) + c(3, 1) * b(1, 1) + c(3, 2) * b(2, 1) + c(3, 3) * b(3, 1);
a(3, 2) = c(3, 0) * b(0, 2) + c(3, 1) * b(1, 2) + c(3, 2) * b(2, 2) + c(3, 3) * b(3, 2);
a(3, 3) = c(3, 0) * b(0, 3) + c(3, 1) * b(1, 3) + c(3, 2) * b(2, 3) + c(3, 3) * b(3, 3);
}
phanes::core::math::coretypes::Matrix4 phanes::core::math::coretypes::operator+(const Matrix4& a, float s)
{
Matrix4 m;
m[0] = a[0] + s;
m[1] = a[1] + s;
m[2] = a[2] + s;
m[3] = a[3] + s;
return m;
}
phanes::core::math::coretypes::Matrix4 phanes::core::math::coretypes::operator+(const Matrix4& a, const Matrix4& b)
{
Matrix4 m;
m[0] = a[0] + b[0];
m[1] = a[1] + b[1];
m[2] = a[2] + b[2];
m[3] = a[3] + b[3];
return m;
}
phanes::core::math::coretypes::Matrix4 phanes::core::math::coretypes::operator-(const Matrix4& a, float s)
{
Matrix4 m;
m[0] = a[0] - s;
m[1] = a[1] - s;
m[2] = a[2] - s;
m[3] = a[3] - s;
return m;
}
phanes::core::math::coretypes::Matrix4 phanes::core::math::coretypes::operator-(const Matrix4& a, const Matrix4& b)
{
Matrix4 m;
m[0] = a[0] - b[0];
m[1] = a[1] - b[1];
m[2] = a[2] - b[2];
m[3] = a[3] - b[3];
return m;
}
phanes::core::math::coretypes::Matrix4 phanes::core::math::coretypes::operator*(const Matrix4& a, float s)
{
Matrix4 m;
m[0] = a[0] * s;
m[1] = a[1] * s;
m[2] = a[2] * s;
m[3] = a[3] * s;
return m;
}
phanes::core::math::coretypes::Matrix4 phanes::core::math::coretypes::operator*(const Matrix4& a, const Matrix4& b)
{
Matrix4 m;
m(0, 0) = a(0, 0) * b(0, 0) + a(0, 1) * b(1, 0) + a(0, 2) * b(2, 0) + a(0, 3) * b(3, 0);
m(0, 1) = a(0, 0) * b(0, 1) + a(0, 1) * b(1, 1) + a(0, 2) * b(2, 1) + a(0, 3) * b(3, 1);
m(0, 2) = a(0, 0) * b(0, 2) + a(0, 1) * b(1, 2) + a(0, 2) * b(2, 2) + a(0, 3) * b(3, 2);
m(0, 3) = a(0, 0) * b(0, 3) + a(0, 1) * b(1, 3) + a(0, 2) * b(2, 3) + a(0, 3) * b(3, 3);
m(1, 0) = a(1, 0) * b(0, 0) + a(1, 1) * b(1, 0) + a(1, 2) * b(2, 0) + a(1, 3) * b(3, 0);
m(1, 1) = a(1, 0) * b(0, 1) + a(1, 1) * b(1, 1) + a(1, 2) * b(2, 1) + a(1, 3) * b(3, 1);
m(1, 2) = a(1, 0) * b(0, 2) + a(1, 1) * b(1, 2) + a(1, 2) * b(2, 2) + a(1, 3) * b(3, 2);
m(1, 3) = a(1, 0) * b(0, 3) + a(1, 1) * b(1, 3) + a(1, 2) * b(2, 3) + a(1, 3) * b(3, 3);
m(2, 0) = a(2, 0) * b(0, 0) + a(2, 1) * b(1, 0) + a(2, 2) * b(2, 0) + a(2, 3) * b(3, 0);
m(2, 1) = a(2, 0) * b(0, 1) + a(2, 1) * b(1, 1) + a(2, 2) * b(2, 1) + a(2, 3) * b(3, 1);
m(2, 2) = a(2, 0) * b(0, 2) + a(2, 1) * b(1, 2) + a(2, 2) * b(2, 2) + a(2, 3) * b(3, 2);
m(2, 3) = a(2, 0) * b(0, 3) + a(2, 1) * b(1, 3) + a(2, 2) * b(2, 3) + a(2, 3) * b(3, 3);
m(3, 0) = a(3, 0) * b(0, 0) + a(3, 1) * b(1, 0) + a(3, 2) * b(2, 0) + a(3, 3) * b(3, 0);
m(3, 1) = a(3, 0) * b(0, 1) + a(3, 1) * b(1, 1) + a(3, 2) * b(2, 1) + a(3, 3) * b(3, 1);
m(3, 2) = a(3, 0) * b(0, 2) + a(3, 1) * b(1, 2) + a(3, 2) * b(2, 2) + a(3, 3) * b(3, 2);
m(3, 3) = a(3, 0) * b(0, 3) + a(3, 1) * b(1, 3) + a(3, 2) * b(2, 3) + a(3, 3) * b(3, 3);
return m;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::operator*(const Matrix4& a, const Vector4& v)
{
Vector4 b = createVector(
a(0, 0) * v.x + a(0, 1) * v.y + a(0, 2) * v.z + a(0, 3) * v.w,
a(1, 0) * v.x + a(1, 1) * v.y + a(1, 2) * v.z + a(1, 3) * v.w,
a(2, 0) * v.x + a(2, 1) * v.y + a(2, 2) * v.z + a(2, 3) * v.w,
a(3, 0) * v.x + a(3, 1) * v.y + a(3, 2) * v.z + a(3, 3) * v.w
);
return b;
}
bool phanes::core::math::coretypes::operator==(const Matrix4& a, const Matrix4& b)
{
if (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3]) {
return true;
}
return false;
}
// =============================== //
// Matrix function definition //
// =============================== //
float phanes::core::math::coretypes::determinant(const Matrix4& a)
{
Vector3 v0 = reinterpret_cast<const Vector3&>(a[0]);
Vector3 v1 = reinterpret_cast<const Vector3&>(a[1]);
Vector3 v2 = reinterpret_cast<const Vector3&>(a[2]);
Vector3 v3 = reinterpret_cast<const Vector3&>(a[3]);
Vector3 s = crossP(v0, v1);
Vector3 t = crossP(v2, v3);
Vector3 u = a(3, 1) * v0 + a(3, 0) * v1;
Vector3 v = a(3, 3) * v2 + a(3, 2) * v3;
return s * v + t * u;
}
void phanes::core::math::coretypes::inverseNR(Matrix4& a)
{
Vector3 v0 = reinterpret_cast<const Vector3&>(a[0]);
Vector3 v1 = reinterpret_cast<const Vector3&>(a[1]);
Vector3 v2 = reinterpret_cast<const Vector3&>(a[2]);
Vector3 v3 = reinterpret_cast<const Vector3&>(a[3]);
Vector3 s = crossP(v0, v1);
Vector3 t = crossP(v2, v3);
Vector3 u = a(3, 1) * v0 + a(3, 0) * v1;
Vector3 v = a(3, 3) * v2 + a(3, 2) * v3;
float _1_det = 1.0f / determinant(a);
Vector3 r0 = crossP(v1, v) + t * a(3, 1);
Vector3 r1 = crossP(v, v0) - t * a(3, 0);
Vector3 r2 = crossP(v3, u) + s * a(3, 3);
Vector3 r3 = crossP(u, v2) - s * a(3, 2);
a = createMatrix(
r0.x, r0.y, r0.z, -dotP(v1, t),
r1.x, r1.y, r1.z, -dotP(v0, t),
r2.x, r2.y, r2.z, -dotP(v3, s),
r3.x, r3.y, r3.z, -dotP(v2, s)
);
}
void phanes::core::math::coretypes::transposeNR(Matrix4& a)
{
swap(a(0, 1), a(1, 0));
swap(a(0, 2), a(2, 0));
swap(a(0, 3), a(3, 0));
swap(a(1, 2), a(2, 1));
swap(a(1, 3), a(3, 1));
swap(a(2, 3), a(3, 2));
}
phanes::core::math::coretypes::Matrix4 phanes::core::math::coretypes::inverse(Matrix4& a)
{
Vector3 v0 = reinterpret_cast<const Vector3&>(a[0]);
Vector3 v1 = reinterpret_cast<const Vector3&>(a[1]);
Vector3 v2 = reinterpret_cast<const Vector3&>(a[2]);
Vector3 v3 = reinterpret_cast<const Vector3&>(a[3]);
Vector3 s = crossP(v0, v1);
Vector3 t = crossP(v2, v3);
Vector3 u = a(3, 1) * v0 + a(3, 0) * v1;
Vector3 v = a(3, 3) * v2 + a(3, 2) * v3;
float _1_det = 1.0f / determinant(a);
Vector3 r0 = crossP(v1, v) + t * a(3, 1);
Vector3 r1 = crossP(v, v0) - t * a(3, 0);
Vector3 r2 = crossP(v3, u) + s * a(3, 3);
Vector3 r3 = crossP(u, v2) - s * a(3, 2);
Matrix4 m = createMatrix(
r0.x, r0.y, r0.z, -dotP(v1, t),
r1.x, r1.y, r1.z, -dotP(v0, t),
r2.x, r2.y, r2.z, -dotP(v3, s),
r3.x, r3.y, r3.z, -dotP(v2, s)
);
return m;
}
phanes::core::math::coretypes::Matrix4 phanes::core::math::coretypes::transpose(const Matrix4& a)
{
Matrix4 m = a;
swap(m(0, 1), m(1, 0));
swap(m(0, 2), m(2, 0));
swap(m(0, 3), m(3, 0));
swap(m(1, 2), m(2, 1));
swap(m(1, 3), m(3, 1));
swap(m(2, 3), m(3, 2));
return m;
}
bool phanes::core::math::coretypes::isIndentityMatrix(const Matrix4& a)
{
if (a == phanes::core::math::coretypes::createMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)) {
return true;
}
return false;
}

View File

@ -1,388 +0,0 @@
// ========================== //
// Vector4 implementation //
// ========================== //
#include "Misc/CommonDefines.h"
#include PHANES_CORE_PCH_DEFAULT_PATH
#include "Math/Vector4.h"
#include "Math/Vector3.h"
#include "Math/Vector2.h"
// ===================== //
// Vector4 operators //
// ===================== //
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::createVector(float x, float y, float z, float w)
{
Vector4 _new{};
_new.x = x;
_new.y = y;
_new.z = z;
_new.w = w;
return _new;
}
void phanes::core::math::coretypes::operator+=(Vector4& a, float s)
{
a.x += s;
a.y += s;
a.z += s;
a.w += s;
}
void phanes::core::math::coretypes::operator+= (phanes::core::math::coretypes::Vector4& a, const phanes::core::math::coretypes::Vector4& b) {
a.x += b.x;
a.y += b.y;
a.z += b.z;
a.w += b.w;
}
void phanes::core::math::coretypes::operator-=(Vector4& a, float s)
{
a.x -= s;
a.y -= s;
a.z -= s;
a.w -= s;
}
void phanes::core::math::coretypes::operator-= (phanes::core::math::coretypes::Vector4& a, const phanes::core::math::coretypes::Vector4& b) {
a.x -= b.x;
a.y -= b.y;
a.z -= b.z;
a.w -= b.w;
}
void phanes::core::math::coretypes::operator*= (phanes::core::math::coretypes::Vector4& a, float s) {
a.x *= s;
a.y *= s;
a.z *= s;
a.w *= s;
}
void phanes::core::math::coretypes::operator/= (phanes::core::math::coretypes::Vector4& a, float s) {
s = 1.0f / s;
a.x *= s;
a.y *= s;
a.z *= s;
a.w *= s;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::operator*(const Vector4& a, float s)
{
Vector4 v;
v.x = a.x * s;
v.y = a.y * s;
v.z = a.z * s;
v.w = a.w * s;
return v;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::operator*(float s, const Vector4& a)
{
Vector4 v;
v.x = a.x * s;
v.y = a.y * s;
v.z = a.z * s;
v.w = a.w * s;
return v;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::operator/(const Vector4& a, float s)
{
Vector4 v;
s = 1.0f / s;
v.x = a.x * s;
v.y = a.y * s;
v.z = a.z * s;
v.w = a.w * s;
return v;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::operator/(float s, const Vector4& a)
{
Vector4 v;
s = 1.0f / s;
v.x = a.x * s;
v.y = a.y * s;
v.z = a.z * s;
v.w = a.w * s;
return v;
}
float phanes::core::math::coretypes::operator*(const Vector4& a, const Vector4& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::operator+(const Vector4& a, float s)
{
Vector4 v;
v.x = a.x + s;
v.y = a.y + s;
v.z = a.z + s;
v.w = a.w + s;
return v;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::operator+(const Vector4& a, const Vector4& b)
{
Vector4 v;
v.x = a.x + b.x;
v.y = a.y + b.y;
v.z = a.z + b.z;
v.w = a.w + b.w;
return v;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::operator-(const Vector4& a, float s)
{
Vector4 v;
v.x = a.x - s;
v.y = a.y - s;
v.z = a.z - s;
v.w = a.w - s;
return v;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::operator-(const Vector4& a, const Vector4& b)
{
Vector4 v;
v.x = a.x - b.x;
v.y = a.y - b.y;
v.z = a.z - b.z;
v.w = a.w - b.w;
return v;
}
void phanes::core::math::coretypes::operator-(Vector4& a)
{
a.x = -a.x;
a.y = -a.y;
a.z = -a.z;
a.w = -a.w;
}
bool phanes::core::math::coretypes::operator==(const Vector4& a, const Vector4& b)
{
if (abs(a.x - b.x) <= P_FLT_INAC and abs(a.y - b.y) <= P_FLT_INAC and abs(a.z - b.z) <= P_FLT_INAC and abs(a.w - b.w) <= P_FLT_INAC)
{
return true;
}
return false;
}
// ====================================== //
// Vector4 function implementation //
// ====================================== //
float phanes::core::math::coretypes::magnitude(const Vector4& a)
{
return sqrtf(a.x * a.x + a.y * a.y + a.z * a.z + a.w * a.w);
}
float phanes::core::math::coretypes::sqrMagnitude(const Vector4& a)
{
return a.x * a.x + a.y * a.y + a.z * a.z;
}
void phanes::core::math::coretypes::normalizeNR(Vector4& a)
{
a /= sqrtf(a.x * a.x + a.y * a.y + a.z * a.z);
}
float phanes::core::math::coretypes::angle(const Vector4& a, const Vector4& b)
{
return acosf(dotP(a, b) / (magnitude(a) * magnitude(b)));
}
float phanes::core::math::coretypes::dotP(const Vector4& a, const Vector4& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z;
}
void phanes::core::math::coretypes::orthogonolize(Vector4& a, Vector4& b, Vector4& c)
{
Set(b, b - project(b, a));
Set(c, c - project(c, a) - project(c, b));
}
void phanes::core::math::coretypes::orthoNormalize(Vector4& a, Vector4& b, Vector4& c)
{
Set(b, b - project(b, a));
Set(c, c - project(c, a) - project(c, b));
a /= sqrtf(a.x * a.x + a.y * a.y + a.z * a.z);
b /= sqrtf(b.x * b.x + b.y * b.y + b.z * b.z);
c /= sqrtf(c.x * c.x + c.y * c.y + c.z * c.z);
}
void phanes::core::math::coretypes::scaleToMagnitude(Vector4& a, float size)
{
a /= sqrtf(a.x * a.x + a.y * a.y + a.z * a.z);
a *= size;
}
bool phanes::core::math::coretypes::equals(const Vector4& a, const Vector4& b, float threshold)
{
if (abs(a.x - b.x) <= threshold and abs(a.y - b.y) <= threshold and abs(a.z - b.z) <= threshold)
{
return true;
}
return false;
}
void phanes::core::math::coretypes::perpspectiveDivideNR(Vector4& a)
{
float _z = 1.0f / a.z;
a.x *= _z;
a.y *= _z;
a.z = 0.0f;
}
void phanes::core::math::coretypes::maxNR(Vector4& a, const Vector4& b)
{
a.x = phanes::core::math::max(a.x, b.x);
a.y = phanes::core::math::max(a.y, b.y);
}
void phanes::core::math::coretypes::minNR(Vector4& a, const Vector4& b)
{
a.x = phanes::core::math::min(a.x, b.x);
a.y = phanes::core::math::min(a.y, b.y);
}
void phanes::core::math::coretypes::scaleNR(Vector4& a, const Vector4& b)
{
a.x *= b.x;
a.y *= b.y;
a.z *= b.z;
}
// projects vector a onto vector b
void phanes::core::math::coretypes::projectNR(Vector4& a, const Vector4& b)
{
float x = (a * b) / (b * b);
a.x = x * b.x;
a.y = x * b.y;
a.z = x * b.z;
}
// rejects vector a from vector b
void phanes::core::math::coretypes::rejectNR(Vector4& a, const Vector4& b)
{
float x = ((a * b) / (b * b));
a.x -= x * b.x;
a.y -= x * b.y;
a.z -= x * b.z;
}
void phanes::core::math::coretypes::Set(Vector4& a, const Vector4& b)
{
a.x = b.x;
a.y = b.y;
a.z = b.z;
}
// WITH RETURN: //
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::perpspectiveDivide(const Vector4& a)
{
float _z = 1.0f / a.z;
return createVector(a.x * _z, a.y * _z, a.z * _z, 0.0f);
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::lerp(const Vector4& a, const Vector4& b, float t)
{
t = phanes::core::math::clamp(t, .0f, 1.0f);
return a * (1 - t) + t * b;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::lerpUnclamped(const Vector4& a, const Vector4& b, float t)
{
return a * (1 - t) + t * b;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::slerp(const Vector4& a, const Vector4& b, float t)
{
t = phanes::core::math::clamp(t, 0.0f, 1.0f);
Vector4 _a = normalize(a);
Vector4 _b = normalize(b);
float _angle = angle(_a, _b);
return (((sinf(1.0f - t) * _angle) / sinf(_angle)) * _a) + ((sinf(t * _angle) / sinf(_angle)) * _b);
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::slerpUnclamped(const Vector4& a, const Vector4& b, float t)
{
Vector4 _a = normalize(a);
Vector4 _b = normalize(b);
float _angle = angle(_a, _b);
return (((sinf(1.0f - t) * _angle) / sinf(_angle)) * _a) + ((sinf(t * _angle) / sinf(_angle)) * _b);
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::max(const Vector4& a, const Vector4& b)
{
Vector4 _new{};
_new.x = phanes::core::math::max(a.x, b.x);
_new.y = phanes::core::math::max(a.y, b.y);
_new.z = phanes::core::math::max(a.z, b.z);
return _new;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::min(const Vector4& a, const Vector4& b)
{
Vector4 _new{};
_new.x = phanes::core::math::min(a.x, b.x);
_new.y = phanes::core::math::min(a.y, b.y);
_new.z = phanes::core::math::min(a.z, b.z);
return _new;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::scale(const Vector4& a, const Vector4& b)
{
return createVector(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::project(const Vector4& a, const Vector4& b)
{
return ((a * b) / (b * b)) * b;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::reject(const Vector4& a, const Vector4& b)
{
return a - ((a * b) / (b * b)) * b;
}
phanes::core::math::coretypes::Vector4 phanes::core::math::coretypes::normalize(const Vector4& a)
{
return a / sqrtf(a.x * a.x + a.y * a.y + a.z * a.z);
}

View File

@ -61,7 +61,9 @@ namespace Phanes::Core::Math
template<typename T>
concept IntType = std::is_integral_v<T>;
// Typenames with Arithmethic constrain have to be number.
template<typename T>
concept Arithmethic = std::is_arithmetic_v<T>;

View File

@ -124,6 +124,38 @@ namespace Phanes::Core::Math {
}
template<typename T>
FORCEINLINE T Abs(T s)
{
return abs(s);
}
template<>
FORCEINLINE float Abs<float>(float s)
{
return fabs(s);
};
template<>
FORCEINLINE long long Abs<long long>(long long s)
{
return llabs(s);
};
template<>
FORCEINLINE long Abs<long>(long s)
{
return labs(s);
};
template<>
FORCEINLINE double Abs<double>(double s)
{
return fabsl(s);
};
} // phanes
#endif // !MATH_COMMON_H

View File

@ -1,93 +0,0 @@
// This file includes the necessary header for vectorization intrinsics. If no specifics are defined SSE4.2 is used.
//
// ARM is not supported.
#include "Core/public/Math/SIMD/Platform.h"
#include "Core/public/Math/MathTypes.h"
#if P_INTRINSICS == P_INTRINSICS_AVX2
# include "PhanesVectorMathAVX2.hpp"
#elif P_INTRINSICS == P_INTRINSICS_AVX
# include "PhanesVectorMathAVX.hpp"
#elif P_INTRINSICS == P_INTRINSICS_SSE
# include "PhanesVectorMathSSE.hpp"
#elif P_INTRINSICS == P_INTRINSICS_NEON
# include "PhanesVectorMathNeon.hpp"
#elif P_INTRINSICS == P_INTRINSICS_FPU
# include "PhanesVectorMathFPU.hpp"
#endif
// Register aliases
namespace Phanes::Core::Types
{
#if P_INTRINSICS >= 1
typedef __m128 Vec4f32Reg;
typedef __m128d Vec2f64Reg;
typedef __m128i Vec4i32Reg;
typedef __m128i Vec2i64Reg;
typedef __m128i Vec4u32Reg;
typedef __m128i Vec2u64Reg;
#elif P_INTRINSICS != P_INTRINSICS_NEON
typedef struct alignas(16) Vec4f32Reg { float data[4]; } Vec4f32Reg;
typedef struct alignas(16) Vec2f64Reg { double data[2]; } Vec2f64Reg;
typedef struct alignas(16) Vec4i32Reg { int data[4]; } Vec4i32Reg;
typedef struct alignas(16) Vec2i64Reg { Phanes::Core::Types::int64 data[2]; } Vec2i64Reg;
typedef struct alignas(16) Vec4u32Reg { unsigned int data[4]; } Vec4u32Reg;
typedef struct alignas(16) Vec2u64Reg { Phanes::Core::Types::uint64 data[4]; } Vec2u64Reg;
#endif
#if P_INTRINSICS >= 2
typedef __m256 Vec4x2f32Reg;
typedef __m256 Vec8f32Reg;
typedef __m256d Vec2x2f64Reg;
typedef __m256d Vec4f64Reg;
#elif P_INTRINSICS != P_INTRINSICS_NEON
typedef struct alignas(32) Vec4x2f32Reg { float data[8]; } Vec4x2f32Reg;
typedef struct alignas(32) Vec8f32Reg { float data[8]; } Vec8f32Reg;
typedef struct alignas(32) Vec2x2f64Reg { double data[4]; } Vec2x2f64Reg;
typedef struct alignas(32) Vec4f64Reg { double data[4]; } Vec4f64Reg;
#endif
#if P_INTRINSICS == 3
typedef __m256i Vec4x2i32Reg;
typedef __m256i Vec8i32Reg;
typedef __m256i Vec2x2i64Reg;
typedef __m256i Vec4i64Reg;
typedef __m256i Vec4x2u32Reg;
typedef __m256i Vec8u32Reg;
typedef __m256i Vec2x2u64Reg;
typedef __m256i Vec4u64Reg;
#elif P_INTRINSICS != P_INTRINSICS_NEON
typedef struct alignas(32) Vec4x2i32Reg { int data[8]; } Vec4x2i32Reg;
typedef struct alignas(32) Vec8i32Reg { int data[8]; } Vec8i32Reg;
typedef struct alignas(32) Vec2x2i64Reg { Phanes::Core::Types::int64 data[4]; } Vec2x2i64Reg;
typedef struct alignas(32) Vec4i64Reg { Phanes::Core::Types::int64 data[4]; } Vec4i64Reg;
typedef struct alignas(32) Vec4x2u32Reg { unsigned int data[8]; } Vec4x2u32Reg;
typedef struct alignas(32) Vec8u32Reg { unsigned int data[8]; } Vec8u32Reg;
typedef struct alignas(32) Vec2x2u64Reg { Phanes::Core::Types::uint64 data[4]; } Vec2x2u64Reg;
typedef struct alignas(32) Vec4u64Reg { Phanes::Core::Types::uint64 data[4]; } Vec4u64Reg;
#endif
// NEON ...
}

View File

@ -8,6 +8,7 @@
#include "Core/public/Math/MathCommon.hpp"
#include "Core/public/Math/MathAbstractTypes.h"
#include "Core/public/Math/MathFwd.h"
#include "Core/public/Math/SIMD/Storage.h"
#ifndef P_DEBUG
#pragma warning(disable : 4244)
@ -884,21 +885,6 @@ namespace Phanes::Core::Math {
return v1;
};
/**
* Reflect by plane
*
* @param(v1) Vector to mirror
* @param(plane) Plane to mirror on
*
* @note result is stored in v1.
*/
template<RealType T>
FORCEINLINE TVector3<T> ReflectFromPlaneV(TVector3<T>& v1, const TVector3<T>& normal)
{
return ReflectV(v1, normal);
}
/**
* Rotates vector around axis
*

View File

@ -0,0 +1,705 @@
#pragma once
#include "Core/public/Math/Boilerplate.h"
#include "Core/public/Math/MathCommon.hpp"
#include "Core/public/Math/SIMD/Storage.h"
#include "Core/public/Math/MathFwd.h"
#include "Core/public/Math/Vector2.hpp"
namespace Phanes::Core::Math
{
/// 4D Vector defined with x, y, z, w.
template<RealType T, bool IsAlgined = false>
struct TVector4
{
public:
using Real = T;
union
{
struct {
/// <summary>
/// X component of vector
/// </summary>
T x;
/// <summary>
/// X component of vector
/// </summary>
T y;
/// <summary>
/// Z component of vector
/// </summary>
T z;
/// <summary>
/// W component of vector
/// </summary>
T w;
};
/// <summary>
/// Wraps components in one array / xmm register.
/// </summary>
union
{
typename Phanes::Core::SIMD::Storage<4, T, IsAlgined>::type comp;
typename Phanes::Core::SIMD::Storage<4, T, IsAlgined>::type data;
};
};
/// Default constructor
TVector4() = default;
/// Copy constructor
TVector4(const TVector4<Real, IsAlgined>& v);
/// <summary>
/// Construct vector from one scalar.
/// <para>x,y,z,w = s</para>
/// </summary>
/// <param name="s">Scalar</param>
TVector4(Real s);
/// <summary>
/// Construct vector from x, y, z, w components.
/// </summary>
/// <param name="_x">X component</param>
/// <param name="_y">Y component</param>
/// <param name="_z">Z component</param>
/// <param name="_w">W component</param>
TVector4(Real _x, Real _y, Real _z, Real _w);
/// <summary>
/// Construct vector from two 2d vectors like:
/// <para>x, y = v1.x, v1.y</para>
/// z, w = v2.x, v2.y
/// </summary>
/// <param name="v1">TVector2 one</param>
/// <param name="v2">TVector2 two</param>
TVector4(const TVector2<Real>& v1, const TVector2<Real>& v2);
/// <summary>
/// Construct vector from array of components
/// </summary>
/// <param name="comp">Array of at least 4 components</param>
TVector4(const Real* comp);
/// <summary>
/// Construct the vector, by calculating the way between two points.
/// </summary>
/// <param name="start">Starting point of the vector.</param>
/// <param name="end">End point of the vector.</param>
TVector4(const TPoint4<Real>& start, const TPoint4<Real>& end);
};
// ===================== //
// Vector4 operators //
// ===================== //
// Unary arithmetic operators
/// <summary>
/// Vector addition.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator+= (TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Vector - scalar addition.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator+= (TVector4<T, A>& v1, T s);
/// <summary>
/// Vector substraction.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator-= (TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Vector - scalar substraction.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator-= (TVector4<T, A>& v1, T s);
/// <summary>
/// Vector - scalar multiplication.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator*= (TVector4<T, A>& v1, T s);
/// <summary>
/// Scale vector by another vector componentwise.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator*= (TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Vector - scalar division.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator/= (TVector4<T, A>& v1, T s);
/// <summary>
/// Coponentwise vector division.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator/= (TVector4<T, A>& v1, const TVector4<T, A>& v2);
// Unary arithmetic operators
/// <summary>
/// Vector addition.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator+ (TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Vector - scalar addition.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator+ (TVector4<T, A>& v1, T s);
/// <summary>
/// Vector substraction.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator- (TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Vector - scalar substraction.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator- (TVector4<T, A>& v1, T s);
/// <summary>
/// Vector - scalar multiplication.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator* (TVector4<T, A>& v1, T s);
/// <summary>
/// Scale vector by another vector componentwise.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator* (TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Vector - scalar division.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="s">Scalar</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator/ (TVector4<T, A>& v1, T s);
/// <summary>
/// Componentwise vector division.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Computed vector.</returns>
template<RealType T, bool A>
TVector4<T, A> operator/ (TVector4<T, A>& v1, const TVector4<T, A>& v2);
// Comparison operators
/// <summary>
/// Test to vectors for equality.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns><code>True</code>, if equal and <code>false</code> if not.</returns>
template<RealType T, bool A>
bool operator==(const TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Test to vectors for inequality.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns><code>True</code>, if inequal and <code>false</code> if equal.</returns>
template<RealType T, bool A>
bool operator!=(const TVector4<T, A>& v1, const TVector4<T, A>& v2);
// Unaray increment operators
/// <summary>
/// Increment vector by one
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A>& operator++(TVector4<T, A>& v1);
/// <summary>
/// Decrement vector by one
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>v1</returns>
template<RealType T, bool A>
TVector4<T, A>& operator--(TVector4<T, A>& v1);
/// <summary>
/// Increment vector by one
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>v1</returns>
template<RealType T, bool A>
TVector4<T, A> operator++(TVector4<T, A>& v1, int);
/// <summary>
/// Decrement vector by one
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> operator--(TVector4<T, A>& v1, int);
// ====================== //
// TVector4 functions //
// ====================== //
/// <summary>
/// Get magnitude of vector.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v">Vector</param>
/// <returns>Magnitude of vector.</returns>
template<RealType T, bool A>
T Magnitude(const TVector4<T, A>& v);
/// <summary>
/// Get square of magnitude of vector.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v">Vector</param>
/// <returns>Square of magnitude of vector.</returns>
template<RealType T, bool A>
T SqrMagnitude(const TVector4<T, A>& v);
/// <summary>
/// Get magnitude of vector.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v">Vector</param>
/// <returns>Magnitude of vector.</returns>
template<RealType T, bool A>
constexpr T Length(const TVector4<T, A>& v) { return Magnitude(v); }
/// <summary>
/// Get square of magnitude of vector.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v">Vector</param>
/// <returns>Square of magnitude of vector.</returns>
template<RealType T, bool A>
constexpr T SqrLength(const TVector4<T, A>& v) { return SqrMagnitude(v); }
/// <summary>
/// Angle between two vectors.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns></returns>
template<RealType T, bool A>
T Angle(const TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Cosine of angle between two vectors.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns></returns>
template<RealType T, bool A>
T CosineAngle(const TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Normalizes a vector.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Normalized vector</returns>
template<RealType T, bool A>
TVector4<T, A> Normalize(const TVector4<T, A>& v1);
/// <summary>
/// Normalizes a vector.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> NormalizeV(TVector4<T, A>& v1);
/// <summary>
/// Normalizes a vector.
/// </summary>
/// <remarks>Doesn't check for zero vector.</remarks>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Normalized vector</returns>
template<RealType T, bool A>
TVector4<T, A> UnsafeNormalize(const TVector4<T, A>& v1);
/// <summary>
/// Normalizes a vector.
/// </summary>
/// <remarks>Doesn't check for zero vector.</remarks>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> UnsafeNormalizeV(TVector4<T, A>& v1);
/// <summary>
/// Calculates the dot product between two vectors.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Dot product between vectors.</returns>
template<RealType T, bool A>
T DotP(const TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Gets componentwise max of both vectors.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Vector with componentwise max of both vectors.</returns>
template<RealType T, bool A>
TVector4<T, A> Max(const TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Gets componentwise max of both vectors.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> MaxV(TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Gets componentwise min of both vectors.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Vector with componentwise max of both vectors.</returns>
template<RealType T, bool A>
TVector4<T, A> Min(const TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Gets componentwise min of both vectors.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector one</param>
/// <param name="v2">Vector two</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> MinV(TVector4<T, A>& v1, const TVector4<T, A>& v2);
/// <summary>
/// Inverses vector.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Inverted vector</returns>
template<RealType T, bool A>
TVector4<T, A> Negate(const TVector4<T, A>& v1);
/// <summary>
/// Inverses vector.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> NegateV(TVector4<T, A>& v1);
/// <summary>
/// Inverses the components of vector.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Vector with reciprocal of components.</returns>
template<RealType T, bool A>
TVector4<T, A> CompInverse(const TVector4<T, A>& v1);
/// <summary>
/// Inverses the components of vector.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> CompInverseV(TVector4<T, A>& v1);
/// <summary>
/// Clamp the vectors length to a magnitude.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1"></param>
/// <param name="s"></param>
/// <returns>Vector with magnitude clamped to s.</returns>
template<RealType T, bool A>
TVector4<T, A> ClampToMagnitude(const TVector4<T, A>& v1, T s);
/// <summary>
/// Clamp the vectors length to a magnitude.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="s">Magnitude</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> ClampToMagnitudeV(TVector4<T, A>& v1, T s);
/// <summary>
/// Scale vector to a magnitude
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="s">Magnitude</param>
/// <returns>Vector with scaled magnitude.</returns>
template<RealType T, bool A>
TVector4<T, A> ScaleToMagnitude(const TVector4<T, A>& v1, T s);
/// <summary>
/// Scale vector to a magnitude
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="s">Magnitude</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> ScaleToMagnitudeV(TVector4<T, A>& v1, T s);
/// <summary>
/// Reflect vector on plane.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="normal">Planes normal</param>
/// <returns>Reflected vector</returns>
template<RealType T, bool A>
TVector4<T, A> Reflect(const TVector4<T, A>& v1, const TVector4<T, A> normal);
/// <summary>
/// Reflect vector on plane.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <param name="normal">Planes normal</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> ReflectV(TVector4<T, A>& v1, const TVector4<T, A> normal);
/// <summary>
/// Project vector v1 onto v2.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector to project</param>
/// <param name="v2">Vector to project on</param>
/// <returns>Projected vector.</returns>
template<RealType T, bool A>
TVector4<T, A> Project(const TVector4<T, A>& v1, const TVector4<T, A> v2);
/// <summary>
/// Project vector v1 onto v2.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector to project</param>
/// <param name="v2">Vector to project on</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> ProjectV(const TVector4<T, A>& v1, const TVector4<T, A> v2);
/// <summary>
/// Reject vector v1 from v2.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector to reject</param>
/// <param name="v2">Vector to reject from</param>
/// <returns>Rejected vector.</returns>
template<RealType T, bool A>
TVector4<T, A> Reject(const TVector4<T, A>& v1, const TVector4<T, A> v2);
/// <summary>
/// Reject vector v1 from v2.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector to reject</param>
/// <param name="v2">Vector to reject from</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> RejectV(const TVector4<T, A>& v1, const TVector4<T, A> v2);
/// <summary>
/// Perspective divide vector.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Perspective divided vector.</returns>
template<RealType T, bool A>
TVector4<T, A> PrespectiveDivide(const TVector4<T, A>& v1);
/// <summary>
/// Perspective divide vector.
/// </summary>
/// <typeparam name="T">Type of vector</typeparam>
/// <typeparam name="A">Vector is aligned?</typeparam>
/// <param name="v1">Vector</param>
/// <returns>Copy of v1.</returns>
template<RealType T, bool A>
TVector4<T, A> PrespectiveDivideV(TVector4<T, A>& v1);
}
// No SIMD
#include "Core/public/Math/Vector4.inl"
// SIMD
#include "Core/public/Math/SIMD/SIMDIntrinsics.h"

View File

@ -0,0 +1,177 @@
#pragma once
#include "Core/public/Math/Boilerplate.h"
#include "Core/public/Math/Detail/Vector4Decl.inl"
#include "Core/public/Math/Vector4.hpp"
#include <stdio.h>
namespace Phanes::Core::Math
{
template<RealType T, bool A>
TVector4<T, A>::TVector4(const TVector4<Real, A>& v) :
x(v.x),
y(v.y),
z(v.z),
w(v.w)
{}
template<RealType T, bool A>
TVector4<T, A>::TVector4(Real _x, Real _y, Real _z, Real _w) :
x(_x),
y(_y),
z(_z),
w(_w)
{}
template<RealType T, bool A>
TVector4<T, A> operator+=(TVector4<T, A>& v1, const TVector4<T, A>& v2)
{
Detail::compute_vec4_add<T, A>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool A>
TVector4<T, A> operator+=(TVector4<T, A>& v1, T s)
{
Detail::compute_vec4_add<T, A>::map(v1, v1, s);
return v1;
}
template<RealType T, bool A>
TVector4<T, A> operator-=(TVector4<T, A>& v1, const TVector4<T, A>& v2)
{
Detail::compute_vec4_sub<T, A>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool A>
TVector4<T, A> operator-=(TVector4<T, A>& v1, T s)
{
Detail::compute_vec4_sub<T, A>::map(v1, v1, s);
return v1;
}
template<RealType T, bool A>
TVector4<T, A> operator*=(TVector4<T, A>& v1, const TVector4<T, A>& v2)
{
Detail::compute_vec4_mul<T, A>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool A>
TVector4<T, A> operator*=(TVector4<T, A>& v1, T s)
{
Detail::compute_vec4_mul<T, A>::map(v1, v1, s);
return v1;
}
template<RealType T, bool A>
TVector4<T, A> operator/=(TVector4<T, A>& v1, const TVector4<T, A>& v2)
{
Detail::compute_vec4_div<T, A>::map(v1, v1, v2);
return v1;
}
template<RealType T, bool A>
TVector4<T, A> operator/=(TVector4<T, A>& v1, T s)
{
Detail::compute_vec4_div<T, A>::map(v1, v1, s);
return v1;
}
template<RealType T, bool A>
TVector4<T, A> operator+(TVector4<T, A>& v1, const TVector4<T, A>& v2)
{
TVector4<T, A> r;
Detail::compute_vec4_add<T, A>::map(r, v1, v2);
return r;
}
template<RealType T, bool A>
TVector4<T, A> operator+(TVector4<T, A>& v1, T s)
{
TVector4<T, A> r;
Detail::compute_vec4_add<T, A>::map(r, v1, s);
return r;
}
template<RealType T, bool A>
TVector4<T, A> operator-(TVector4<T, A>& v1, const TVector4<T, A>& v2)
{
TVector4<T, A> r;
Detail::compute_vec4_sub<T, A>::map(r, v1, v2);
return r;
}
template<RealType T, bool A>
TVector4<T, A> operator-(TVector4<T, A>& v1, T s)
{
TVector4<T, A> r;
Detail::compute_vec4_sub<T, A>::map(r, v1, s);
return r;
}
template<RealType T, bool A>
TVector4<T, A> operator*(TVector4<T, A>& v1, const TVector4<T, A>& v2)
{
TVector4<T, A> r;
Detail::compute_vec4_mul<T, A>::map(r, v1, v2);
return r;
}
template<RealType T, bool A>
TVector4<T, A> operator*(TVector4<T, A>& v1, T s)
{
TVector4<T, A> r;
Detail::compute_vec4_mul<T, A>::map(r, v1, s);
return r;
}
template<RealType T, bool A>
TVector4<T, A> operator/(TVector4<T, A>& v1, const TVector4<T, A>& v2)
{
TVector4<T, A> r;
Detail::compute_vec4_div<T, A>::map(r, v1, v2);
return r;
}
template<RealType T, bool A>
TVector4<T, A> operator/(TVector4<T, A>& v1, T s)
{
TVector4<T, A> r;
Detail::compute_vec4_div<T, A>::map(r, v1, s);
return r;
}
// Comparision
template<RealType T, bool A>
TVector4<T, A> operator==(const TVector4<T, A>& v1, const TVector4<T, A>& v2)
{
return Detail::compute_vec4_eq<T, A>::map(v1, v2);
}
template<RealType T, bool A>
TVector4<T, A> operator!=(const TVector4<T, A>& v1, const TVector4<T, A>& v2)
{
return Detail::compute_vec4_ieq<T, A>::map(v1, v2);
}
// SIMD
template<>
TVector4<float, true>::TVector4(Real _x, Real _y, Real _z, Real _w) :
x(_x),
y(_y),
z(_z),
w(_w)
{
this->comp = _mm_load_ps(reinterpret_cast<float*>(&x));
}
}

View File

@ -3,3 +3,4 @@
// --- Core -------------------
#include "Core/Include.h"

View File

@ -1,15 +1,17 @@
#include <iostream>
#include <chrono>
#include <wmmintrin.h>
#include "Core/public/Math/Vector4.hpp"
namespace PMath = Phanes::Core::Math;
int main()
{
PMath::TVector4<float, true> vec0{ 3.4f, 2.3f, 1.2f, 7.5f };
PMath::TVector4<float, true> vec1{ 7.5f, 3.4f, 2.7f, 2.6f };
for (int i = 0; i < 10; i++)
/*for (int i = 0; i < 10; i++)
{
auto start = std::chrono::high_resolution_clock::now();
@ -20,8 +22,10 @@ int main()
auto end = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() << std::endl;
}
}*/
// vec0 += vec1;
std::cout << vec0.x << " " << vec0.y << " " << vec0.z << " " << vec0.w << std::endl;
return 0;