Add logging (spdlog) and abstract the api.

This commit is contained in:
scorpioblood 2024-05-15 23:06:11 +02:00
parent 08c2d7b9d1
commit cd02a6014b
37 changed files with 8588 additions and 53 deletions

29
.gitignore vendored
View File

@ -1,3 +1,23 @@
# Exclude folders
bin/
bin-int/
external/
# Exclude files
# Temporary excludes
Matrix2d.cpp
Matrix3.cpp
Matrix4.cpp
Vector4.cpp
Matrix3.h
Matrix4.h
Vector4.h
############################################################################################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
@ -402,12 +422,3 @@ FodyWeavers.xsd
*.sln
*.vcxproj
*.filters
# Exclude other folders
bin/
bin-int/
external/

3
.gitmodules vendored
View File

@ -0,0 +1,3 @@
[submodule "Engine/ThirdParty/spdlog"]
path = Engine/ThirdParty/spdlog
url = https://github.com/gabime/spdlog

1
Engine/ThirdParty/spdlog vendored Submodule

@ -0,0 +1 @@
Subproject commit 27cb4c76708608465c413f6d0e6b8d99a4d84302

View File

@ -3,6 +3,16 @@
#ifdef P_WIN_BUILD
#ifdef P_BUILD_LIB
#define PHANES_CORE __declspec(dllexport)
#else
#define PHANES_CORE __declspec(dllimport)
#endif
#ifdef P_DEBUG
#define P_DEBUGBREAK DebugBreak();

View File

@ -1,12 +1,16 @@
#pragma once
// --- Logging -------------------------------------
#include "Core/public/Logging/Logging.h"
// --- Starting point ------------------------------
#include "Core/public/StartingPoint/StartingPoint.h"
#include "Core/public/StartingPoint/EntryPoint.h"
// --- OSAL ----------------------------------------
#include "Core/public/OSAL/PlatformTypes.h"
@ -18,6 +22,4 @@
// Starting point
namespace PApp = Phanes::Core::Application;
using namespace Phanes::Core::Math::UnitLiterals;
#endif

View File

@ -0,0 +1,14 @@
#include "PhanesEnginePCH.h"
#include "Core/public/Logging/Logging.h"
void Phanes::Core::Logging::Init()
{
spdlog::set_pattern("%^[%n][%T][%l]:%$ %v");
_PEngineLogger = spdlog::stdout_color_mt("PHANES");
_PEngineLogger->set_level(spdlog::level::trace);
_PAppLogger = spdlog::stdout_color_mt("GAME");
_PAppLogger->set_level(spdlog::level::trace);
}

View File

@ -0,0 +1,15 @@
#include "PhanesEnginePCH.h"
#include "Core/public/Math/IntPoint.h"
template<IntType T, RealType Rt>
Rt Phanes::Core::Math::Distance(const TIntPoint3<T>& p1, const TIntPoint3<T>& p2)
{
return Magnitude(p2 - p1);
}
template<IntType T, RealType Rt>
Rt Phanes::Core::Math::Distance(const TIntPoint2<T>& p1, const TIntPoint2<T>& p2)
{
return Magnitude(p2 - p1);
}

View File

@ -0,0 +1,461 @@
// ============================== //
// TIntVector2 implementation //
// ============================== //
#include "PhanesEnginePCH.h"
#include "Core/public/Math/IntVector2.h"
#include "Core/public/Math/IntPoint.h"
//#include "Math/Matrix2.h"
//#include "Math/Matrix2.h"
//#include "Math/Vector3.h"
//#include "Math/Vector4.h"
//#include "Math/IntVector2.h"
//#include "Math/IntVector3.h"
//#include "Math/IntVector4.h"
// ============================ //
// TIntVector2 constructors //
// ============================ //
template<IntType T>
Phanes::Core::Math::TIntVector2<T>::TIntVector2(const T x, const T y)
{
this->x = x;
this->y = y;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T>::TIntVector2(const T* comp)
{
static_assert(sizeof(comp) > 2 * sizeof(T), "PHANES_CORE (IntVector2.cpp): Setting 2D vector coordinates by an array, comp must have a size of at least 2 components.");
memcpy(this->comp, comp, sizeof(T) * 2);
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T>::TIntVector2(const TIntPoint2<T>& start, const TIntPoint2<T>& end)
{
this->x = end.x - start.x;
this->y = end.y - start.y;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T>::TIntVector2(const TIntVector3<T>& v)
{
this->x = v.x;
this->y = v.y;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T>::TIntVector2(const TIntVector2<T>& v)
{
memcpy(this->comp, comp, sizeof(T) * 2);
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T>::TIntVector2(TIntVector2<T>&& v)
{
this->comp = v.comp;
v.comp = nullptr;
}
// ========================= //
// TIntVector2 operators //
// ========================= //
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::operator+=(TIntVector2<T>& v1, T s)
{
v1.x += s;
v1.y += s;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::operator+=(TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
v1.x += v2.x;
v1.y += v2.y;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::operator-=(TIntVector2<T>& v1, T s)
{
v1.x -= s;
v1.y -= s;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::operator-=(TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
v1.x -= v2.x;
v1.y -= v2.y;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::operator*=(TIntVector2<T>& v1, T s)
{
v1.x *= s;
v1.y *= s;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::operator*(const TIntVector2<T>& v1, T s)
{
return TIntVector2<T>(v1.x * s, v1.y * s);
}
template<IntType T>
inline Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::operator*(T s, const TIntVector2<T>& v1)
{
return v1 * s;
}
template<IntType T, IntType Rt>
Rt Phanes::Core::Math::operator* (const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return v1.x * v2.x + v1.y * v2.y;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::operator+(const TIntVector2<T>& v1, T s)
{
return TIntVector2<T>(v1.x + s, v1.y + s);
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::operator+(const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return TIntVector2<T>(v1.x + v2.x, v1.y + v2.y);
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::operator-(const TIntVector2<T>& v1, T s)
{
return TIntVector2<T>(v1.x - s, v1.y - s);
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::operator-(const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return TIntVector2<T>(v1.x - v2.x, v1.y - v2.y);
}
template<IntType T>
void Phanes::Core::Math::operator-(TIntVector2<T>& v1)
{
v1.x = -v1.x;
v1.y = -v1.y;
}
template<IntType T>
bool Phanes::Core::Math::operator== (const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return (abs(v1.x - v1.x) < P_FLT_INAC && abs(v1.y - v1.y) < P_FLT_INAC);
}
template<IntType T>
bool Phanes::Core::Math::operator!=(const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return (abs(v1.x - v1.x) > P_FLT_INAC || abs(v1.y - v1.y) > P_FLT_INAC);
}
template<IntType T, IntType Rt>
Rt Phanes::Core::Math::Magnitude(const TIntVector2<T>& v1)
{
return sqrtf(v1.x * v1.x + v1.y * v1.y);
}
template<IntType T>
T Phanes::Core::Math::SqrMagnitude(const TIntVector2<T>& v1)
{
return v1.x * v1.x + v1.y * v1.y;
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::DivideTruncV(TIntVector2<T>& v1, T s)
{
Rt _s = (Rt)1.0 / s;
v1.x = trunc(v1.x * s);
v1.y = trunc(v1.y * s);
return v1;
}
template<IntType T, RealType Rt>
Rt Phanes::Core::Math::Angle(const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return acos((v1 * v2) / Magnitude(v1) * Magnitude(v2));
}
template<IntType T, RealType Rt>
Rt Phanes::Core::Math::CosineAngle(const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return (v1 * v2) / Magnitude(v1) * Magnitude(v2);
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::SignVectorV(TIntVector2<T>& v1)
{
v1.x = (v1.x > 0) ? 1 : -1;
v1.y = (v1.y > 0) ? 1 : -1;
return v1;
}
template<IntType T>
T Phanes::Core::Math::DotP(const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return v1.x * v2.x + v1.y * v2.y;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::MaxV(TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
v1.x = Phanes::Core::Math::Max(v1.x, v2.x);
v1.y = Phanes::Core::Math::Max(v1.y, v2.y);
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::MinV(TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
v1.x = Phanes::Core::Math::Min(v1.x, v2.x);
v1.y = Phanes::Core::Math::Min(v1.y, v2.y);
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::GetPerpendicularV(TIntVector2<T>& v1)
{
T x = v1.x;
v1.x = v1.y;
v1.y = -v1.x;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::GetReversePerpendicularV(TIntVector2<T>& v1)
{
T x = v1.x;
v1.x = -v1.y;
v1.y = v1.x;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::ScaleV(TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
v1.x *= v2.x;
v1.y *= v2.y;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::Set(TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
v1 = v2;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::Set(TIntVector2<T>& v1, T x, T y)
{
v1.x = x;
v1.y = y;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::NegateV(TIntVector2<T>& v1)
{
v1.x = -v1.x;
v1.y = -v1.y;
}
template<IntType T>
inline bool Phanes::Core::Math::IsNormalized(const TIntVector2<T>& v1)
{
return (SqrMagnitude(v1));
}
template<IntType T>
inline bool Phanes::Core::Math::IsPerpendicular(const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return (abs(DotP(v1, v2)) = 0);
}
template<IntType T>
inline bool Phanes::Core::Math::IsParallel(const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return (abs(DotP(v1, v2)) = 1);
}
template<IntType T>
inline bool Phanes::Core::Math::IsCoincident(const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return (DotP(v1, v2) > 1);
}
//
//Phanes::Core::Math::Matrix2 Phanes::Core::Math::OuterProduct(const TIntVector2& v1, const TIntVector2& v2)
//{
// return Matrix2(
// v1.x * v2.x, v1.x * v2.y,
// v1.y * v2.x, v1.y * v2.y
// );
//}
// ================================================================= //
// TIntVector2 static function implementation with return values //
// ================================================================= //
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector2<Rt> Phanes::Core::Math::Reflect(const TIntVector2<T>& v1, const TVector2<Rt>& normal)
{
return TVector2<Rt>(v1 - (2 * (v1 * normal) * normal));
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::Scale(const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return TIntVector2<T>(v1.x * v2.x, v1.y * v2.y);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector2<Rt> Phanes::Core::Math::CompInverse(const TIntVector2<T>& v1)
{
return TVector2<T>(1.0f / v1.x, 1.0f / v1.y);
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::Negate(const TIntVector2<T>& v1)
{
return TIntVector2<T>(-v1.x, -v1.y);
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::GetPerpendicular(const TIntVector2<T>& v1)
{
return TIntVector2<T>(v1.y, -v1.x);
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::GetReversePerpendicular(const TIntVector2<T>& v1)
{
return TIntVector2<T>(-v1.y, v1.x);
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::Min(const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return TIntVector2<T>(Phanes::Core::Math::Min(v1.x, v2.x), Phanes::Core::Math::Min(v1.y, v2.y));
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::Max(const TIntVector2<T>& v1, const TIntVector2<T>& v2)
{
return TIntVector2<T>(Phanes::Core::Math::Max(v1.x, v2.x), Phanes::Core::Math::Max(v1.y, v2.y));
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector2<Rt> Phanes::Core::Math::Normalize(const TIntVector2<T>& v1)
{
float vecNorm = Magnitude(v1);
return (vecNorm < P_FLT_INAC) ? PIntZeroVector2(T) : (v1 / vecNorm);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector2<Rt> Phanes::Core::Math::UnsafeNormalize(const TIntVector2<T>& v1)
{
return TVector2(v1 / Magnitude(v1));
}
template<IntType T>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::SignVector(const TIntVector2<T>& v1)
{
return TIntVector2<T>((v1.x > 0) ? 1 : -1, (v1.y > 0) ? 1 : -1);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector2<Rt> Phanes::Core::Math::BindToSquare(const TIntVector2<T>& v1, T radius)
{
float k = (abs(v1.x) > abs(v1.y)) ? abs(radius / v1.x) : abs(radius / v1.y);
return v1 * k;
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector2<Rt> Phanes::Core::Math::ClampToSquare(const TIntVector2<T>& v1, T radius)
{
float prime = (abs(v1.x) > abs(v1.y)) ? v1.x : v1.y;
float k = (prime > radius) ? abs(radius / prime) : 1.0f;
return TVector2(v1 * k);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector2<Rt> Phanes::Core::Math::Lerp(const TIntVector2<T>& startVec, const TIntVector2<T>& destVec, Rt t)
{
t = Phanes::Core::Math::Clamp(t, (T)0.0, (T)1.0);
return ((Rt)t * destVec) + (((Rt)1.0 - t) * startVec);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector2<Rt> Phanes::Core::Math::LerpUnclamped(const TIntVector2<T>& startVec, const TIntVector2<T>& destVec, Rt t)
{
return ((Rt)t * destVec) + (((Rt)1.0 - t) * startVec);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector2<Rt> Phanes::Core::Math::Rotate(const TIntVector2<T>& v1, Rt angle)
{
float sinAngle = sin(angle);
float cosAngle = cos(angle);
return TVector2<Rt>((Rt)v1.x * cosAngle - (Rt)v1.y * sinAngle, (Rt)v1.y * cosAngle + (Rt)v1.x * sinAngle);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector2<Rt> Phanes::Core::Math::ClockwiseRotate(const TIntVector2<T>& v1, Rt angle)
{
return Rotate(v1, -angle);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TIntVector2<T> Phanes::Core::Math::DivideTrunc(const TIntVector2<T>& v1, T s)
{
Rt _s = (Rt)1.0 / s;
return TIntVector2<T>(trunc(v1.x * _s), trunc(v1.y * _s));
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector2<Rt> Phanes::Core::Math::DivideFloat(const TIntVector2<T>& v1, T s)
{
Rt _s = (Rt)1.0 / s;
return TIntVector2<T>((Rt)v1.x * _s, (Rt)v1.y * _s);
}

View File

@ -0,0 +1,514 @@
// ============================== //
// TIntVector2 implementation //
// ============================== //
#include "PhanesEnginePCH.h"
#include "Core/public/Math/IntVector3.h"
#include "Core/public/Math/IntPoint.h"
#include "Core/public/Math/Plane.h"
template<IntType T>
inline Phanes::Core::Math::TIntVector3<T>::TIntVector3(const T x, const T y, const T z)
{
this->x = x;
this->y = y;
this->z = z;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T>::TIntVector3(const T* comp)
{
static_assert(sizeof(comp) > 2 * sizeof(T), "PHANES_CORE (IntVector3.cpp): Setting 3D vector coordinates by an array, comp must have a size of at least 3 components.");
memcpy(this->comp, comp, sizeof(T) * 3);
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T>::TIntVector3(const TIntVector2<T>& v)
{
this->x = v.x;
this->y = v.y;
this->z = (T)0;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T>::TIntVector3(const TIntPoint3<T>& start, const TIntPoint3<T>& end)
{
this->x = end.x - start.x;
this->y = end.y - start.y;
this->z = end.z - start.z;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T>::TIntVector3(const TIntVector3<T>& v)
{
memcpy(this->comp, comp, sizeof(T) * 3);
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T>::TIntVector3(TIntVector3<T>&& v)
{
this->comp = v.comp;
v.comp = nullptr;
}
// ========================= //
// TIntVector3 operators //
// ========================= //
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::operator+=(TIntVector3<T>& v1, T s)
{
v1.x += s;
v1.y += s;
v1.z += s;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::operator+=(TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
v1.x += v2.x;
v1.y += v2.y;
v1.z += v2.z;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::operator-=(TIntVector3<T>& v1, T s)
{
v1.x -= s;
v1.y -= s;
v1.z -= s;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::operator-=(TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
v1.x -= v2.x;
v1.y -= v2.y;
v1.z -= v2.z;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::operator*=(TIntVector3<T>& v1, T s)
{
v1.x *= s;
v1.y *= s;
v1.z *= s;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::operator*(const TIntVector3<T>& v1, T s)
{
return TIntVector3<T>(v1.x * s.v1.y * s, v1.z * s);
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::operator*(T s, const TIntVector3<T>& v1)
{
return v1 * s;
}
template<IntType T>
T Phanes::Core::Math::operator*(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::operator+(const TIntVector3<T>& v1, T s)
{
return TIntVector3<T>(v1.x + s.v1.y + s, v1.z + s);
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::operator+(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return TIntVector3<T>(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::operator-(const TIntVector3<T>& v1, T s)
{
return TIntVector3<T>(v1.x - s.v1.y - s, v1.z - s);
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::operator-(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return TIntVector3<T>(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::operator-(TIntVector3<T>& v1)
{
v1.x = -v1.x;
v1.y = -v1.y;
v1.z = -v1.z;
return v1;
}
template<IntType T>
bool Phanes::Core::Math::operator==(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return (abs(v1.x - v2.x) < P_FLT_INAC && abs(v1.y - v2.y) < P_FLT_INAC && abs(v1.z - v2.z) < P_FLT_INAC);
}
template<IntType T>
bool Phanes::Core::Math::operator!=(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return (abs(v1.x - v2.x) > P_FLT_INAC || abs(v1.y - v2.y) > P_FLT_INAC || abs(v1.z - v2.z) > P_FLT_INAC);
}
// ======================================= //
// TIntVector3 function implementation //
// ======================================= //
template<IntType T, RealType Rt>
Rt Phanes::Core::Math::Magnitude(const TIntVector3<T>& v1)
{
return sqrt(DotP(v1, v1));
}
template<IntType T>
T Phanes::Core::Math::SqrMagnitude(const TIntVector3<T>& v1)
{
return DotP(v1, v1);
}
template<IntType T, RealType Rt>
Rt Phanes::Core::Math::Angle(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return acos((v1 * v2) / (Magnitude(v1) * Magnitude(v2)));
}
template<IntType T>
T Phanes::Core::Math::DotP(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::VectorTriple(const TIntVector3<T>& v1, const TIntVector3<T>& v2, const TIntVector3<T>& v3)
{
return CrossP(CrossP(v1, v2), v3);
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::SignVector(const TIntVector3<T>& v1)
{
v1.x = (v1.x > 0) - (v1.x < 0);
v1.y = (v1.y > 0) - (v1.y < 0);
v1.z = (v1.z > 0) - (v1.z < 0);
return v1;
}
template<IntType T>
bool Phanes::Core::Math::Equals(const TIntVector3<T>& v1, const TIntVector3<T>& v2, T threshold)
{
return (abs(v1.x - v2.x) < threshold && abs(v1.y - v2.y) < threshold && abs(v1.z - v2.z) < threshold);
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::CrossPV(TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
float x = v1.x;
float y = v1.y;
float z = v1.z;
v1.x = (y * v2.z) - (z * v2.y);
v1.y = (z * v2.x) - (x * v2.z);
v1.z = (x * v2.y) - (y * v2.x);
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::MaxV(TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
v1.x = Max(v1.x, v2.x);
v1.y = Max(v1.y, v2.y);
v1.z = Max(v1.z, v2.z);
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::MinV(TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
v1.x = Min(v1.x, v2.x);
v1.y = Min(v1.y, v2.y);
v1.z = Min(v1.z, v2.z);
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::NegateV(TIntVector3<T>& v1)
{
v1.x = -v1.x;
v1.y = -v1.y;
v1.z = -v1.z;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::ScaleV(TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
v1.x *= v2.x;
v1.y *= v2.y;
v1.z *= v2.z;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::Set(TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
v1 = v2;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::Set(TIntVector3<T>& v1, T x, T y, T z)
{
v1.x = x;
v1.y = y;
v1.z = z;
return v1;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::SignVectorV(TIntVector3<T>& v1)
{
v1.x = (v1.x > 0) ? 1 : 0;
v1.y = (v1.y > 0) ? 1 : 0;
v1.z = (v1.z > 0) ? 1 : 0;
return v1;
}
template<IntType T>
T Phanes::Core::Math::ScalarTriple(const TIntVector3<T>& v1, const TIntVector3<T>& v2, const TIntVector3<T>& v3)
{
return CrossP(v1, v2) * v3;
}
template<IntType T>
T Phanes::Core::Math::CosineAngle(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return (v1 * v2) / (Magnitude(v1) * Magnitude(v2));
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::VectorTripleV(TIntVector3<T>& v1, const TIntVector3<T>& v2, const TIntVector3<T>& v3)
{
CrossPV(CrossPV(v1, v2), v3);
return v1;
}
template<IntType T>
bool Phanes::Core::Math::IsPerpendicular(const TIntVector3<T>& v1, const TIntVector3<T>& v2, T threshold)
{
return (abs(DotP(v1, v2)) < threshold);
}
template<IntType T>
bool Phanes::Core::Math::IsParallel(const TIntVector3<T>& v1, const TIntVector3<T>& v2, T threshold)
{
return (abs(DotP(v1, v2)) > threshold);
}
template<IntType T>
bool Phanes::Core::Math::IsCoincident(const TIntVector3<T>& v1, const TIntVector3<T>& v2, T threshold)
{
return (DotP(v1, v2) > threshold);
}
template<IntType T>
bool Phanes::Core::Math::IsNormalized(const TIntVector3<T>& v1, T threshold)
{
return (SqrMagnitude(v1) < threshold);
}
template<IntType T>
bool Phanes::Core::Math::IsCoplanar(const TIntVector3<T>& v1, const TIntVector3<T>& v2, const TIntVector3<T>& v3, T threshold)
{
return (ScalarTriple(v1, v2, v3) < threshold);
}
// =============== //
// With Return //
// =============== //
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::Normalize(const TIntVector3<T>& v1)
{
float vecNorm = Magnitude(v1);
return (vecNorm < P_FLT_INAC) ? PZeroVector3(T) : v1 / vecNorm;
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::UnsafeNormalize(const TIntVector3<T>& v1)
{
return v1 / Magnitude(v1);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::Reflect(const TIntVector3<T>& v1, const TVector3<Rt>& normal)
{
return v1 - (2 * (v1 * normal) * normal);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::PerspectiveDivide(const TIntVector3<T>& v1)
{
float _z = (T)1.0 / v1.z;
return TIntVector3<T>(v1.x * _z, v1.y * _z, (T)0.0);
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::CrossP(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return TIntVector3<T>((v1.y * v2.z) - (v1.z * v2.y),
(v1.z * v2.x) - (v1.x * v2.z),
(v1.x * v2.y) - (v1.y * v2.x));
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::Lerp(const TIntVector3<T>& start, const TIntVector3<T>& dest, Rt t)
{
t = Clamp(t, (Rt)0.0, (Rt), 1.0);
return ((Rt)1.0 - t) * start + t * dest;
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::LerpUnclamped(const TIntVector3<T>& start, const TIntVector3<T>& dest, Rt t)
{
return (1 - t) * start + t * dest;
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::Max(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return TIntVector3<T>((v1.x > v2.x) ? v1.x : v2.x,
(v1.y > v2.y) ? v1.y : v2.y,
(v1.z > v2.z) ? v1.z : v2.z);
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::Min(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return TIntVector3<T>((v1.x < v2.x) ? v1.x : v2.x,
(v1.y < v2.y) ? v1.y : v2.y,
(v1.z < v2.z) ? v1.z : v2.z);
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::Negate(const TIntVector3<T>& v1)
{
return TIntVector3<T>(-v1.x, -v1.y, -v1.z);
}
template<IntType T>
Phanes::Core::Math::TIntVector3<T> Phanes::Core::Math::Scale(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return TIntVector3<T>(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::ClampMagnitude(const TIntVector3<T>& v1, T min, T max)
{
Rt magnitude = Magnitude(v1);
const TVector3<Rt> unitVec = (magnitude > P_FLT_INAC) ? v1 / magnitude : PZeroVector3(T);
Clamp(magnitude, min, max);
return unitVec * magnitude;
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::ScaleToMagnitude(const TIntVector3<T>& v1, T magnitude)
{
NormalizeV(v1) *= magnitude;
return v1;
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::CompInverse(const TIntVector3<T>& v1)
{
return TIntVector3<T>((Rt)1.0 / v1.x, (Rt)1.0 / v1.y, (Rt)1.0 / v1.z);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::ReflectFromPlane(const TIntVector3<T>& v1, const TPlane<Rt>& plane)
{
return Reflect(v1, plane.normal);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::ReflectFromPlane(const TIntVector3<T>& v1, const TVector3<Rt>& normal)
{
return Reflect(v1, normal);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::RotateAroundAxis(const TIntVector3<T>& v1, const TVector3<Rt>& axisNormal, Rt angle)
{
T sinAngle = sin(angle);
T cosAngle = cos(angle);
return ((Rt)1 - cosAngle) * DotP(v1, axisNormal) * axisNormal + cosAngle * v1 + sinAngle * CrossP(v1, axisNormal);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::Project(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return (DotP(v1, v2) / DotP(v2, v2)) * v2;
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::Reject(const TIntVector3<T>& v1, const TIntVector3<T>& v2)
{
return v1 - (DotP(v1, v2) / DotP(v2, v2)) * v2;
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::ProjectOntoPlane(const TIntVector3<T>& v1, const TVector3<Rt>& normal)
{
return Reject(v1, normal);
}
template<IntType T, RealType Rt>
Phanes::Core::Math::TVector3<Rt> Phanes::Core::Math::ProjectOntoPlane(const TIntVector3<T>& v1, const TPlane<Rt>& plane)
{
return Reject(v1, plane.normal);
}

View File

@ -0,0 +1,57 @@
#include "PhanesEnginePCH.h"
#include "Core/public/Math/MathCommon.h"
#include "Core/public/OSAL/PlatformTypes.h"
// NOTE: oneline if statments are much faster than the max / min algorithm or expanded if's (64.519 ms per 1 000 000 operations)
template<typename T>
T Phanes::Core::Math::Clamp(T value, T low, T high)
{
if (value < low) value = low;
if (value > high) value = high;
return value;
}
template<typename T>
T Phanes::Core::Math::Max(T x, T y)
{
return (x > y) ? x : y;
}
template<typename T>
T Phanes::Core::Math::Min(T x, T y)
{
return (x < y) ? x : y;
}
template<typename T>
void Phanes::Core::Math::Swap(T& x, T& y)
{
float z = x;
x = y;
y = z;
}
template<typename T>
bool Phanes::Core::Math::Equals(T x, T y, T threshold)
{
if (abs(x - y) < threshold) {
return true;
}
return false;
}
template<typename T>
float Phanes::Core::Math::FastInvSqrt(T n)
{
Phanes::Core::Types::int32 i = * ( int * ) &n;
float x2 = n * 0.5f;
i = 0x5f3759df - (i >> 1);
n = * ( float * ) &i;
n = n * (1.5f - (x2 * n * n));
return n;
}

View File

@ -0,0 +1,48 @@
#include "PhanesEnginePCH.h"
#include "Core/public/Math/MathTypeConversion.h"
// ============ //
// ToString //
// ============ //
template<RealType T>
std::string Phanes::Core::Math::ToString(const Phanes::Core::Math::TVector2<T>& v) {
return "(" + std::to_string(v.x) + ", " + std::to_string(v.y) + ")";
}
template<IntType T>
std::string Phanes::Core::Math::ToString(const TIntVector2<T>& v)
{
return "(" + std::to_string(v.x) + ", " + std::to_string(v.y) + ")";
}
template<RealType T>
std::string Phanes::Core::Math::ToString(const Phanes::Core::Math::TVector3<T>& v) {
return "(" + std::to_string(v.x) + ", " + std::to_string(v.y) + ", " + std::to_string(v.z) + ")";
}
template<IntType T>
std::string Phanes::Core::Math::ToString(const TIntVector3<T>& v)
{
std::to_string(3);
return "(" + std::to_string(v.x) + ", " + std::to_string(v.y) + ", " + std::to_string(v.z) + ")";
}
//template<typename T>
//std::string Phanes::Core::Math::ToString(const Vector4& v)
//{
// return "(" + std::to_string(v.x) + ", " + std::to_string(v.y) + ", " + std::to_string(v.z) + ", " + std::to_string(v.w) + ")";
//}
//
//template<typename T>
//std::string Phanes::Core::Math::ToString(const Matrix2& v)
//{
// return std::to_string(v(0,0)) + " | " + std::to_string(v(0,1)) + "\n" + std::to_string(v(1,0)) + " | " + std::to_string(v(1,1));
//}
//
//template<typename T>
//std::string Phanes::Core::Math::ToString(const Matrix3& v)
//{
// return std::to_string(v(0, 0)) + " | " + std::to_string(v(0, 1)) + " | " + std::to_string(v(0, 2)) + "\n" + std::to_string(v(1, 0)) + " | " + std::to_string(v(1, 1)) + " | " + std::to_string(v(1, 2)) + "\n" + std::to_string(v(2, 0)) + " | " + std::to_string(v(2, 1)) + " | " + std::to_string(v(2, 2));
//}

View File

@ -0,0 +1,60 @@
#include "PhanesEnginePCH.h"
#include "Core/public/Math/MathUnitConversion.h"
template<RealType T>
inline T Phanes::Core::Math::UnitConversion::DegToRad(T deg)
{
return deg * P_PI_180_FLT;
}
template<RealType T>
inline T Phanes::Core::Math::UnitConversion::RadToDeg(T rad)
{
return rad * P_180_PI_FLT;
}
template<RealType T>
inline T Phanes::Core::Math::UnitConversion::DegToGradian(T deg)
{
return deg * 1.111111f;
}
template<RealType T>
inline T Phanes::Core::Math::UnitConversion::GradianToDeg(T g)
{
return g * 0.9f;
}
template<RealType T>
inline T Phanes::Core::Math::UnitConversion::RadToGradian(T rad)
{
return rad * 200 / P_PI_FLT;
}
template<RealType T>
inline T Phanes::Core::Math::UnitConversion::GradianToRad(T g)
{
return g * P_PI_FLT / 200;
}
// Unit Literals
double Phanes::Core::Math::UnitLiterals::operator""_deg(long double _x)
{
return _x * P_PI_180_FLT;
}
double Phanes::Core::Math::UnitLiterals::operator""_rad(long double _x)
{
return _x;
}
double Phanes::Core::Math::UnitLiterals::operator""_g(long double _x)
{
return _x * P_PI_FLT / 200;
}

View File

@ -0,0 +1,145 @@
// =========================== //
// Matrix2D implementation //
// =========================== //
#include "PhanesEnginePCH.h"
#include "Core/public/Math/Matrix2.h"
#include "Core/public/Math/Vector2.h"
template<RealType T>
inline Phanes::Core::Math::TMatrix2<T>::TMatrix2(const TMatrix2<T>& m1)
{
memcpy(this->m, m1.m, sizeof(T) * 2);
}
template<RealType T>
Phanes::Core::Math::TMatrix2<T>::TMatrix2(TMatrix2<T>&& m)
{
this->comp = m.comp;
m.comp = nullptr;
}
template<RealType T>
Phanes::Core::Math::TMatrix2<T>::TMatrix2(T fields[2][2])
{
this->m[0][0] = fields[0][0]; this->m[1][0] = fields[0][1];
this->m[1][0] = fields[1][0]; this->m[1][1] = fields[1][1];
}
template<RealType T>
Phanes::Core::Math::TMatrix2<T>::TMatrix2(T n00, T n10, T n01, T n11)
{
this->m[0][0] = n00; this->m[1][0] = n01;
this->m[1][0] = n10; this->m[1][1] = n11;
}
template<RealType T>
Phanes::Core::Math::TMatrix2<T>::TMatrix2(const TVector2<T>& v1, const TVector2<T>& v2)
{
this->m[0][0] = v1.x; this->m[1][0] = v1.y;
this->m[0][1] = v2.x; this->m[1][1] = v2.y;
}
template<RealType T>
T& Phanes::Core::Math::TMatrix2<T>::operator()(int n, int m)
{
return this->m[m][n];
}
// ================================= //
// Class Methods for easy access //
// ================================= //
template<RealType T>
Phanes::Core::Math::TVector2<T>& Phanes::Core::Math::TMatrix2<T>::operator[](int m)
{
return reinterpret_cast<TVector2*>(this->m[m]);
}
template<RealType T>
const T& Phanes::Core::Math::TMatrix2<T>::operator()(int n, int m) const
{
return this->m[m][n];
}
template<RealType T>
const Phanes::Core::Math::TVector2<T>& Phanes::Core::Math::TMatrix2<T>::operator[](int m) const
{
return reinterpret_cast<const TVector2*>(this->m[m]);
}
// ===================== //
// TMatrix2 operator //
// ===================== //
template<RealType T>
Phanes::Core::Math::TMatrix2<T> Phanes::Core::Math::operator+=(TMatrix2<T>& m1, T s)
{
m1->m[0][0] += s;
m1->m[0][1] += s;
m1->m[1][0] += s;
m1->m[1][1] += s;
return m1;
}
template<RealType T>
Phanes::Core::Math::TMatrix2<T> Phanes::Core::Math::operator+=(TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
m1->m[0][0] += m2.m[0][0];
m1->m[0][1] += m2.m[0][1];
m1->m[1][0] += m2.m[1][0];
m1->m[1][1] += m2.m[1][1];
return m1;
}
template<RealType T>
Phanes::Core::Math::TMatrix2<T> Phanes::Core::Math::operator-=(TMatrix2<T>& m1, T s)
{
m1->m[0][0] -= s;
m1->m[0][1] -= s;
m1->m[1][0] -= s;
m1->m[1][1] -= s;
return m1;
}
template<RealType T>
Phanes::Core::Math::TMatrix2<T> Phanes::Core::Math::operator-=(TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
m1->m[0][0] -= m2.m[0][0];
m1->m[0][1] -= m2.m[0][1];
m1->m[1][0] -= m2.m[1][0];
m1->m[1][1] -= m2.m[1][1];
return m1;
}
template<RealType T>
Phanes::Core::Math::TMatrix2<T> Phanes::Core::Math::operator*=(TMatrix2<T>& m1, T s)
{
m1->m[0][0] *= s;
m1->m[0][1] *= s;
m1->m[1][0] *= s;
m1->m[1][1] *= s;
return m1;
}
template<RealType T>
Phanes::Core::Math::TMatrix2<T> Phanes::Core::Math::operator*=(TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
Matrix2 c = m1;
m1(0, 0) = c(0, 0) * m2(0, 0) + c(0, 1) * m2(1, 0);
m1(0, 1) = c(0, 0) * m2(0, 1) + c(0, 1) * m2(1, 1);
m1(1, 0) = c(1, 0) * m2(0, 0) + c(1, 1) * m2(1, 0);
m1(1, 1) = c(1, 0) * m2(0, 1) + c(1, 1) * m2(1, 1);
return m1;
}

View File

@ -0,0 +1,34 @@
#include "PhanesEnginePCH.h"
#include "Core/public/Math/Point.h"
#include "Core/public/Math/Vector2.h"
#include "Core/public/Math/Vector3.h"
// #include "Core/public/Math/Vector4.h"
// ----- TPoint2 ------------------------------------------
template<RealType T>
T Phanes::Core::Math::Distance(const TPoint2<T>& p1, const TPoint2<T>& p2)
{
return Magnitude(p2 - p1);
}
// ----- TPoint3 ------------------------------------------
template<RealType T>
T Phanes::Core::Math::Distance(const TPoint3<T>& p1, const TPoint3<T>& p2)
{
return Magnitude(p2 - p1);
}
// ----- TPoint4 ------------------------------------------
//template<RealType T>
//T Phanes::Core::Math::Distance(const TPoint4<T>& p1, const TPoint4<T>& p2)
//{
// return Magnitude(TVector3<T>(p1, p2));
//}

View File

@ -0,0 +1,571 @@
// =========================== //
// TVector2 implementation //
// =========================== //
#include "PhanesEnginePCH.h"
#include "Core/public/Math/Vector2.h"
#include "Core/public/Math/Vector3.h"
#include "Core/public/Math/Point.h"
//#include "Math/Matrix2.h"
//#include "Math/Matrix2.h"
//#include "Math/Vector3.h"
//#include "Math/Vector4.h"
//#include "Math/IntVector2.h"
//#include "Math/IntVector3.h"
//#include "Math/IntVector4.h"
// ========================= //
// TVector2 constructors //
// ========================= //
template<RealType T>
Phanes::Core::Math::TVector2<T>::TVector2(const Real x, const Real y)
{
this->x = x;
this->y = y;
}
template<RealType T>
Phanes::Core::Math::TVector2<T>::TVector2(const Real* comp)
{
// static_assert(sizeof(comp) > 2 * sizeof(T), "PHANES_CORE (Vector2.cpp): Setting 2D vector coordinates by an array, comp must have a size of at least 2 components.");
memcpy(this->comp, comp, sizeof(T) * 2);
}
template<RealType T>
Phanes::Core::Math::TVector2<T>::TVector2(const TPoint2<Real>& start, const TPoint2<Real>& end)
{
this->x = end.x - start.x;
this->y = end.y - start.y;
}
template<RealType T>
Phanes::Core::Math::TVector2<T>::TVector2(const TVector3<Real>& v)
{
this->x = v.x;
this->y = v.y;
}
template<RealType T>
Phanes::Core::Math::TVector2<T>::TVector2(const TVector2<Real>& v)
{
memcpy(this->comp, comp, sizeof(T) * 2);
}
template<RealType T>
Phanes::Core::Math::TVector2<T>::TVector2(TVector2<Real>&& v)
{
this->comp = v.comp;
v.comp = nullptr;
}
//
//Phanes::Core::Math::TVector2::TVector2(const Vector3& v)
//{
// std::copy(v.components, v.components + 2, this->components);
//}
//
//
//Phanes::Core::Math::TVector2::TVector2(const Vector4& v)
//{
// std::copy(v.components, v.components + 2, this->components);
//}
//
//
//Phanes::Core::Math::TVector2::TVector2(const IntVector2& v)
//{
// std::copy(v.components, v.components + 2, this->components);
//}
//
//
//Phanes::Core::Math::TVector2::TVector2(const IntVector3& v)
//{
// std::copy(v.components, v.components + 2, this->components);
//}
//
//
//Phanes::Core::Math::TVector2::TVector2(const IntVector4& v)
//{
// std::copy(v.components, v.components + 2, this->components);
//}
//
//
//Phanes::Core::Math::TVector2::TVector2(const Point2& v)
//{
// std::copy(v.components, v.components + 2, this->components);
//}
// ====================== //
// TVector2 operators //
// ====================== //
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator+=(TVector2<T>& v1, T s)
{
v1.x += s;
v1.y += s;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator+=(TVector2<T>& v1, const TVector2<T>& v2)
{
v1.x += v2.x;
v1.y += v2.y;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator-=(TVector2<T>& v1, T s)
{
v1.x -= s;
v1.y -= s;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator-=(TVector2<T>& v1, const TVector2<T>& v2)
{
v1.x -= v2.x;
v1.y -= v2.y;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator*=(TVector2<T>& v1, T s)
{
v1.x *= s;
v1.y *= s;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator/=(TVector2<T>& v1, T s)
{
s = 1.0f / s;
v1.x *= s;
v1.y *= s;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator*(const TVector2<T>& v1, T s)
{
return TVector2<T>(v1.x * s, v1.y * s);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator/(const TVector2<T>& v1, T s)
{
s = 1.0f / s;
return TVector2<T>(v1.x * s, v1.y * s);
}
template<RealType T>
inline Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator*(T s, const TVector2<T>& v1)
{
return v1 * s;
}
template<RealType T>
inline Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator/(T s, const TVector2<T>& v1)
{
s = 1.0f / s;
return v1 * s;
}
template<RealType T>
T Phanes::Core::Math::operator* (const TVector2<T>& v1, const TVector2<T>& v2)
{
return v1.x * v2.x + v1.y * v2.y;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator+(const TVector2<T>& v1, T s)
{
return TVector2<T>(v1.x + s, v1.y + s);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator+(const TVector2<T>& v1, const TVector2<T>& v2)
{
return TVector2<T>(v1.x + v2.x, v1.y + v2.y);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator-(const TVector2<T>& v1, T s)
{
return TVector2<T>(v1.x - s, v1.y - s);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::operator-(const TVector2<T>& v1, const TVector2<T>& v2)
{
return TVector2<T>(v1.x - v2.x, v1.y - v2.y);
}
template<RealType T>
void Phanes::Core::Math::operator-(TVector2<T>& v1)
{
v1.x = -v1.x;
v1.y = -v1.y;
}
template<RealType T>
bool Phanes::Core::Math::operator== (const TVector2<T>& v1, const TVector2<T>& v2)
{
return (abs(v1.x - v1.x) < P_FLT_INAC && abs(v1.y - v1.y) < P_FLT_INAC);
}
template<RealType T>
bool Phanes::Core::Math::operator!=(const TVector2<T>& v1, const TVector2<T>& v2)
{
return (abs(v1.x - v1.x) > P_FLT_INAC || abs(v1.y - v1.y) > P_FLT_INAC);
}
template<RealType T>
T Phanes::Core::Math::Magnitude(const TVector2<T>& v1)
{
return sqrtf(v1.x * v1.x + v1.y * v1.y);
}
template<RealType T>
T Phanes::Core::Math::SqrMagnitude(const TVector2<T>& v1)
{
return v1.x * v1.x + v1.y * v1.y;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::NormalizeV(TVector2<T>& v1)
{
float vecNorm = Magnitude(v1);
v1 /= (vecNorm < P_FLT_INAC) ? 1 : vecNorm;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::UnsafeNormalizeV(TVector2<T>& v1)
{
v1 /= Magnitude(v1);
return v1;
}
template<RealType T>
T Phanes::Core::Math::Angle(const TVector2<T>& v1, const TVector2<T>& v2)
{
return acos((v1 * v2) / Magnitude(v1) * Magnitude(v2));
}
template<RealType T>
T Phanes::Core::Math::CosineAngle(const TVector2<T>& v1, const TVector2<T>& v2)
{
return (v1 * v2) / Magnitude(v1) * Magnitude(v2);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::SignVectorV(TVector2<T>& v1)
{
v1.x = (v1.x > 0) ? 1 : -1;
v1.y = (v1.y > 0) ? 1 : -1;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::BindToSquareV(TVector2<T>& v1, T radius)
{
float k = (abs(v1.x) > abs(v1.y)) ? abs(radius / v1.x) : abs(radius / v1.y);
v1 *= k;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::ClampToSquareV(TVector2<T>& v1, T radius)
{
float prime = (abs(v1.x) > abs(v1.y)) ? v1.x : v1.y;
float k = (prime > radius) ? abs(radius / prime) : 1.0f;
v1 *= k;
return v1;
}
template<RealType T>
T Phanes::Core::Math::DotP(const TVector2<T>& v1, const TVector2<T>& v2)
{
return v1.x * v2.x + v1.y * v2.y;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::MaxV(TVector2<T>& v1, const TVector2<T>& v2)
{
v1.x = Phanes::Core::Math::Max(v1.x, v2.x);
v1.y = Phanes::Core::Math::Max(v1.y, v2.y);
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::MinV(TVector2<T>& v1, const TVector2<T>& v2)
{
v1.x = Phanes::Core::Math::Min(v1.x, v2.x);
v1.y = Phanes::Core::Math::Min(v1.y, v2.y);
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::GetPerpendicularV(TVector2<T>& v1)
{
T x = v1.x;
v1.x = v1.y;
v1.y = -v1.x;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::GetReversePerpendicularV(TVector2<T>& v1)
{
T x = v1.x;
v1.x = -v1.y;
v1.y = v1.x;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::ScaleV(TVector2<T>& v1, const TVector2<T>& v2)
{
v1.x *= v2.x;
v1.y *= v2.y;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::CompInverseV(TVector2<T>& v1)
{
v1.x = 1.0f / v1.x;
v1.y = 1.0f / v1.y;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::ReflectV(TVector2<T>& v1, const TVector2<T>& normal)
{
Set(v1, v1 - (2 * (v1 * normal) * normal));
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::Set(TVector2<T>& v1, const TVector2<T>& v2)
{
v1 = v2;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::Set(TVector2<T>& v1, T x, T y)
{
v1.x = x;
v1.y = y;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::RotateV(TVector2<T>& v1, T angle)
{
float sinAngle = sin(angle);
float cosAngle = cos(angle);
Set(v1,
v1.x * cosAngle - v1.y * sinAngle,
v1.y * cosAngle + v1.x * sinAngle
);
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::ClockwiseRotateV(TVector2<T>& v1, T angle)
{
RotateV(v1, -angle);
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::NegateV(TVector2<T>& v1)
{
v1.x = -v1.x;
v1.y = -v1.y;
}
template<RealType T>
inline bool Phanes::Core::Math::IsNormalized(const TVector2<T>& v1, T threshold)
{
return (SqrMagnitude(v1) < threshold);
}
template<RealType T>
inline bool Phanes::Core::Math::IsPerpendicular(const TVector2<T>& v1, const TVector2<T>& v2, T threshold)
{
return (abs(DotP(v1, v2)) < threshold);
}
template<RealType T>
inline bool Phanes::Core::Math::IsParallel(const TVector2<T>& v1, const TVector2<T>& v2, T threshold)
{
return (abs(DotP(v1,v2)) > threshold);
}
template<RealType T>
inline bool Phanes::Core::Math::IsCoincident(const TVector2<T>& v1, const TVector2<T>& v2, T threshold)
{
return (DotP(v1, v2) > threshold);
}
//
//Phanes::Core::Math::Matrix2 Phanes::Core::Math::OuterProduct(const TVector2& v1, const TVector2& v2)
//{
// return Matrix2(
// v1.x * v2.x, v1.x * v2.y,
// v1.y * v2.x, v1.y * v2.y
// );
//}
// ============================================================== //
// TVector2 static function implementation with return values //
// ============================================================== //
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::Reflect(const TVector2<T>& v1, const TVector2<T>& normal)
{
return TVector2<T>(v1 - (2 * (v1 * normal) * normal));
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::Scale(const TVector2<T>& v1, const TVector2<T>& v2)
{
return TVector2<T>(v1.x * v2.x, v1.y * v2.y);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::CompInverse(const TVector2<T>& v1)
{
return TVector2<T>(1.0f / v1.x, 1.0f / v1.y);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::Negate(const TVector2<T>& v1)
{
return TVector2<T>(-v1.x, -v1.y);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::GetPerpendicular(const TVector2<T>& v1)
{
return TVector2<T>(v1.y, -v1.x);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::GetReversePerpendicular(const TVector2<T>& v1)
{
return TVector2<T>(-v1.y, v1.x);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::Min(const TVector2<T>& v1, const TVector2<T>& v2)
{
return TVector2<T>(Phanes::Core::Math::Min(v1.x, v2.x), Phanes::Core::Math::Min(v1.y, v2.y));
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::Max(const TVector2<T>& v1, const TVector2<T>& v2)
{
return TVector2<T>(Phanes::Core::Math::Max(v1.x, v2.x), Phanes::Core::Math::Max(v1.y, v2.y));
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::Normalize(const TVector2<T>& v1)
{
float vecNorm = Magnitude(v1);
return (vecNorm < P_FLT_INAC) ? PZeroVector2(T) : (v1 / vecNorm);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::UnsafeNormalize(const TVector2<T>& v1)
{
return (v1 / Magnitude(v1));
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::SignVector(const TVector2<T>& v1)
{
return TVector2<T>((v1.x > 0) ? 1 : -1, (v1.y > 0) ? 1 : -1);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::BindToSquare(const TVector2<T>& v1, T radius)
{
float k = (abs(v1.x) > abs(v1.y)) ? abs(radius / v1.x) : abs(radius / v1.y);
return v1 * k;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::ClampToSquare(const TVector2<T>& v1, T radius)
{
float prime = (abs(v1.x) > abs(v1.y)) ? v1.x : v1.y;
float k = (prime > radius) ? abs(radius / prime) : 1.0f;
return v1 * k;
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::Lerp(const TVector2<T>& startVec, const TVector2<T>& destVec, T t)
{
t = Phanes::Core::Math::Clamp(t, (T)0.0, (T)1.0);
return (t * destVec) + ((1 - t) * startVec);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::LerpUnclamped(const TVector2<T>& startVec, const TVector2<T>& destVec, T t)
{
return (t * destVec) + ((1 - t) * startVec);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::Rotate(const TVector2<T>& v1, T angle)
{
float sinAngle = sin(angle);
float cosAngle = cos(angle);
return TVector2<T>(v1.x * cosAngle - v1.y * sinAngle,
v1.y * cosAngle + v1.x * sinAngle);
}
template<RealType T>
Phanes::Core::Math::TVector2<T> Phanes::Core::Math::ClockwiseRotate(const TVector2<T>& v1, T angle)
{
return Rotate(v1, -angle);
}

View File

@ -0,0 +1,669 @@
// =========================== //
// TVector3 implementation //
// =========================== //
#include "PhanesEnginePCH.h"
#include "Core/public/Math/Vector3.h"
#include "Core/public/Math/Point.h"
#include "Core/public/Math/Plane.h"
template<RealType T>
inline Phanes::Core::Math::TVector3<T>::TVector3(const Real x, const Real y, const Real z)
{
this->x = x;
this->y = y;
this->z = z;
}
template<RealType T>
Phanes::Core::Math::TVector3<T>::TVector3(const Real* comp)
{
static_assert(sizeof(comp) > 2 * sizeof(T), "PHANES_CORE (Vector3.cpp): Setting 3D vector coordinates by an array, comp must have a size of at least 3 components.");
memcpy(this->comp, comp, sizeof(T) * 3);
}
template<RealType T>
Phanes::Core::Math::TVector3<T>::TVector3(const TPoint3<T>& start, const TPoint3<T>& end)
{
this->x = end.x - start.x;
this->y = end.y - start.y;
this->z = end.z - start.z;
}
template<RealType T>
Phanes::Core::Math::TVector3<T>::TVector3(const TVector3<Real>& v)
{
memcpy(this->comp, comp, sizeof(T) * 3);
}
template<RealType T>
Phanes::Core::Math::TVector3<T>::TVector3(TVector3<Real>&& v)
{
this->comp = v.comp;
v.comp = nullptr;
}
// ====================== //
// TVector3 operators //
// ====================== //
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator+=(TVector3<T>& v1, T s)
{
v1.x += s;
v1.y += s;
v1.z += s;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator+=(TVector3<T>& v1, const TVector3<T>& v2)
{
v1.x += v2.x;
v1.y += v2.y;
v1.z += v2.z;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator-=(TVector3<T>& v1, T s)
{
v1.x -= s;
v1.y -= s;
v1.z -= s;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator-=(TVector3<T>& v1, const TVector3<T>& v2)
{
v1.x -= v2.x;
v1.y -= v2.y;
v1.z -= v2.z;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator*=(TVector3<T>& v1, T s)
{
v1.x *= s;
v1.y *= s;
v1.z *= s;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator/=(TVector3<T>& v1, T s)
{
s = (T)1.0 / s;
v1.x *= s;
v1.y *= s;
v1.z *= s;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator*(const TVector3<T>& v1, T s)
{
return TVector3<T>(v1.x * s. v1.y * s, v1.z * s);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator/(const TVector3<T>& v1, T s)
{
s = (T)1.0 / s;
return TVector3<T>(v1.x * s.v1.y * s, v1.z * s);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator*(T s, const TVector3<T>& v1)
{
return v1 * s;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator/(T s, const TVector3<T>& v1)
{
return v1 / s;
}
template<RealType T>
T Phanes::Core::Math::operator*(const TVector3<T>& v1, const TVector3<T>& v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator+(const TVector3<T>& v1, T s)
{
return TVector3<T>(v1.x + s.v1.y + s, v1.z + s);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator+(const TVector3<T>& v1, const TVector3<T>& v2)
{
return TVector3<T>(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator-(const TVector3<T>& v1, T s)
{
return TVector3<T>(v1.x - s.v1.y - s, v1.z - s);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator-(const TVector3<T>& v1, const TVector3<T>& v2)
{
return TVector3<T>(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::operator-(TVector3<T>& v1)
{
v1.x = -v1.x;
v1.y = -v1.y;
v1.z = -v1.z;
return v1;
}
template<RealType T>
bool Phanes::Core::Math::operator==(const TVector3<T>& v1, const TVector3<T>& v2)
{
return (abs(v1.x - v2.x) < P_FLT_INAC && abs(v1.y - v2.y) < P_FLT_INAC && abs(v1.z - v2.z) < P_FLT_INAC);
}
template<RealType T>
bool Phanes::Core::Math::operator!=(const TVector3<T>& v1, const TVector3<T>& v2)
{
return (abs(v1.x - v2.x) > P_FLT_INAC || abs(v1.y - v2.y) > P_FLT_INAC || abs(v1.z - v2.z) > P_FLT_INAC);
}
// ==================================== //
// TVector3 function implementation //
// ==================================== //
template<RealType T>
T Phanes::Core::Math::Magnitude(const TVector3<T>& v1)
{
return sqrt(DotP(v1, v1));
}
template<RealType T>
T Phanes::Core::Math::SqrMagnitude(const TVector3<T>& v1)
{
return DotP(v1, v1);
}
template<RealType T>
T Phanes::Core::Math::SqrLength(const TVector3<T>& v1)
{
return SqrMagnitude(v1);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::NormalizeV(TVector3<T>& v1)
{
float vecNorm = Magnitude(v1);
v1 /= (vecNorm < P_FLT_INAC) ? 1 : vecNorm;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::UnsafeNormalizeV(TVector3<T>& v1)
{
v1 /= Magnitude(v1);
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ReflectV(TVector3<T>& v1, const TVector3<T>& normal)
{
Set(v1, v1 - (2 * (v1 * normal) * normal));
return v1;
}
template<RealType T>
T Phanes::Core::Math::Angle(const TVector3<T>& v1, const TVector3<T>& v2)
{
return acos((v1 * v2) / (Magnitude(v1) * Magnitude(v2)));
}
template<RealType T>
T Phanes::Core::Math::DotP(const TVector3<T>& v1, const TVector3<T>& v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
template<RealType T>
void Phanes::Core::Math::Orthogonalize(TVector3<T>& v1, TVector3<T>& v2, TVector3<T>& v3)
{
Set(v2, Reject(v2, v1));
Set(v3, Reject(Reject(v3, v1), v2));
}
template<RealType T>
void Phanes::Core::Math::OrthoNormalize(TVector3<T>& v1, TVector3<T>& v2, TVector3<T>& v3)
{
Set(v2, Reject(v2, v1));
Set(v3, Reject(Reject(v3, v1), v2));
NormalizeV(v1);
NormalizeV(v2);
NormalizeV(v3);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ScaleToMagnitude(const TVector3<T>& v1, T magnitude)
{
NormalizeV(v1) *= magnitude;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::CompInverse(const TVector3<T>& v1)
{
return TVector3<T>((T)1.0f / v1.x, (T)1.0f / v1.y, (T)1.0f / v1.z);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ReflectFromPlane(const TVector3<T>& v1, const TPlane<T>& plane)
{
return Reflect(v1, plane.normal);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ReflectFromPlane(const TVector3<T>& v1, const TVector3<T>& normal)
{
return Reflect(v1, normal);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::RotateAroundAxis(const TVector3<T>& v1, const TVector3<T>& axisNormal, T angle)
{
T sinAngle = sin(angle);
T cosAngle = cos(angle);
return (1 - cosAngle) * DotP(v1, axisNormal) * axisNormal + cosAngle * v1 + sinAngle * CrossP(v1, axisNormal);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::VectorTriple(const TVector3<T>& v1, const TVector3<T>& v2, const TVector3<T>& v3)
{
return CrossP(CrossP(v1, v2), v3);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::Project(const TVector3<T>& v1, const TVector3<T>& v2)
{
return (DotP(v1, v2) / DotP(v2, v2)) * v2;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::Reject(const TVector3<T>& v1, const TVector3<T>& v2)
{
return v1 - (DotP(v1, v2) / DotP(v2, v2)) * v2;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ProjectOntoPlane(const TVector3<T>& v1, const TVector3<T>& normal)
{
return Reject(v1, normal);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ProjectOntoPlane(const TVector3<T>& v1, const TPlane<T>& plane)
{
return Reject(v1, plane.normal);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::SignVector(const TVector3<T>& v1)
{
v1.x = (v1.x > 0) - (v1.x < 0);
v1.y = (v1.y > 0) - (v1.y < 0);
v1.z = (v1.z > 0) - (v1.z < 0);
return v1;
}
template<RealType T>
bool Phanes::Core::Math::Equals(const TVector3<T>& v1, const TVector3<T>& v2, T threshold)
{
return (abs(v1.x - v2.x) < threshold && abs(v1.y - v2.y) < threshold && abs(v1.z - v2.z) < threshold);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::PerspectiveDivideV(TVector3<T>& v1)
{
float _z = (T)1.0 / v1.z;
v1.x *= _z;
v1.y *= _z;
v1.z = (T)0.0;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::CrossPV(TVector3<T>& v1, const TVector3<T>& v2)
{
float x = v1.x;
float y = v1.y;
float z = v1.z;
v1.x = (y * v2.z) - (z * v2.y);
v1.y = (z * v2.x) - (x * v2.z);
v1.z = (x * v2.y) - (y * v2.x);
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::MaxV(TVector3<T>& v1, const TVector3<T>& v2)
{
v1.x = Max(v1.x, v2.x);
v1.y = Max(v1.y, v2.y);
v1.z = Max(v1.z, v2.z);
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::MinV(TVector3<T>& v1, const TVector3<T>& v2)
{
v1.x = Min(v1.x, v2.x);
v1.y = Min(v1.y, v2.y);
v1.z = Min(v1.z, v2.z);
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::NegateV(TVector3<T>& v1)
{
v1.x = -v1.x;
v1.y = -v1.y;
v1.z = -v1.z;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ScaleV(TVector3<T>& v1, const TVector3<T>& v2)
{
v1.x *= v2.x;
v1.y *= v2.y;
v1.z *= v2.z;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ProjectV(TVector3<T>& v1, const TVector3<T>& v2)
{
float x = (v1 * v2) / (v2 * v2);
v1 = x * v2;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::RejectV(TVector3<T>& v1, const TVector3<T>& v2)
{
float x = (v1 * v2) / (v2 * v2);
v1 -= x * v2;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ProjectOntoPlaneV(TVector3<T>& v1, const TVector3<T>& normal)
{
return RejectV(v1, normal);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ProjectOntoPlaneV(TVector3<T>& v1, const TPlane<T>& plane)
{
return RejectV(v1, plane.normal);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::Set(TVector3<T>& v1, const TVector3<T>& v2)
{
v1 = v2;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::Set(TVector3<T>& v1, T x, T y, T z)
{
v1.x = x;
v1.y = y;
v1.z = z;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ClampMagnitudeV(TVector3<T>& v1, T min, T max)
{
T magnitude = Magnitude(v1);
v1 = (magnitude > P_FLT_INAC) ? v1 / magnitude : PZeroVector3(T);
Clamp(magnitude, min, max);
v1 *= magnitude;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::CompInverseV(TVector3<T>& v1)
{
v1.x = 1.0f / v1.x;
v1.y = 1.0f / v1.y;
v1.z = 1.0f / v1.z;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ReflectFromPlaneV(TVector3<T>& v1, const TPlane<T>& plane)
{
return ReflectV(v1, plane.normal);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ReflectFromPlaneV(TVector3<T>& v1, const TVector3<T>& normal)
{
return ReflectV(v1, normal);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::RotateAroundAxisV(TVector3<T>& v1, const TVector3<T>& axisNormal, T angle)
{
T sinAngle = sin(angle);
T cosAngle = cos(angle);
v1 = ((T)1.0 - cosAngle) * DotP(axisNormal, v1) * axisNormal + cosAngle * v1 + sinAngle * CrossP(axisNormal, v1);
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ScaleToMagnitudeV(TVector3<T>& v1, T magnitude)
{
NormalizeV(v1) *= magnitude;
return v1;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::SignVectorV(TVector3<T>& v1)
{
v1.x = (v1.x > 0) ? 1 : 0;
v1.y = (v1.y > 0) ? 1 : 0;
v1.z = (v1.z > 0) ? 1 : 0;
return v1;
}
template<RealType T>
T Phanes::Core::Math::ScalarTriple(const TVector3<T>& v1, const TVector3<T>& v2, const TVector3<T>& v3)
{
return CrossP(v1, v2) * v3;
}
template<RealType T>
T Phanes::Core::Math::CosineAngle(const TVector3<T>& v1, const TVector3<T>& v2)
{
return (v1 * v2) / (Magnitude(v1) * Magnitude(v2));
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::VectorTripleV(TVector3<T>& v1, const TVector3<T>& v2, const TVector3<T>& v3)
{
CrossPV(CrossPV(v1, v2), v3);
return v1;
}
template<RealType T>
bool Phanes::Core::Math::IsPerpendicular(const TVector3<T>& v1, const TVector3<T>& v2, T threshold)
{
return (abs(DotP(v1, v2)) < threshold);
}
template<RealType T>
bool Phanes::Core::Math::IsParallel(const TVector3<T>& v1, const TVector3<T>& v2, T threshold)
{
return (abs(DotP(v1, v2)) > threshold);
}
template<RealType T>
bool Phanes::Core::Math::IsCoincident(const TVector3<T>& v1, const TVector3<T>& v2, T threshold)
{
return (DotP(v1, v2) > threshold);
}
template<RealType T>
bool Phanes::Core::Math::IsNormalized(const TVector3<T>& v1, T threshold)
{
return (SqrMagnitude(v1) < threshold);
}
template<RealType T>
bool Phanes::Core::Math::IsCoplanar(const TVector3<T>& v1, const TVector3<T>& v2, const TVector3<T>& v3, T threshold)
{
return (ScalarTriple(v1, v2, v3) < threshold);
}
// ================ //
// With return: //
// ================ //
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::Normalize(const TVector3<T>& v1)
{
float vecNorm = Magnitude(v1);
return (vecNorm < P_FLT_INAC) ? PZeroVector3(T) : v1 / vecNorm;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::UnsafeNormalize(const TVector3<T>& v1)
{
return v1 / Magnitude(v1);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::Reflect(const TVector3<T>& v1, const TVector3<T>& normal)
{
return v1 - (2 * (v1 * normal) * normal);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::PerspectiveDivide(const TVector3<T>& v1)
{
float _z = (T)1.0 / v1.z;
return TVector3<T>(v1.x * _z, v1.y * _z, (T)0.0);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::CrossP(const TVector3<T>& v1, const TVector3<T>& v2)
{
return TVector3<T>((v1.y * v2.z) - (v1.z * v2.y),
(v1.z * v2.x) - (v1.x * v2.z),
(v1.x * v2.y) - (v1.y * v2.x));
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::Lerp(const TVector3<T>& start, const TVector3<T>& dest, T t)
{
t = Clamp(t, (T)0.0, (T), 1.0);
return (1 - t) * start + t * dest;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::LerpUnclamped(const TVector3<T>& start, const TVector3<T>& dest, T t)
{
return (1 - t) * start + t * dest;
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::Max(const TVector3<T>& v1, const TVector3<T>& v2)
{
return TVector3<T>((v1.x > v2.x) ? v1.x : v2.x,
(v1.y > v2.y) ? v1.y : v2.y,
(v1.z > v2.z) ? v1.z : v2.z);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::Min(const TVector3<T>& v1, const TVector3<T>& v2)
{
return TVector3<T>((v1.x < v2.x) ? v1.x : v2.x,
(v1.y < v2.y) ? v1.y : v2.y,
(v1.z < v2.z) ? v1.z : v2.z);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::Negate(const TVector3<T>& v1)
{
return TVector3<T>(-v1.x, -v1.y, -v1.z);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::Scale(const TVector3<T>& v1, const TVector3<T>& v2)
{
return TVector3<T>(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
}
template<RealType T>
Phanes::Core::Math::TVector3<T> Phanes::Core::Math::ClampMagnitude(const TVector3<T>& v1, T min, T max)
{
T magnitude = Magnitude(v1);
const TVector3<T> unitVec = (magnitude > P_FLT_INAC) ? v1 / magnitude : PZeroVector3(T);
Clamp(magnitude, min, max);
return unitVec * magnitude;
}

View File

@ -35,38 +35,21 @@ static void IdleMsg()
Phanes::Core::Application::PhanesGame::PhanesGame()
Phanes::Core::Application::PhanesProject::PhanesProject(std::string _ProjectName) : projectName(_ProjectName)
{
}
Phanes::Core::Application::PhanesGame::~PhanesGame()
Phanes::Core::Application::PhanesProject::~PhanesProject()
{
}
void Phanes::Core::Application::PhanesGame::Run()
std::string Phanes::Core::Application::PhanesProject::GetName()
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, 12);
std::cout << "Welcome to PhanesEngine!" << std::endl << std::endl;
SetConsoleTextAttribute(hConsole, 15);
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "It's silent..." << std::endl << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
std::cout << "To silent." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "\nI will go now" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(4));
std::cout << "\nGood by!" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
return this->projectName;
}
void Phanes::Core::Application::PhanesProject::Run()
{
std::cin.get();
}

View File

@ -0,0 +1,57 @@
#pragma once
#include "PhanesEnginePCH.h"
#include "Core/Core.h"
#ifndef P_DEBUG
#pragma warning(disable : 4251) // Disable STL dll export warning
#endif
namespace Phanes::Core::Logging
{
static std::shared_ptr<spdlog::logger> _PEngineLogger;
static std::shared_ptr<spdlog::logger> _PAppLogger;
PHANES_CORE void Init();
PHANES_CORE inline std::shared_ptr<spdlog::logger>& PEngineLogger() { return _PEngineLogger; };
PHANES_CORE inline std::shared_ptr<spdlog::logger>& PGameLogger() { return _PAppLogger; };
}
namespace PLog = Phanes::Core::Logging; // User Macros
#ifdef P_DEBUG
// Default logger
#define PENGINE_LOG_TRACE(...) ::Phanes::Core::Logging::PEngineLogger()->trace(__VA_ARGS__)
#define PENGINE_LOG_INFO(...) ::Phanes::Core::Logging::PEngineLogger()->info(__VA_ARGS__)
#define PENGINE_LOG_WARN(...) ::Phanes::Core::Logging::PEngineLogger()->warn(__VA_ARGS__)
#define PENGINE_LOG_ERROR(...) ::Phanes::Core::Logging::PEngineLogger()->error(__VA_ARGS__)
#define PENGINE_LOG_FATAL(...) ::Phanes::Core::Logging::PEngineLogger()->fatal(__VA_ARGS__)
#define PAPP_LOG_TRACE(...) ::Phanes::Core::Logging::PAppLogger()->trace(__VA_ARGS__)
#define PAPP_LOG_INFO(...) ::Phanes::Core::Logging::PAppLogger()->info(__VA_ARGS__)
#define PAPP_LOG_WARN(...) ::Phanes::Core::Logging::PAppLogger()->warn(__VA_ARGS__)
#define PAPP_LOG_ERROR(...) ::Phanes::Core::Logging::PAppLogger()->error(__VA_ARGS__)
#define PAPP_LOG_FATAL(...) ::Phanes::Core::Logging::PAppLogger()->fatal(__VA_ARGS__)
#else
#define PENGINE_LOG_TRACE(...)
#define PENGINE_LOG_INFO(...)
#define PENGINE_LOG_WARN(...)
#define PENGINE_LOG_ERROR(...)
#define PENGINE_LOG_FATAL(...)
#define PAPP_LOG_TRACE(...)
#define PAPP_LOG_INFO(...)
#define PAPP_LOG_WARN(...)
#define PAPP_LOG_ERROR(...)
#define PAPP_LOG_FATAL(...)
#endif

View File

@ -0,0 +1,154 @@
#pragma once
#include "Core/public/Misc/Boilerplate.h"
#include "Core/public/Math/MathCommon.h"
#include "Core/public/Math/MathAbstractTypes.h"
#include "Core/public/Math/MathFwd.h"
#include "Core/public/Math/IntVector2.h"
#include "Core/public/Math/IntVector3.h"
// #include "Core/public/Math/IntVector4.h"
#ifndef P_DEBUG
#pragma warning(disable : 4244)
#endif
/**
* General annonation: The Point is the same as a vector. The type exists, to ensure a
* easy differentiation between the two.
*/
#ifndef INTPOINT_H
#define INTPOINT_H
namespace Phanes::Core::Math {
/**
* A 2D Point with components x and y with integer precision.
*/
template<IntType T>
struct TIntPoint2 : public TIntVector2<T> {
using TIntVector2<T>::TIntVector2;
/**
* Creates IntPoint2 from IntPoint3's xy
*
* @param a IntPoint3 one
*/
TIntPoint2(const TIntPoint3<T>& a)
{
this->x = a.x;
this->y = a.y;
}
/**
* Creates IntPoint2 from IntPoint4's xy
*
* @param a IntPoint4 one
*/
//TIntPoint2(const TIntPoint4<T>& a)
//{
// this->x = a.x;
// this->y = a.y;
//}
};
template<IntType T, RealType Rt>
Rt Distance(const TIntPoint2<T>& p1, const TIntPoint2<T>& p2);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* A 3D Point with components x and y with integer precision.
*/
template<IntType T>
struct TIntPoint3 : public TIntVector3<T> {
using TIntVector3<T>::TIntVector3;
/**
* Creates IntPoint3 from IntPoint2's xy and zero
*
* @param a IntPoint2 one
*/
TIntPoint3(const TIntPoint2<T>& a)
{
this->x = a.x;
this->y = a.y;
this->z = 0;
}
/**
* Creates IntPoint3 from IntPoint4's xyz
*
* @param a IntPoint4 one
*/
//TIntPoint3(const TIntPoint4<T>& a)
//{
// this->components[0] = a.components[0];
// this->components[1] = a.components[1];
// this->components[2] = a.components[2];
//}
};
template<IntType T, RealType Rt>
Rt Distance(const TIntPoint3<T>& p1, const TIntPoint3<T>& p2);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* A 4D Point with components x and y with integer precision.
*/
//template<typename T>
//struct TIntPoint4 : public TIntVector4<T> {
// static_assert(std::is_integral_v(T), "T must be an integer type.");
// using IntVector4<T>::IntVector4;
// /**
// * Creates IntPoint4 from IntPoint2's xy and the last two zero
// *
// * @param a IntPoint2 one
// */
// PHANES_CORE_API IntPoint4(const IntPoint2<T>& a)
// {
// this->components[0] = a.components[0];
// this->components[1] = a.components[1];
// this->components[2] = 0;
// this->components[3] = 0;
// }
// /**
// * Creates IntPoint4 from IntPoint3's xyz and zero
// *
// * @param a IntPoint3 one
// */
// PHANES_CORE_API IntPoint4(const IntPoint3<T>& a)
// {
// this->components[0] = a.components[0];
// this->components[1] = a.components[1];
// this->components[2] = a.components[2];
// this->components[3] = 0;
// }
//};
} // phanes::core::math::coretypes
#endif // !INTPOINT_H

View File

@ -0,0 +1,872 @@
#pragma once
#include "Core/Core.h"
#include "Core/public/Misc/Boilerplate.h"
#include "Core/public/Math/MathCommon.h"
#include "Core/public/Math/MathAbstractTypes.h"
#include "Core/public/Math/MathFwd.h"
#ifndef P_DEBUG
#pragma warning(disable : 4244)
#endif
/**
* Note: Some function are deleted, because, their unusable with int types, except very specific cases.
* To keep the library verbose, these functions are explicitly marked as deleted.
*/
#ifndef INTVECTOR2_H
#define INTVECTOR2_H
#define PIntZeroVector2(type) TIntVector2<##type>(0,0)
#define PIntVectorSouth2(type) TIntVector2<##type>(0,-1)
#define PIntVectorNorth2(type) TIntVector2<##type>(0,1)
#define PIntVectorEast2(type) TIntVector2<##type>(1,0)
#define PIntVectorWest2(type) TIntVector2<##type>(-1,0)
namespace Phanes::Core::Math {
/**
* A 2D Vector with components x and y with integer precision.
*/
template<IntType T>
struct TIntVector2 {
static_assert(std::is_integral_v<T>, "T must be an integer type.");
public:
// Using in combination with a struct and an array allows us the reflect changes of the x and y variables in the comp array and vise versa.
union
{
struct
{
/** X component of Vector
*
* @ref [FIELD]components
* @note x does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
*/
T x;
/** Y component of Vector
*
* @ref [FIELD]components
*
* @note y does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
*/
T y;
};
/** Components array holding the data
*
* @ref [FIELD]x
* @ref [FIELD]y
*
* @note Components are split into x and y. Access and manipulation is possible by these variables.
*/
T comp[2];
};
public:
/**
* Default constructor without initialization
*/
TIntVector2() = default;
/**
* Copy constructor
*/
TIntVector2(const TIntVector2<T>& v);
/**
* Move constructor
*/
TIntVector2(TIntVector2<T>&& v);
/**
* Convert other type of vector
*/
template<IntType OtherIntType>
explicit TIntVector2(const TIntVector2<OtherIntType>& v) : x((T)v.x), y((T)v.y) {};
template<RealType Real>
explicit TIntVector2(const TVector2<Real>& v) : x((T)v.x), y((T)v.y) {};
/**
* Construct Vector from xy components.
*
* @param x X component
* @param y Y component
*/
TIntVector2(const T x, const T y);
/**
* Construct Vector from two component array.
*
* @param comp Array of components
*/
TIntVector2(const T* comp);
/**
* Construct Vector from 3D integer Vector's xy.
*
* @param v 3D IntVector to copy from
*/
TIntVector2(const TIntVector3<T>& v);
/**
* Construct Vector from 4D integer Vector's xy.
*
* @param v 4D IntVector to copy from
*/
//TIntVector2(const TIntVector4<IntType>& v);
/**
* Construct Vector from 2D Point's xy.
*
* @param v 2D Point to copy from
*/
//TIntVector2(const TIntPoint2<IntType>& v);
/**
* Constructs a vector pointing from start to end.
*
* @param(start) Startingpoint
* @param(end) Endpoint
*/
TIntVector2(const TIntPoint2<T>& start, const TIntPoint2<T>& end);
};
// ======================== //
// IntVector2 operators //
// ======================== //
/**
* Addition operation on same TIntVector2<T> (this) by a floating point value.
*
* @param(v1) Vector to add to
* @param(s) Floating point to add
*/
template<IntType T>
TIntVector2<T> operator+= (TIntVector2<T>& v1, T s);
/**
* Addition operation on same TIntVector2<T> (this) by a another TIntVector2<T>.
*
* @param(v1) Vector to add to
* @param(v2) Vector to add
*/
template<IntType T>
TIntVector2<T> operator+= (TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Substraction operation on same TIntVector2<T> (this) by a floating point.
*
* @param(v1) Vector to substract from
* @param(v2) Floating point to substract
*/
template<IntType T>
TIntVector2<T> operator-= (TIntVector2<T>& v1, T s);
/**
* Substraction operation on same TIntVector2<T> (this) by a another TIntVector2<T>.
*
* @param(v1) Vector to substract from
* @param(v2) Vector to substract
*/
template<IntType T>
TIntVector2<T> operator-= (TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Multiplication of TIntVector2<T> (this) with a floating point.
*
* @param(v1) Vector to multiply with
* @param(s Floating point to multiply with
*/
template<IntType T>
TIntVector2<T> operator*= (TIntVector2<T>& v1, T s);
/**
* Devision of Vector (this) by floating point.
*
* @param(v1) Vector to divide with
* @param(s Floating point to divide with
*/
template<IntType T>
TIntVector2<T> operator/= (TIntVector2<T>& v1, T s) = delete;
/**
* Scale of Vector by floating point. (> Creates a new TIntVector2<T>)
*
* @param(v1) Vector to multiply with
* @param(s Floating point to multiply with
*
* @return Result Vector
*/
template<IntType T>
TIntVector2<T> operator* (const TIntVector2<T>& v1, T s);
/**
* Division of Vector by floating point. (> Creates another TIntVector2<T>)
*
* @see [FUNC]DivideFloat
*
* @param(v1) Vector to multiply with
* @param(s Floating point to divide with
*
* @return Result Vector
* @note Deleted, because the returntype might not implicitly be obvious, when using in code or reading.
*/
template<IntType T>
TIntVector2<T> operator/ (const TIntVector2<T>& v1, T s) = delete;
/**
* Scale of Vector by floating point. (> Creates a new TIntVector2<T>)
*
* @param(v1) Vector to multiply with
* @param(s Floating point to multiply with
*
* @return Result Vector
*/
template<IntType T>
inline TIntVector2<T> operator* (T s, const TIntVector2<T>& v1);
/**
* Division of Vector by floating point. (> For convenience not arithmethicaly correct. Works like overloaded counterpart.)
*
* @see [FUNC]DivideFloat
*
* @param(v1) Vector to multiply with
* @param(s Floating point to divide with
*
* @return Result Vector
*
* @note Deleted, because the returntype might not implicitly be obvious, when using in code or reading.
*/
template<IntType T>
inline TIntVector2<T> operator/ (T s, const TIntVector2<T>& v1) = delete;
/**
* Dot product between two Vectors.
*
* @see [FUNC]DotP
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @result Dot product
*/
template<IntType T, IntType Rt = float>
Rt operator* (const TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Componentwise addition of Vector with floating point.
*
* @param(v1) Vector to add to
* @param(s Floating point to add
*
* @return Result Vector
*/
template<IntType T>
TIntVector2<T> operator+ (const TIntVector2<T>& v1, T s);
/**
* Componentwise addition of Vector with floating point.
*
* @param(v1) Vector to add to
* @param(s Floating point to add
*
* @return Result Vector
*/
template<IntType T>
TIntVector2<T> operator+ (const TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Componentwise substraction of Vector with floating point.
*
* @param(v1) Vector to substract from
* @param(s Floating point to substract
*
* @return Result Vector
*/
template<IntType T>
TIntVector2<T> operator- (const TIntVector2<T>& v1, T s);
/**
* Componentwise substraction of Vector with Vector.
*
* @param(v1) Vector to substract from
* @param(s Floating point to substract
*
* @return Result Vector
*/
template<IntType T>
TIntVector2<T> operator- (const TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Negate Vector.
*
* @param(v1) Vector to negate
*/
template<IntType T>
void operator- (TIntVector2<T>& v1);
/**
* Compare Vector for equality.
*
* @see [FUNC]Equals
*
* @param(v1) Vector to negate
*
* @return true if equal, false if inequal
*/
template<IntType T>
bool operator== (const TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Compare Vector for inequality.
*
* @see [FUNC]Equals
*
* @param(v1) Vector to negate
*
* @return true if inequal, false if equal
*/
template<IntType T>
bool operator!= (const TIntVector2<T>& v1, const TIntVector2<T>& v2);
// ============================================== //
// IntVector2 static function implementation //
// ============================================== //
/**
* Magnitude of Vector
*
* @param(v1) Vector
*
* @return Size of Vector
*/
template<IntType T, IntType Rt = float>
Rt Magnitude(const TIntVector2<T>& v1);
/**
* @see [FUNC]Magnitude
*/
template<IntType T, IntType Rt = float>
FORCEINLINE Rt Length(const TIntVector2<T>& v1) { return Magnitude(v1); };
/**
* Square of magnitude of Vector
*
* @param(v1) Vector
*
* @return Magnitude without calculating square root
*/
template<IntType T>
T SqrMagnitude(const TIntVector2<T>& v1);
/**
* @see [FUNC]SqrMagnitude
*/
template<IntType T>
FORCEINLINE T SqrLength(const TIntVector2<T>& v1) { return SqrMagnitude(v1); };
/**
* Divide vector and truncate result.
*
* @param(v1) Vector to divide
* @param(s) Number to divide with
*
* @note Rt is the type of the reciprocal of s.
*/
template<IntType T, RealType Rt = float>
TIntVector2<T> DivideTruncV(TIntVector2<T>& v1, T s);
/**
* Angle between to Vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*/
template<IntType T, RealType Rt = float>
Rt Angle(const TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Cosine of angle between to Vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*/
template<IntType T, RealType Rt = float>
Rt CosineAngle(const TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Returns signs of components in vector: -1 / +1 / 0.
*
* @param(v1) Vector one
*/
template<IntType T>
TIntVector2<T> SignVectorV(TIntVector2<T>& v1);
/**
* Dot product of two Vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*/
template<IntType T>
T DotP(const TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Creates Vector, with component wise largest values.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @note Stores new Vector to v1
*/
template<IntType T>
TIntVector2<T> MaxV(TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Creates Vector, with component wise smallest values.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @note Stores new Vector to v1
*/
template<IntType T>
TIntVector2<T> MinV(TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Gets perpendicular Vector to v1.
*
* @param(v1) Vector one
*
* @note Stores new Vector to v1
*/
template<IntType T>
TIntVector2<T> GetPerpendicularV(TIntVector2<T>& v1);
/**
* Gets perpendicular Vector to v1.
*
* @reg [FUNC]PerpendicularV
*
* @param(v1) Vector one
*
* @note Stores new Vector to v1
*/
template<IntType T>
TIntVector2<T> GetReversePerpendicularV(TIntVector2<T>& v1);
/**
* Component wise multiplication of Vector
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @note Stores new Vector to v1
*/
template<IntType T>
TIntVector2<T> ScaleV(TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Copies one Vector two another
*
* @param(v1) Vector to copy to
* @param(v2) Vector to copy
*/
template<IntType T>
TIntVector2<T> Set(TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Sets components of a vector.
*
* @param(v1) Vector to copy to
* @param(v2) Vector to copy
*/
template<IntType T>
TIntVector2<T> Set(TIntVector2<T>& v1, T x, T y);
/**
* Negates Vector
*
* @param(v1) Vector one
*/
template<IntType T>
TIntVector2<T> NegateV(TIntVector2<T>& v1);
/**
* Tests if vector is a unity vector.
*
* @param(v1) Vector one
*
* @return true if unit vector, false if not
*/
template<IntType T>
inline bool IsNormalized(const TIntVector2<T>& v1);
/**
* Tests if 2 vectors are perpendicular to each other.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return true if perpendicular, false if not
*
* @note Requires v1 and v2 to be normal vectors.
*/
template<IntType T>
inline bool IsPerpendicular(const TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Tests if 2 vectors are parallel to each other. (Angle is close to zero.)
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return true if parallel, false if not
*
* @note Requires v1 and v2 to be normal vectors.
*/
template<IntType T>
inline bool IsParallel(const TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Tests if 2 vectors are coincident. (Are parallel and point in the same direction.)
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return true if coincident, false if not
*
* @note Requires v1 and v2 to be normal vectors.
*/
template<IntType T>
inline bool IsCoincident(const TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Gets outer product of to vectors.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Resulting matrix
*/
//template<IntType T>
//Matrix2<T> OuterProduct(const TIntVector2<T>& v1, const TIntVector2<T>& v2);
// ============================================================= //
// IntVector2 static function implementation with return values //
// ============================================================= //
/**
* Reflects a vector on a normal
*
* @param(v1) Vector one
* @param(normal) Normal of surface
*
* @return Reflected vector
*/
template<IntType T, RealType Rt = float>
TVector2<Rt> Reflect(const TIntVector2<T>& v1, const TVector2<Rt>& normal);
/**
* Scales a vector component wise
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Reflected vector
*/
template<IntType T>
TIntVector2<T> Scale(const TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Componentwise inverse of a vector
*
* @param(v1) Vector one
*
* @return Componentwise inverted, floating point vector
*/
template<IntType T, RealType Rt = float>
TVector2<Rt> CompInverse(const TIntVector2<T>& v1);
/**
* Negates Vector
*
* @param(v1) Vector one
*
* @return Componentwise inverted vector
*/
template<IntType T>
TIntVector2<T> Negate(const TIntVector2<T>& v1);
/**
* Gets the perpendicular vector of v1
*
* @param(v1) Vector one
*
* @return Perpendicular vector
*/
template<IntType T>
TIntVector2<T> GetPerpendicular(const TIntVector2<T>& v1);
/**
* Gets reverse of the perpendicular vector of v1
*
* @param(v1) Vector one
*
* @return Reversed perpendicular vector
*/
template<IntType T>
TIntVector2<T> GetReversePerpendicular(const TIntVector2<T>& v1);
/**
* Creates a new Vector by the component wise minimals of both vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Minimal vector
*/
template<IntType T>
TIntVector2<T> Min(const TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Creates a new Vector by the component wise maxima of both vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Maximal vector
*/
template<IntType T>
TIntVector2<T> Max(const TIntVector2<T>& v1, const TIntVector2<T>& v2);
/**
* Creates a normalized instance of the vector
*
* @param(v1) Vector to normalize
*
* @return Unit vector
* @note Returns floating point vector.
*/
template<IntType T, RealType Rt = float>
TVector2<Rt> Normalize(const TIntVector2<T>& v1);
/**
* Creates a normalized instance of the vector
*
* @param(v1) Vector to normalize
*
* @return Unit vector
* @note Does not test for zero vector
* @note Returns floating point vector.
*/
template<IntType T, RealType Rt = float>
TVector2<Rt> UnsafeNormalize(const TIntVector2<T>& v1);
/**
* Returns signs of components in vector: -1 / +1 / 0.
*
* @param(v1) Vector one
*
* @return Vector with signs as components
*/
template<IntType T>
TIntVector2<T> SignVector(const TIntVector2<T>& v1);
/**
* Binds a vector to a square with a radius
*
* @param(v1) Vector one
* @param(radius) Radius of square (=> Distance from middle to center of each site.)
*
* @return Bound, floating point vector
*/
template<IntType T, RealType Rt = float>
TVector2<Rt> BindToSquare(const TIntVector2<T>& v1, T radius);
/**
* Clamps a vector to a square with a radius
*
* @param(v1) Vector one
* @param(radius) Radius of square (=> Distance from middle to center of each site.)
*
* @return Clamped, floating point vector. If the length of the vector fits the square, then the vector is returned.
*/
template<IntType T, RealType Rt = float>
TVector2<Rt> ClampToSquare(const TIntVector2<T>& v1, T radius);
/**
* Interpolates between to vectors.
*
* @param(startVec) Start vector (t = 0)
* @param(destVec) Destination vector (t = 1)
* @param(t) Interpolation value
*
* @return Interpolated vector
*
* @note Interpolation is clamped between 0 - 1.
*/
template<IntType T, RealType Rt = float>
TVector2<Rt> Lerp(const TIntVector2<T>& startVec, const TIntVector2<T>& destVec, Rt t);
/**
* Interpolates between to vectors.
*
* @param(startVec) Start vector (t = 0)
* @param(destVec) Destination vector (t = 1)
* @param(t) Interpolation value
*
* @return Interpolated vector
*
* @note Interpolation is not clamped. Make shure t is between 0.0f and 1.0f
*/
template<IntType T, RealType Rt = float>
TVector2<Rt> LerpUnclamped(const TIntVector2<T>& startVec, const TIntVector2<T>& destVec, Rt t);
/**
* Anti-clockwise vector rotation.
*
* @param(v1) Vector to rotate
* @param(angle) Angle to rotate
*
* @return Rotated vector
*
* @note Angle is not clamped
*/
template<IntType T, RealType Rt = float>
TVector2<Rt> Rotate(const TIntVector2<T>& v1, Rt angle);
/**
* Clockwise vector rotation.
*
* @param(v1) Vector to rotate
*
* @return Rotated vector
*
* @note Angle is not clamped
*/
template<IntType T, RealType Rt = float>
FORCEINLINE TVector2<Rt> ClockwiseRotate(const TIntVector2<T>& v1, Rt angle);
/**
* Component wise division of Vector
*
* @param(v1) Vector one
* @param(s) Vector two
*
* @note Truncates result instead of rounding
* @note Rt is the type of the reciprocal of s.
*/
template<IntType T, RealType Rt = float>
TIntVector2<T> DivideTrunc(const TIntVector2<T>& v1, T s);
/**
* Component wise division of Vector
*
* @param(v1) Vector one
* @param(s) Vector two
*
* @return Floating point vector
*/
template<IntType T, RealType Rt = float>
TVector2<Rt> DivideFloat(const TIntVector2<T>& v1, T s);
} // phanes::core::math::coretypes
#endif // !INTVECTOR2_H

View File

@ -0,0 +1,966 @@
#pragma once
#include "Core/public/Misc/Boilerplate.h"
#include "Core/public/Math/MathCommon.h"
#include "Core/public/Math/MathAbstractTypes.h"
#include "Core/public/Math/MathFwd.h"
#include "Core/public/Math/Vector3.h"
#ifndef P_DEBUG
#pragma warning(disable : 4244)
#endif
#ifndef INTVECTOR3_H
#define INTVECTOR3_H
#define PIntZeroVector3(type) TIntVector3<##type>(0,0,0)
#define PIntVectorForward3(type) TIntVector3<##type>(1,0,0)
#define PIntVectorBackward3(type) TIntVector3<##type>(-1,0,0)
#define PIntVectorEast3(type) TIntVector3<##type>(0,1,0)
#define PIntVectorWest3(type) TIntVector3<##type>(0,-1,0)
#define PIntVectorUp3(type) TIntVector3<##type>(0,0,1)
#define PIntVectorDown3(type) TIntVector3<##type>(0,0,-1)
namespace Phanes::Core::Math {
/**
* A 3D Vector with components x, y and z with integer precision.
*/
template<IntType T>
struct TIntVector3 {
public:
// Using in combination with a struct and an array allows us the reflect changes of the x and y variables in the comp array and vise versa.
union
{
struct
{
/** X component of Vector
*
* @ref [FIELD]components
* @note x does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
*/
T x;
/** Y component of Vector
*
* @ref [FIELD]components
*
* @note y does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
*/
T y;
/** Z component of Vector
*
* @ref [FIELD]components
*
* @note Z does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
*/
T z;
};
/** Components array holding the data
*
* @ref [FIELD]x
* @ref [FIELD]y
* @ref [FIELD]z
*
* @note Components are split into x, y and z. Access and manipulation is possible by these variables.
*/
T comp[3];
};
public:
/**
* Default constructor without initialization
*/
TIntVector3() = default;
/**
* Copy constructor
*/
TIntVector3(const TIntVector3<T>& v);
/**
* Move constructor
*/
TIntVector3(TIntVector3<T>&& v);
/**
* Convert other type of vector
*/
template<IntType OtherIntType>
explicit TIntVector3(const TIntVector3<OtherIntType>& v) : x((T)v.x), y((T)v.y) {};
template<RealType Real>
explicit TIntVector3(const TVector3<Real>& v) : x((T)v.x), y((T)v.y) {};
/**
* Construct Vector from xy components.
*
* @param x X component
* @param y Y component
* @param z Z component
*/
TIntVector3(const T x, const T y, const T z);
/**
* Construct Vector from two component array.
*
* @param comp Array of components
*/
TIntVector3(const T* comp);
/**
* Construct Vector from 3D integer Vector's xy.
*
* @param v 3D IntVector to copy from
*/
TIntVector3(const TIntVector2<T>& v);
/**
* Construct Vector from 4D integer Vector's xy.
*
* @param v 4D IntVector to copy from
*/
//TIntVector2(const TIntVector4<IntType>& v);
/**
* Construct Vector from 2D Point's xy.
*
* @param v 2D Point to copy from
*/
//TIntVector2(const TIntPoint2<IntType>& v);
/**
* Constructs a vector pointing from start to end.
*
* @param(start) Startingpoint
* @param(end) Endpoint
*/
TIntVector3(const TIntPoint3<T>& start, const TIntPoint3<T>& end);
};
// ======================== //
// IntVector3 operators //
// ======================== //
/**
* Coponentwise addition of floating point to 3D vector
*
* @param(v1) vector to add to
* @param(s) floating point to add
*/
template<IntType T>
inline TIntVector3<T> operator+= (TIntVector3<T>& v1, T s);
/**
* Coponentwise addition of 3D vector to 3D vector
*
* @param(v1) vector to add to
* @param(v2) vector to add
*/
template<IntType T>
inline TIntVector3<T> operator+= (TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Coponentwise substraction of floating point of 3D vector
*
* @param(v1) vector to substract from
* @param(s) floating point to substract
*/
template<IntType T>
inline TIntVector3<T> operator-= (TIntVector3<T>& v1, T s);
/**
* Coponentwise substraction of 3D vector to 3D vector
*
* @param(v1) vector to substract from
* @param(v2) vector to substract with
*/
template<IntType T>
inline TIntVector3<T> operator-= (TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Dot product between two 3D Vectors
*
* @param(v1) vector one
* @param(s) floating point
*/
template<IntType T>
inline TIntVector3<T> operator*= (TIntVector3<T>& v1, T s);
/**
* Coponentwise multiplication of 3D Vectors with floating point
*
* @param(v1) vector one
* @param(s) floating point
*
* @return Resulting vector
*/
template<IntType T>
TIntVector3<T> operator* (const TIntVector3<T>& v1, T s);
/**
* Coponentwise multiplication of 3D Vectors with floating point
*
* @param(s) floating point
* @param(v2) vector
*
* @return Resultion vector
*/
template<IntType T>
inline TIntVector3<T> operator* (T s, const TIntVector3<T>& v1);
/**
* Dot product between two 3D Vectors
*
* @param(v1) vector one
* @param(v2) vector two
*
* @return Dot product of Vectors
*/
template<IntType T>
T operator* (const TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Coponentwise addition of floating point to 3D vector
*
* @param(v1) vector to add to
* @param(s) floating point to add
*
* @return Resulting vector
*/
template<IntType T>
TIntVector3<T> operator+ (const TIntVector3<T>& v1, T s);
/**
* Coponentwise addition of 3D vector to 3D vector
*
* @param(v1) vector to add to
* @param(v2) vector to add
*
* @return Resulting vector
*/
template<IntType T>
TIntVector3<T> operator+ (const TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Coponentwise substraction of floating point of 3D vector
*
* @param(v1) vector to substract from
* @param(s) floating point to substract
*
* @return Resulting vector
*/
template<IntType T>
TIntVector3<T> operator- (const TIntVector3<T>& v1, T s);
/**
* Coponentwise substraction of floating point of 3D vector
*
* @param(v1) vector to substract from
* @param(v2) vector to substract with
*
* @return Resulting vector
*/
template<IntType T>
TIntVector3<T> operator- (const TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Negates vector
*
* @param(v1) Vector to negate
*/
template<IntType T>
TIntVector3<T> operator- (TIntVector3<T>& v1);
/**
* Tests two 3D vectors for equality.
*
* @ref [FUNC]Equals
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return True if equal, false if not.
*
* @note Uses [MACRO]P_FLT_INAC
*/
template<IntType T>
inline bool operator== (const TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Tests two 3D vectors for inequality.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return True if inequal, false if not.
*/
template<IntType T>
inline bool operator!= (const TIntVector3<T>& v1, const TIntVector3<T>& v2);
// ============================================== //
// IntVector3 static function implementation //
// ============================================== //
/**
* Gets magnitude of vector
*
* @param(v1) Vector
*
* @return Magnitude of vector
*/
template<IntType T, RealType Rt = float>
inline Rt Magnitude(const TIntVector3<T>& v1);
/**
* @see [FUNC]Magnitude
*/
template<IntType T>
FORCEINLINE T Length(const TIntVector3<T>& v1) { return Magnitude(v1); };
/**
* Gets square magnitude of vector
*
* @param(v1) Vector
*
* @return Square magnitude of vector
*/
template<IntType T>
inline T SqrMagnitude(const TIntVector3<T>& v1);
/**
* @see SqrMagnitude
*/
template<IntType T>
FORCEINLINE T SqrLength(const TIntVector3<T>& v1) { return SqrMagnitude(v1); };
/**
* Gets angle between two vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Angle between vectors
*/
template<IntType T, RealType Rt = float>
Rt Angle(const TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Dot product of two vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Dot product of vectors
*/
template<IntType T>
T DotP(const TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Returns signs of components in vector: -1 / +1 / 0.
*
* @param(v1) Vector one
*
* @return Vector with signs a components.
*/
template<IntType T>
TIntVector3<T> SignVector(const TIntVector3<T>& v1);
/**
* Tests two vectors for equality.
*
* @param(v1) Vector one
* @param(v2) Vector two
* @param(threshold) Allowed T inaccuracy.
*
* @return True if equal, false if not.
*/
template<IntType T>
inline bool Equals(const TIntVector3<T>& v1, const TIntVector3<T>& v2, T threshold = P_FLT_INAC);
/**
* Calculates the cross product between two vectors.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @note result is stored in v1.
*/
template<IntType T>
TIntVector3<T> CrossPV(TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Gets the componentwise max of both vectors.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @note result is stored in v1.
*/
template<IntType T>
TIntVector3<T> MaxV(TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Gets the componentwise min of both vectors.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @note result is stored in v1.
*/
template<IntType T>
TIntVector3<T> MinV(TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Gets reversed vector.
*
* @param(v1) Vector one
*
* @note result is stored in v1.
*/
template<IntType T>
TIntVector3<T> NegateV(TIntVector3<T>& v1);
/**
* Performes componentwise multiplication of two vectors.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @note result is stored in v1.
*/
template<IntType T>
TIntVector3<T> ScaleV(TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Copies v1 vector
*
* @param(v1) Vector to copy to
* @param(v2) Vector to copy
*/
template<IntType T>
TIntVector3<T> Set(TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Sets vector.
*
* @param(v1) Vector to copy to
* @param(x) X component
* @param(y) Y component
* @param(z) Z component
*/
template<IntType T>
TIntVector3<T> Set(TIntVector3<T>& v1, T x, T y, T z);
/**
* Returns signs of components in vector: -1 / +1 / 0.
*
* @param(v1) Vector one
*/
template<IntType T>
TIntVector3<T> SignVectorV(TIntVector3<T>& v1);
/**
* Gets scalar triple product ((v1 x v2) * v3). (Volume of parallelepiped.)
*
* @param(v1) Vector one
* @param(v2) Vector two
* @param(v3) Vector three
*
* @return Vector triple product
*/
template<IntType T>
T ScalarTriple(const TIntVector3<T>& v1, const TIntVector3<T>& v2, const TIntVector3<T>& v3);
/**
* Gets the cosine of the angle between to vectors.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Cosine of angle between vectors.
* @note Simply omits acos of angle.
*/
template<IntType T>
T CosineAngle(const TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Gets vector triple product ((v1 x v2) x v3).
*
* @param(v1) Vector one
* @param(v2) Vector two
* @param(v3) Vector three
*
* @note result is stored in v1
*/
template<IntType T>
TIntVector3<T> VectorTripleV(TIntVector3<T>& v1, const TIntVector3<T>& v2, const TIntVector3<T>& v3);
/**
* Tests whether two vectors are perpendicular.
*
* @param(v1) Vector one
* @param(v2) Vector two
* @param(threshold) Allowed T inaccuracy
*
* @return True if perpendicular, false if not.
*/
template<IntType T>
inline bool IsPerpendicular(const TIntVector3<T>& v1, const TIntVector3<T>& v2, T threshold = P_FLT_INAC);
/**
* Tests whether two vectors are parallel.
*
* @param(v1) Vector one
* @param(v2) Vector two
* @param(threshold) Allowed T inaccuracy from one (e.g. 0.98f)
*
* @return True if parallel, false if not.
*/
template<IntType T>
inline bool IsParallel(const TIntVector3<T>& v1, const TIntVector3<T>& v2, T threshold = 1.0f - P_FLT_INAC);
/**
* Tests whether two vectors are coincident (Parallel and point in same direction).
*
* @param(v1) Vector one
* @param(v2) Vector two
* @param(threshold) Allowed T inaccuracy from one (e.g. 0.98f)
*
* @return True if coincident, false if not.
*/
template<IntType T>
inline bool IsCoincident(const TIntVector3<T>& v1, const TIntVector3<T>& v2, T threshold = 1.0f - P_FLT_INAC);
/**
* Tests whether v1 vectors is v1 unit vector.
*
* @param(v1) Vector
* @param(threshold) Allowed T inaccuracy
*
* @return True if unit vector, false if not.
*/
template<IntType T>
inline bool IsNormalized(const TIntVector3<T>& v1, T threshold = P_FLT_INAC);
/**
* Tests if three vectors are coplanar
*
* @param(v1) Vector one
* @param(v2) Vector two
* @param(v3) Vector three
* @param(threshold) Allowed T inaccuracy
*
* @return True if coplanar, false if not.
*/
template<IntType T>
inline bool IsCoplanar(const TIntVector3<T>& v1, const TIntVector3<T>& v2, const TIntVector3<T>& v3, T threshold = P_FLT_INAC);
/**
* Gets outer product of to vectors.
*
* @param a Vector one
* @param b Vector two
*
* @return Resulting matrix
*/
//template<IntType T>
//Matrix3<T> OuterProduct(const IntVector3<T>& a, const IntVector3<T>& b);
// ================================================================ //
// IntVector3 static function implementation with return values //
// ================================================================ //
/**
* Normalized vector
*
* @param(v1) vector to normalize
*
* @return Normalized vector
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> Normalize(const TIntVector3<T>& v1);
/**
* Normalizes vector
*
* @param(v1) Vector
*
* @note Does not test for zero vector
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> UnsafeNormalize(const TIntVector3<T>& v1);
/**
* Reflects a vector on a surface
*
* @param(v1) Vector one
* @param(normal) Normal of surface
*
* @return Reflected vector
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> Reflect(const TIntVector3<T>& v1, const TVector3<Rt>& normal);
/**
* Performes perspective divide on vector.
*
* @param(v1) vector to perspective divide
*
* @return Perspective divided vector
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> PerspectiveDivide(const TIntVector3<T>& v1);
/**
* Gets cross product between two vectors.
*
* @param(v1) vector one
* @param(v2) vector two
*
* @return Cross product of v1 and v2
*/
template<IntType T>
TIntVector3<T> CrossP(const TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Linearly interpolates between two vectors.
*
* @param(start) Starting vector
* @param(dest) Destination vector
* @param(t) 0.0 to 1.0 interpolation value
*
* @return Cross product of v1 and v2
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> Lerp(const TIntVector3<T>& start, const TIntVector3<T>& dest, Rt t);
/**
* Linearly interpolates between two vectors.
*
* @param(v1) Starting vector
* @param(dest) Destination vector
* @param(t) 0.0 to 1.0 interpolation value
*
* @return Cross product of v1 and v2
* @note Does not clamp t between 0.0 and 1.0.
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> LerpUnclamped(const TIntVector3<T>& start, const TIntVector3<T>& dest, Rt t);
/**
* Creates a new Vector by the componentwise max of both vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Vector of componentwise max
*/
template<IntType T>
TIntVector3<T> Max(const TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Creates a new Vector by the componentwise min of both vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Vector of componentwise min
*/
template<IntType T>
TIntVector3<T> Min(const TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Gets reversed vector.
*
* @param(v1) Vector one
*
* @note result is stored in v1.
*/
template<IntType T>
TIntVector3<T> Negate(const TIntVector3<T>& v1);
/**
* Multiplies vector componentwise.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Vector with componentwise products
*/
template<IntType T>
TIntVector3<T> Scale(const TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Clamps vector to a range of magnitudes.
*
* @param(v1) Vector to clamp
* @param(min) Min magnitude
* @param(max) Max magnitude
*
* @return Clamped vector
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> ClampMagnitude(const TIntVector3<T>& v1, T min, T max);
/**
* Binds vector into cube.
*
* @param(v1) Vector to clamp
* @param(cubeRadius) Radius of the cube
*
* @result Vector clamped in cube.
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> BoundToCube(const TIntVector3<T> v1, T cubeRadius) {};
/**
* Clamps vector into cube.
*
* @param(v1) Vector to clamp
* @param(cubeRadius) Radius of the cube
*
* @result Vector clamped in cube.
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> ClampToCube(const TIntVector3<T> v1, T cubeRadius) {};
/**
* Scales vector two specific magnitude.
*
* @param(v1) Vector
*
* @note It's faster to use operator* or operator*= for naturaly normalized vectors.
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> ScaleToMagnitude(const TIntVector3<T>& v1, T magnitude);
/**
* Clamps vector into cube.
*
* @param(v1) Vector
*
* @result Vector with inverted components.
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> CompInverse(const TIntVector3<T>& v1);
/**
* Reflect by plane
*
* @param(v1) Vector to mirror
* @param(plane) Plane to mirror on
*
* @return Mirrored vector
*/
template<IntType T, RealType Rt = float>
FORCEINLINE TVector3<Rt> ReflectFromPlane(const TIntVector3<T>& v1, const TPlane<Rt>& plane);
/**
* Reflect by plane
*
* @param(v1) Vector to mirror
* @param(plane) Normal of plane
*
* @return Mirrored vector
*/
template<IntType T, RealType Rt = float>
FORCEINLINE TVector3<Rt> ReflectFromPlane(const TIntVector3<T>& v1, const TVector3<Rt>& normal);
/**
* Rotates vector around axis
*
* @param(v1) Vector to mirror
* @param(axisNormal) Axis to rotate around
*
* @return Rotated vector
* @note Calculates vector rotation with Rodrigues-Rotation
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> RotateAroundAxis(const TIntVector3<T>& v1, const TVector3<Rt>& axisNormal, Rt angle);
/**
* Gets vector triple product ((v1 x v2) x v3).
*
* @param(v1) Vector one
* @param(v2) Vector two
* @param(v3) Vector three
*
* @return Vector triple product
*/
template<IntType T>
TIntVector3<T> VectorTriple(const TIntVector3<T>& v1, const TIntVector3<T>& v2, const TIntVector3<T>& v3);
/**
* Projects vector v1 onto v2
*
* @param(v1) Vector to project
* @param(v2) Vector to project on
*
* @return Projected vector
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> Project(const TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Rejects vector v1 from v2
*
* @param(v1) Vector to reject
* @param(v2) Vector to reject from
*
* @return Rejected vector
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> Reject(const TIntVector3<T>& v1, const TIntVector3<T>& v2);
/**
* Projects vector onto plane
*
* @param(v1) Vector to reject
* @param(normal) Normal of the plane
*
* @return Projected vector
* @note Simply rejects the vector from normal
*/
template<IntType T, RealType Rt = float>
FORCEINLINE TVector3<Rt> ProjectOntoPlane(const TIntVector3<T>& v1, const TVector3<Rt>& normal);
/**
* Projects vector onto plane
*
* @param(v1) Vector to reject
* @param(normal) Plane
*
* @return Projected vector
* @note Simply rejects the vector from normal
*/
template<IntType T, RealType Rt = float>
FORCEINLINE TVector3<Rt> ProjectOntoPlane(const TIntVector3<T>& v1, const TPlane<Rt>& plane);
/**
* Interpolate vector v1 to desitnation v2 using v1 constant s. The magnitude of the vector stays the same throughout the interpolation.
*
* @param(v1) Starting vector
* @param(v2) Destination vector
* @param(t) 0.0 to 1.0 interpolation value
*
* @return Interpolated unit vector
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> Slerp(const TIntVector3<T>& v1, const TIntVector3<T>& v2, Rt t) {};
/**
* Interpolate vector v1 to desitnation v2 using v1 constant s. The magnitude of the vector stays the same throughout the interpolation.
*
* @param(v1) Starting vector
* @param(v2) Destination vector
* @param(t) 0.0 to 1.0 interpolation value
*
* @return Interpolated unit vector.
* @note Does not clamp s between 0.0 and 1.0.
*/
template<IntType T, RealType Rt = float>
TVector3<Rt> SlerpUnclamped(const TIntVector3<T>& v1, const TIntVector3<T>& v2, Rt t) {};
} // phanes::core::math::coretypes
#endif // !INTVECTOR3_H

View File

@ -0,0 +1,941 @@
#pragma once
#include "Misc/BoilerplateHeader.h"
#include PHANES_CORE_PCH_DEFAULT_PATH
#include "Math/MathCommon.h"
#include "Math/MathAbstractTypes.h"
#include "Math/MathFwd.h"
#ifndef P_DEBUG
#pragma warning(disable : 4244)
#endif
#ifndef INTVECTOR4_H
#define INTVECTOR4_H
namespace phanes::core::math::coretypes {
/**
* A 4D Vector with components x, y, z and w with integer precision.
*/
template<typename T>
struct IntVector4 {
static_assert(std::is_integral_v(T), "T must be an integer type.");
public:
union
{
struct
{
/** X component of Vector
*
* @ref [FIELD]components
*
* @note x does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
*/
T x = &components[1];
/** Y component of Vector
*
* @ref [FIELD]components
*
* @note y does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
*/
T y = &components[1];
/** Z component of Vector
*
* @ref [FIELD]components
*
* @note z does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
*/
T z = &components[2];
/** W component of Vector
*
* @ref [FIELD]components
*
* @note w does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
*/
T w = &components[3];
};
/** Components array holding the data
*
* @ref [FIELD]x
* @ref [FIELD]y
* @ref [FIELD]z
* @ref [FIELD]w
*
* @note Components are split into x, y, z and w. Access and manipulation is possible by these variables.
*/
T components[4];
};
public:
/**
* Default constructor without initialization
*/
PHANES_CORE_API IntVector4() = default;
/**
* Construct Vector from xy components.
*
* @param x X component
* @param y Y component
* @param z Z component
* @param w W component
*/
PHANES_CORE_API IntVector4(const T x, const T y, const T z, const T w);
/**
* Construct Vector from two component array.
*
* @param comp Array of components
*/
PHANES_CORE_API IntVector4(const T comp[4]);
/**
* Construct Vector from 2D Vector's xy and the last two zero.
*
* @param v 2D IntVector to copy from
*/
PHANES_CORE_API IntVector4(const Vector2<T>& v);
/**
* Construct Vector from 3D Vector's xyz and zero.
*
* @param v 3D Vector to copy from
*/
PHANES_CORE_API IntVector4(const Vector3<T>& v);
/**
* Construct Vector from 4D Vector's xyzw.
*
* @param v 4D Vector to copy from
*/
PHANES_CORE_API IntVector4(const Vector4<T>& v);
/**
* Construct Vector from 2D integer Vector's xy and the last two zero.
*
* @param v 3D IntVector to copy from
*/
PHANES_CORE_API IntVector4(const IntVector2<T>& v);
/**
* Construct Vector from 4D integer Vector's xyz and zero.
*
* @param v 4D IntVector to copy from
*/
PHANES_CORE_API IntVector4(const IntVector3<T>& v);
/**
* Construct Vector from 3D Point's xyzw.
*
* @param v 3D Point to copy from
*/
PHANES_CORE_API IntVector4(const IntPoint4<T>& v);
};
// List of IntVector4 for DoP and ECS
// List of 4D Vectors using int
using IntVector4List = std::vector <IntVector4<int>>;
// ======================== //
// IntVector4 operators //
// ======================== //
/**
* Addition operation on same IntVector4 (this) by a integer value.
*
* @param a Vector to add to
* @param s integer to add
*/
template<typename T>
INLINE PHANES_CORE_API void operator+= (IntVector4<T>& a, T s);
/**
* Addition operation on same IntVector4 (this) by a another IntVector4.
*
* @param a Vector to add to
* @param b Vector to add
*/
template<typename T>
INLINE PHANES_CORE_API void operator+= (IntVector4<T>& a, const IntVector4<T>& b);
/**
* Substraction operation on same IntVector4 (this) by a integer.
*
* @param a Vector to substract from
* @param b integer to substract
*/
template<typename T>
INLINE PHANES_CORE_API void operator-= (IntVector4<T>& a, T s);
/**
* Substraction operation on same IntVector4 (this) by a another IntVector4.
*
* @param a Vector to substract from
* @param b Vector to substract
*/
template<typename T>
INLINE PHANES_CORE_API void operator-= (IntVector4<T>& a, const IntVector4<T>& b);
/**
* Multiplication of IntVector4 (this) with a integer. (Scale)
*
* @param a Vector to multiply with
* @param s integer to multiply with
*/
template<typename T>
INLINE PHANES_CORE_API void operator*= (IntVector4<T>& a, T s);
/**
* Devision of Vector (this) by integer.
*
* @ref [FUNC]DivideTruncV
* @ref [FUNC]DivideFloatV
*
* @param a Vector to multiply with
* @param s integer to divide with
*
* @note Rounds components
*/
template<typename T>
INLINE PHANES_CORE_API void operator/= (IntVector4<T>& a, T s);
/**
* Componentwise divison of Vector (this) by another vector
*
* @ref [FUNC]DivideTruncV
* @ref [FUNC]DivideFloatV
*
* @param a Vector to multiply with
* @param b Vector to divide with
*
* @note Rounds components
*/
template<typename T>
INLINE PHANES_CORE_API void operator/= (IntVector4<T>& a, const IntVector4<T>& b);
/**
* Scale of Vector by integer. (> Creates a new IntVector4)
*
* @param a Vector to multiply with
* @param s integer to multiply with
*
* @return Result Vector
*/
template<typename T>
INLINE PHANES_CORE_API IntVector4<T> operator* (const IntVector4<T>& a, T s);
/**
* Scale of Vector by integer. (> Creates a new IntVector4)
*
* @param a Vector to multiply with
* @param s integer to multiply with
*
* @return Result Vector
*/
template<typename T>
INLINE PHANES_CORE_API IntVector4<T> operator* (T s, const IntVector4<T>& a);
/**
* Dot product between two Vectors.
*
* @ref [FUNC]DotP
*
* @param a Vector one
* @param b Vector two
*
* @result Dot product
*/
template<typename T>
INLINE PHANES_CORE_API T operator* (const IntVector4<T>& a, const IntVector4<T>& b);
/**
* Division of Vector by integer. (> Creates another IntVector4)
*
* @param a Vector to multiply with
* @param s integer to divide with
*
* @return Result Vector
*/
template<typename T>
INLINE PHANES_CORE_API IntVector4<T> operator/ (const IntVector4<T>& a, T s);
/**
* Division of Vector by integer. (> For convenience not arithmethicaly correct. Works like overloaded counterpart.)
*
* @ref [FUNC]DivideTrunc
* @ref [FUNC]DivideFloat
*
* @param a Vector to multiply with
* @param s integer to divide with
*
* @note Rounds components
*
* @return Result Vector
*/
template<typename T>
INLINE PHANES_CORE_API IntVector4<T> operator/ (T s, const IntVector4<T>& a);
/**
* Componentwise division of Vector (> For convenience not arithmethicaly correct. Works like overloaded counterpart.)
*
* @ref [FUNC]DivideTrunc
* @ref [FUNC]DivideFloat
*
* @param a Vector to multiply with
* @param s integer to divide with
*
* @note Rounds components
*
* @return Result Vector
*/
template<typename T>
INLINE PHANES_CORE_API IntVector4<T> operator/ (const IntVector4<T>& a, const IntVector4<T>& b);
/**
* Componentwise addition of Vector with integer.
*
* @param a Vector to add to
* @param s integer to add
*
* @return Result Vector
*/
template<typename T>
INLINE PHANES_CORE_API IntVector4<T> operator+ (const IntVector4<T>& a, T s);
/**
* Componentwise addition of Vector with integer.
*
* @param a Vector to add to
* @param s integer to add
*
* @return Result Vector
*/
template<typename T>
INLINE PHANES_CORE_API IntVector4<T> operator+ (const IntVector4<T>& a, const IntVector4<T>& b);
/**
* Componentwise substraction of Vector with integer.
*
* @param a Vector to substract from
* @param s integer to substract
*
* @return Result Vector
*/
template<typename T>
INLINE PHANES_CORE_API IntVector4<T> operator- (const IntVector4<T>& a, T s);
/**
* Componentwise substraction of Vector with Vector.
*
* @param a Vector to substract from
* @param s integer to substract
*
* @return Result Vector
*/
template<typename T>
INLINE PHANES_CORE_API IntVector4<T> operator- (const IntVector4<T>& a, const IntVector4<T>& b);
/**
* Negate Vector.
*
* @param a Vector to negate
*/
template<typename T>
INLINE PHANES_CORE_API void operator- (IntVector4<T>& a);
/**
* Compare Vector for equality.
*
* @ref [FUNC]Equals
*
* @param a Vector to negate
*
* @return true if equal, false if inequal
*/
template<typename T>
INLINE PHANES_CORE_API bool operator== (const IntVector4<T>& a, const IntVector4<T>& b);
/**
* Compare Vector for inequality.
*
* @ref [FUNC]Equals
*
* @param a Vector to negate
*
* @return true if inequal, false if equal
*/
template<typename T>
INLINE PHANES_CORE_API bool operator!= (const IntVector4<T>& a, const IntVector4<T>& b);
// ============================================== //
// IntVector4 static function implementation //
// ============================================== //
/**
* Magnitude of Vector
*
* @param a Vector
*
* @return Size of Vector
*/
template<typename T>
PHANES_CORE_API T Magnitude(const IntVector4<T>& a);
/**
* Square of magnitude of Vector
*
* @param a Vector
*
* @return Magnitude without calculating square root
*/
template<typename T>
PHANES_CORE_API T SqrMagnitude(const IntVector4<T>& a);
/**
* Normalize Vector
*
* @param a Vector
*/
template<typename T>
PHANES_CORE_API void NormalizeV(IntVector4<T>& a);
/**
* Angle between to Vectors
*
* @param a Vector one
* @param b Vector two
*/
template<typename T>
PHANES_CORE_API T Angle(const IntVector4<T>& a, const IntVector4<T>& b);
/**
* Dot product of two Vectors
*
* @param a Vector one
* @param b Vector two
*/
template<typename T>
PHANES_CORE_API T DotP(const IntVector4<T>& a, const IntVector4<T>& b);
/**
* Creates Vector, with component wise largest values.
*
* @param a Vector one
* @param b Vector two
*
* @note Stores new Vector to a
*/
template<typename T>
PHANES_CORE_API void MaxV(IntVector4<T>& a, const IntVector4<T>& b);
/**
* Creates Vector, with component wise smallest values.
*
* @param a Vector one
* @param b Vector two
*
* @note Stores new Vector to a
*/
template<typename T>
PHANES_CORE_API void MinV(IntVector4<T>& a, const IntVector4<T>& b);
/**
* Gets perpendicular Vector to a.
*
* @reg NO_RETURN(ReversePerpendicular)
*
* @param a Vector one
*
* @note Stores new Vector to a
*/
template<typename T>
PHANES_CORE_API void PerpendicularV(IntVector4<T>& a);
/**
* Gets perpendicular Vector to a.
*
* @reg NO_RETURN(Perpendicular)
*
* @param a Vector one
*
* @note Stores new Vector to a
*/
template<typename T>
PHANES_CORE_API void ReversePerpendicularV(IntVector4<T>& a);
/**
* Component wise multiplication of Vector
*
* @param a Vector one
* @param b Vector two
*
* @note Stores new Vector to a
*/
template<typename T>
PHANES_CORE_API void ScaleV(IntVector4<T>& a, const IntVector4<T>& b);
/**
* Component wise division of Vector
*
* @param a Vector one
* @param b Vector two
*
* @note Truncates result instead of rounding
* @note Stores new Vector to a
*/
template<typename T>
PHANES_CORE_API void DivideTruncV(IntVector4<T>& a, const IntVector4<T>& b);
/**
* Component wise division of Vector
*
* @param a Vector one
* @param b Vector two
*
* @note Truncates result instead of rounding
* @note Stores new Vector to a
*/
template<typename T>
PHANES_CORE_API void DivideTruncV(IntVector4<T>& a, T s);
/**
* Componentwise inversion of Vector
*
* @param a Vector one
*
* @note Stores new Vector to a
*/
template<typename T>
PHANES_CORE_API void CompInverseV(IntVector4<T>& a);
/**
* Reflect Vector by normal vector.
*
* @param a Vector one
* @param b Vector two
*
* @note Stores new Vector to a
*/
template<typename T>
PHANES_CORE_API void ReflectV(IntVector4<T>& a, const IntVector4<T>& normal);
/**
* Copies one Vector two another
*
* @param a Vector to copy to
* @param b Vector to copy
*/
template<typename T>
PHANES_CORE_API void Set(IntVector4<T>& a, const IntVector4<T>& b);
/**
* Sets components of a vector.
*
* @param a Vector to copy to
* @param b Vector to copy
*/
template<typename T>
PHANES_CORE_API void Set(IntVector4<T>& a, T x, T y, T z, T w);
/**
* Tests if vector is a unity vector.
*
* @param a Vector one
* @param threshold Threshold to one
*
* @return true if unit vector, false if not
*/
template<typename T>
PHANES_CORE_API bool IsNormalized(const IntVector4<T>& a, T threshold = P_FLT_INAC);
/**
* Tests if 2 vectors are perpendicular to each other.
*
* @param a Vector one
* @param b Vector two
* @param threshold Threshold
*
* @return true if perpendicular, false if not
*/
template<typename T>
PHANES_CORE_API bool IsPerpendicular(const IntVector4<T>& a, const IntVector4<T>& b, T threshold = P_FLT_INAC);
/**
* Tests if 2 vectors are parallel to each other. (Angle is close to zero.)
*
* @param a Vector one
* @param b Vector two
* @param threshold Threshold
*
* @return true if parallel, false if not
*/
template<typename T>
PHANES_CORE_API bool IsParallel(const IntVector4<T>& a, const IntVector4<T>& b, T threshold = P_FLT_INAC);
/**
* Tests if 2 vectors are coincident. (Are parallel and point in the same direction.)
*
* @param a Vector one
* @param b Vector two
* @param threshold Threshold
*
* @return true if coincident, false if not
*/
template<typename T>
PHANES_CORE_API bool IsCoincident(const IntVector4<T>& a, const IntVector4<T>& b, T threshold = P_FLT_INAC);
/**
* Gets outer product of to vectors.
*
* @param a Vector one
* @param b Vector two
*
* @return Resulting matrix
*/
template<typename T>
PHANES_CORE_API Matrix2<T> OuterProduct(const IntVector4<T>& a, const IntVector4<T>& b);
// ================================================================ //
// IntVector4 static function implementation with return values //
// ================================================================ //
/**
* Reflects a vector on a normal
*
* @param a Vector one
* @param normal Normal vector
*
* @return Reflected vector
*/
template<typename T>
PHANES_CORE_API IntVector4<T> Reflect(const IntVector4<T>& a, const IntVector4<T>& normal);
/**
* Scales a vector component wise
*
* @param a Vector one
* @param b Vector two
*
* @return Reflected vector
*/
template<typename T>
PHANES_CORE_API IntVector4<T> Scale(const IntVector4<T>& a, const IntVector4<T>& b);
/**
* Component wise division of Vector
*
* @param a Vector one
* @param b Vector two
*
* @note Truncates result instead of rounding
*/
template<typename T>
PHANES_CORE_API IntVector4<T> DivideTrunc(const IntVector4<T>& a, const IntVector4<T>& b);
/**
* Component wise division of Vector
*
* @param a Vector one
* @param b Vector two
*
* @note Truncates result instead of rounding
*/
template<typename T>
PHANES_CORE_API IntVector4<T> DivideTrunc(const IntVector4<T>& a, T s);
/**
* Component wise division of Vector
*
* @param a Vector one
* @param b Vector two
*
* @return Floating point vector
*/
template<typename T>
PHANES_CORE_API Vector2<T> DivideFloat(const IntVector4<T>& a, const IntVector4<T>& b);
/**
* Component wise division of Vector
*
* @param a Vector one
* @param b Vector two
*
* @return Floating point vector
*/
template<typename T>
PHANES_CORE_API Vector2<T> DivideFloat(const IntVector4<T>& a, T s);
/**
* Componentwise inverse of Vector
*
* @param a Vector one
* @param b Vector two
*
* @return Reflected vector
*/
template<typename T>
PHANES_CORE_API IntVector4<T> CompInverse(const IntVector4<T>& a);
/**
* Gets the perpendicular vector of a
*
* @param a Vector one
*
* @return Perpendicular vector
*/
template<typename T>
PHANES_CORE_API IntVector4<T> Perpendicular(const IntVector4<T>& a);
/**
* Gets reverse of the perpendicular vector of a
*
* @param a Vector one
*
* @return Reversed perpendicular vector
*/
template<typename T>
PHANES_CORE_API IntVector4<T> ReversePerpendicular(const IntVector4<T>& a);
/**
* Creates a new Vector by the component wise minimals of both vectors
*
* @param a Vector one
* @param b Vector two
*
* @return Minimal vector
*/
template<typename T>
PHANES_CORE_API IntVector4<T> Min(const IntVector4<T>& a, const IntVector4<T>& b);
/**
* Creates a new Vector by the component wise maxima of both vectors
*
* @param a Vector one
* @param b Vector two
*
* @return Maximal vector
*/
template<typename T>
PHANES_CORE_API IntVector4<T> Max(const IntVector4<T>& a, const IntVector4<T>& b);
/**
* Creates a normalized instance of the vector
*
* @param a Vector to normalize
*
* @return Unit vector
*/
template<typename T>
PHANES_CORE_API IntVector4<T> Normalize(const IntVector4<T>& a);
/**
* Interpolates between to vectors.
*
* @param a Start value (t = 0)
* @param b End value (t = 1)
* @param t Interpolation value
*
* @return Interpolated vector
*
* @note Interpolation is clamped between 0 - 1.
*/
template<typename T>
INLINE PHANES_CORE_API IntVector4<T> Lerp(const IntVector4<T>& a, const IntVector4<T>& b, T t);
/**
* Interpolates between to vectors.
*
* @param a Start value (t = 0)
* @param b End value (t = 1)
* @param t Interpolation value
*
* @return Interpolated vector
*
* @note Interpolation is not clamped.
*/
template<typename T>
INLINE PHANES_CORE_API IntVector4<T> LerpUnclamped(const IntVector4<T>& a, const IntVector4<T>& b, T t);
/**
* Spherical interpolation between two vectors.
*
* @param a Start value (t = 0)
* @param b End value (t = 1)
* @param t Interpolation value
*
* @return Interpolated vector
*
* @note Interpolation is clamped between 0 - 1.
* @note Quaternion are more efficient and should be used if possible.
*/
template<typename T>
PHANES_CORE_API IntVector4<T> Slerp(const IntVector4<T>& a, const IntVector4<T>& b, T t);
/**
* Spherical interpolation between two vectors.
*
* @param a Start value (t = 0)
* @param b End value (t = 1)
* @param t Interpolation value
*
* @return Interpolated vector
*
* @note Interpolation is clamped between 0 - 1.
* @note Quaternion are more efficient and should be used if possible.
*/
template<typename T>
PHANES_CORE_API IntVector4<T> SlerpUnclamped(const IntVector4<T>& a, const IntVector4<T>& b, T t);
} // phanes::core::math::coretypes
#endif // !INTVECTOR3_H

View File

@ -0,0 +1,29 @@
#pragma once
#ifndef ABSTRACT_TYPES_H
#define ABSTRACT_TYPES_H
namespace Phanes::Core::Math::Internal {
template <typename T, unsigned int D = 3>
struct AVector {
public:
/**
* List of n components of the vector
*/
T comp[D];
};
template <typename T, unsigned int n = 3, unsigned int m = 3>
struct AMatrix {
public:
T fields[n][m];
};
}; // Phanes::Core::Math::abstract::coretypes
#endif // !ABSTRACT_TYPES_H

View File

@ -0,0 +1,98 @@
#pragma once
#define P_FLT_INAC_LARGE 0.0001f // large float inaccuracy (1*10^-4);
#define P_FLT_INAC 0.00001f // float inaccuracy (1*10^-5);
#define P_FLT_INAC_SMALL 0.000001f // small float inaccuracy (1*10^-6);
#define P_180_PI 57.29577951308232 // (double) 180°/pi;
#define P_180_PI_FLT 57.29577951308232f // (float) 180°/pi;
#define P_PI_180 0.0174532925199432 // double pi/180°
#define P_PI_180_FLT 0.0174532925199432f // (float) pi/180°
#define P_PI 3.1415926535897932 // PI
#define P_PI_FLT 3.1415926535897932f // PI
#include "Core/Core.h"
#ifndef MATH_COMMON_H
#define MATH_COMMON_H
namespace Phanes::Core::Math {
/**
* Clamps a value between minimum and maximum
*
* @param value Value to clamp
* @param low Minimum
* @param high Maximum
*
* @return Minimum, if value is to small / Maximum, if value is to large / value, if value is in range.
*/
template<typename T>
T Clamp(T value, T low, T high);
/**
* Gets the larger of two values
*
* @param x
* @param y
*
* @return Larger value
*/
template<typename T>
inline T Max(T x, T y);
/**
* Gets the smaller of two values
*
* @param x
* @param y
*
* @return Smaller value
*/
template<typename T>
inline T Min(T x, T y);
/**
* Swaps the values of two variables
*
* @param x
* @param y
*/
template<typename T>
inline void Swap(T& x, T& y);
/**
* Test two numbers for equality
*
* @param x
*/
template<typename T>
bool Equals(T x, T y, T threshold = P_FLT_INAC);
/**
* Calculates the reciprocal of the square root of n using the algorithm of A Quake III
*
* @param n Number to calculate
*
* @return Inverse square root of n
*
* @note a simple 1.0f / sqrtf(x) is faster than this algorithm. Use for research purpose only.
*/
template<typename T>
float FastInvSqrt(T n);
} // phanes
#endif // !MATH_COMMON_H

View File

@ -0,0 +1,103 @@
#pragma once
#include "Core/Core.h"
#include "Core/public/OSAL/PlatformTypes.h"
#ifndef MATH_FWD_H
#define MATH_FWD_H
#include "Core/public/Misc/Boilerplate.h"
/**
* Includes forward declarations, as well as certain useful typedefs.
*
* @ref OSAL/PlatformTypes.h
*/
namespace Phanes::Core::Math {
/**
* Template forward declarations.
*/
template<RealType T> struct TColor;
template<RealType T> struct TLinearColor;
template<RealType T> struct TVector2;
template<RealType T> struct TVector3;
template<RealType T> struct TVector4;
template<RealType T> struct TRay;
template<RealType T> struct TPlane;
template<RealType T> struct TMatrix2;
template<RealType T> struct TMatrix3;
template<RealType T> struct TMatrix4;
template<RealType T> struct TQuaternion;
template<RealType T> struct TTransform;
template<RealType T> struct TPoint2;
template<RealType T> struct TPoint3;
template<RealType T> struct TPoint4;
template<IntType T> struct TIntVector2;
template<IntType T> struct TIntVector3;
template<IntType T> struct TIntVector4;
template<IntType T> struct TIntPoint2;
template<IntType T> struct TIntPoint3;
template<IntType T> struct TIntPoint4;
/**
* Specific instantiation of forward declarations.
*/
// TVector2
typedef TVector2<float> Vector2;
typedef TVector2<double> Vector2d;
typedef std::vector<Vector2> Vector2List;
typedef std::vector<Vector2d> Vector2Listd;
// TVector3
typedef TVector3<float> Vector3;
typedef TVector3<double> Vector3d;
typedef std::vector<Vector3> Vector3List;
typedef std::vector<Vector3d> Vector3Listd;
// TIntVector2
typedef TIntVector2<int> IntVector2;
typedef TIntVector2<long> IntVector2l;
typedef std::vector<IntVector2> IntVector2List;
typedef std::vector<IntVector2l> IntVector2Listl;
// TIntVector3
typedef TIntVector3<int> IntVector3;
typedef TIntVector3<long> IntVector3l;
typedef std::vector<IntVector3> IntVector3List;
typedef std::vector<IntVector3l> IntVector3Listl;
// TMatrix2
typedef TMatrix2<float> Matrix2;
typedef TMatrix2<double> Matrix2d;
typedef std::vector<Matrix2> Matrix2List;
typedef std::vector<Matrix2d> Matrix2Listd;
} // Phanes::Core::Math::coretypes
namespace Phanes::Core::Math::Internal
{
// Internal types
template <typename T, unsigned int D> struct AVector;
template <typename T, unsigned int n, unsigned int> struct AMatrix;
}
#endif // !MATH_FWD_H

View File

@ -0,0 +1,77 @@
#pragma once
// ============================================= //
// Function to convert types into each other //
// //
// @ref [FILE]MathUnitConversion //
// ============================================= //
#include "PhanesEnginePCH.h"
#include "Core/public/Misc/Boilerplate.h"
#include "Core/public/Math/MathAbstractTypes.h"
#include "Core/public/Math/Vector2.h"
#include "Core/public/Math/Vector3.h"
//#include "Core/public/Math/Vector4.h"
//#include "Core/public/Math/Matrix2.h"
//#include "Core/public/Math/Matrix3.h"
#include "Core/public/Math/IntVector2.h"
#include "Core/public/Math/IntVector3.h"
#ifndef MATH_TYPE_CONVERSION_H
#define MATH_TYPE_CONVERSION_H
namespace Phanes::Core::Math {
// =================================================== //
// std::to_string wrapper //
// //
// This is, to make using ToString more general //
// and allow usage of one function instead of two, //
// for converting a mathmatical type to a string. //
// =================================================== //
FORCEINLINE std::string ToString(long long val) { return std::to_string(val); };
FORCEINLINE std::string ToString(double val) { return std::to_string(val); };
FORCEINLINE std::string ToString(float val) { return std::to_string(val); };
FORCEINLINE std::string ToString(int val) { return std::to_string(val); };
FORCEINLINE std::string ToString(long val) { return std::to_string(val); };
FORCEINLINE std::string ToString(long double val) { return std::to_string(val); };
FORCEINLINE std::string ToString(unsigned long long val) { return std::to_string(val); };
FORCEINLINE std::string ToString(unsigned int val) { return std::to_string(val); };
FORCEINLINE std::string ToString(unsigned long val) { return std::to_string(val); };
// ============ //
// ToString //
// ============ //
template<RealType T>
std::string ToString(const TVector2<T>& v);
template<IntType T>
std::string ToString(const TIntVector2<T>& v);
template<RealType T>
std::string ToString(const TVector3<T>& v);
template<IntType T>
std::string ToString(const TIntVector3<T>& v);
//std::string toString(const Vector4& v);
//std::string toString(const Matrix2& v);
//std::string toString(const Matrix3& v);
}
#endif // !MATH_TYPE_CONVERSION_H

View File

@ -0,0 +1,112 @@
#pragma once
// ======================================= //
// Contains functions to convert units //
// ======================================= //
#include "Core/public/Misc/Boilerplate.h"
#include "Core/public/Math/MathCommon.h"
namespace Phanes::Core::Math::UnitConversion
{
/**
* Converts degrees to radians.
*
* @param(deg) Angle in degress (°)
*
* @return Angle in radians
*/
template<RealType T>
inline T DegToRad(T deg);
/**
* Converts radians to degrees.
*
* @param(rad) Angle in radians (rad)
*
* @return Angle in degrees
*/
template<RealType T>
inline T RadToDeg(T rad);
/**
* Converts degrees to gradian.
*
* @param(deg) Angle in degress (°)
*
* @return Angle in gradian
*/
template<RealType T>
inline T DegToGradian(T deg);
/**
* Converts gradian to degrees.
*
* @param(rad) Angle in gradians (g)
*
* @return Angle in degrees
*/
template<RealType T>
inline T GradianToDeg(T g);
/**
* Converts radians to gradians.
*
* @param(deg) Angle in radians (rad)
*
* @return Angle in gradians
*/
template<RealType T>
inline T RadToGradian(T rad);
/**
* Converts gradian to radians.
*
* @param(rad) Angle in gradians (g)
*
* @return Angle in radians
*/
template<RealType T>
inline T GradianToRad(T g);
} // phanes::core::math::typeconversion
namespace Phanes::Core::Math::UnitLiterals
{
// ============================================== //
// unit conversion with user-defined literals //
// ============================================== //
/**
* Convert deg to rad.
*
* @param(_x) Angle in degress
*/
double operator ""_deg(long double _x);
/**
* Convert rad to rad.
*
* @param(_x) Angle in degress
*/
double operator ""_rad(long double _x);
/**
* Convert gradian to rad.
*
* @param(_x) Angle in degress
*/
double operator ""_g(long double _x);
}

View File

@ -0,0 +1,154 @@
#pragma once
#include "Core/Core.h"
#include "Core/public/Misc/Boilerplate.h"
#include "Core/public/Math/Vector2.h"
#ifndef MATRIX2_H
#define MATRIX2_H
namespace Phanes::Core::Math {
// 2x2 Matrix defined in column-major order.
// Accessed by M[Row][Col].
template<RealType T>
struct alignas(4) TMatrix2
{
public:
alignas(4) T m[2][2];
public:
TMatrix2() = default;
/**
* Copy constructor.
*/
TMatrix2(const TMatrix2<T>& m1);
/**
* Move constructor.
*/
TMatrix2(TMatrix2<T>&& m);
/**
* Construct Matrix from 2d array.
*
* @param(fields) 2D Array with column major order.
*/
TMatrix2(T fields[2][2]);
/**
* Construct Matrix from parameters.
*
* @param(n00) M[0][0]
* @param(n10) M[1][0]
* @param(n01) M[0][1]
* @param(n11) M[1][1]
*
* @note nXY = n[Row][Col]
*/
TMatrix2(T n00, T n10, T n01, T n11);
/**
* Construct Matrix from two 2d vector columns.
*
* @param(v1) Column zero
* @param(v2) Column one
*/
TMatrix2(const TVector2<T>& v1, const TVector2<T>& v2);
public:
FORCEINLINE T& operator() (int n, int m);
FORCEINLINE TVector2<T>& operator[] (int m);
FORCEINLINE const T& operator() (int n, int m) const;
FORCEINLINE const TVector2<T>& operator[] (int m) const;
};
// ===================== //
// TMatrix2 operator //
// ===================== //
template<RealType T>
TMatrix2<T> operator+= (TMatrix2<T>& m1, T s);
template<RealType T>
TMatrix2<T> operator+= (TMatrix2<T>& m1, const TMatrix2<T>& m2);
template<RealType T>
TMatrix2<T> operator-= (TMatrix2<T>& m1, T s);
template<RealType T>
TMatrix2<T> operator-= (TMatrix2<T>& m1, const TMatrix2<T>& m2);
template<RealType T>
TMatrix2<T> operator*= (TMatrix2<T>& m1, T s);
template<RealType T>
TMatrix2<T> operator*= (TMatrix2<T>& m1, const TMatrix2<T>& m2);
template<RealType T>
TMatrix2<T> operator+ (const TMatrix2<T>& m1, T s);
template<RealType T>
TMatrix2<T> operator+ (const TMatrix2<T>& m1, const TMatrix2<T>& m2);
template<RealType T>
TMatrix2<T> operator- (const TMatrix2<T>& m1, T s);
template<RealType T>
TMatrix2<T> operator- (const TMatrix2<T>& m1, const TMatrix2<T>& m2);
template<RealType T>
TMatrix2<T> operator* (const TMatrix2<T>& m1, T s);
template<RealType T>
TMatrix2<T> operator* (const TMatrix2<T>& m1, const TMatrix2<T>& m2);
template<RealType T>
TVector2<T> operator* (const TMatrix2<T>& m1, const TVector2<T>& v);
template<RealType T>
bool operator== (const TMatrix2<T>& m1, const TMatrix2<T>& m2);
// =============================== //
// Matrix function definition //
// =============================== //
template<RealType T>
T Determinant(const Matrix2& m1);
template<RealType T>
void InverseV(TMatrix2<T>& m1);
template<RealType T>
void TransposeV(TMatrix2<T>& m1);
// =============== //
// WITH RETURN //
// =============== //
template<RealType T>
TMatrix2<T> Inverse(TMatrix2<T>& m1);
template<RealType T>
TMatrix2<T> Transpose(const TMatrix2<T>& m1);
template<RealType T>
bool IsIndentityMatrix(const TMatrix2<T>& m1, T threshold = P_FLT_INAC);
} // Phanes::Core::Math
#endif // !MATRIX2_H

View File

@ -0,0 +1,23 @@
#pragma once
#include "Core/public/Misc/Boilerplate.h"
#include "Core/public/Math/Vector3.h"
#include "Core/public/Math/MathFwd.h"
namespace Phanes::Core::Math {
// Plane in 3D space, defined as: P: ax + by + cz = d;
template<RealType T>
struct TPlane
{
public:
TVector3<T> normal;
T d;
};
} // Phanes::Core::Math

View File

@ -0,0 +1,184 @@
#pragma once
#include "Core/public/Misc/Boilerplate.h"
#include "Core/public/Math/MathCommon.h"
#include "Core/public/Math/MathAbstractTypes.h"
#include "Core/public/Math/MathFwd.h"
#ifndef P_DEBUG
#pragma warning(disable : 4244)
#endif
/**
* The Point is the same as a vector. The type exists, to ensure
* differentiation between the two types.
*/
#ifndef POINT_H
#define POINT_H
namespace Phanes::Core::Math {
/**
* A 2D Point with components x and y with float precision.
*/
template<RealType T>
struct TPoint2 : public TVector2<T> {
static_assert(std::is_floating_point_v<T>, "T must be a floating point");
using TVector2<T>::TVector2;
using Real = T;
/**
* Creates Point2 from Point3's xy
*
* @param a Point3 one
*/
TPoint2(const TPoint3<T>& p)
{
this->x = p.x;
this->y = p.y;
}
/**
* Creates Point2 from Point4's xy
*
* @param a Point4 one
*/
TPoint2(const TPoint4<T>& p)
{
this->x = p.x;
this->y = p.y;
}
};
/**
* Calculates distance between two points.
*
* @param(p1) Point one
* @param(p2) Point two
*
* @return Distance between two points.
*/
template<RealType T>
T Distance(const TPoint2<T>& p1, const TPoint2<T>& p2);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* A 3D Point with components x and y with float precision.
*/
template<RealType T>
struct TPoint3 : public TVector3<T> {
static_assert(std::is_floating_point_v(T), "T must be a floating point");
using TVector3<T>::TVector3;
using Real = T;
/**
* Creates Point3 from Point2's xy and zero
*
* @param a Point2 one
*/
TPoint3(const TPoint2<T>& p)
{
this->x = p.x;
this->y = p.y;
this->z = 0;
}
/**
* Creates Point3 from Point4's xyz
*
* @param a Point4 one
*/
TPoint3(const TPoint4<T>& p)
{
this->x = p.x;
this->y = p.y;
this->z = p.z;
}
};
/**
* Calculates distance between two points.
*
* @param(p1) Point one
* @param(p2) Point two
*
* @return Distance between two points.
*/
template<RealType T>
T Distance(const TPoint3<T>& p1, const TPoint3<T>& p2);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* A 4D Point with components x and y with float precision.
*/
//template<RealType T>
//struct TPoint4 : public TVector4<T> {
// static_assert(std::is_floating_point_v(T), "T must be a floating point");
// using TVector4<T>::TVector4;
// /**
// * Creates Point4 from Point2's xy and the last two zero
// *
// * @param a Point2 one
// */
// TPoint4(const TPoint2<T>& p)
// {
// this->x = p.x;
// this->y = p.y;
// this->z = 0;
// this->w = 0;
// }
// /**
// * Creates Point4 from Point3's xyz and zero
// *
// * @param a Point3 one
// */
// TPoint4(const TPoint3<T>& p)
// {
// this->x = p.x;
// this->y = p.y;
// this->z = p.z;
// this->w = 0;
// }
//};
///**
// * Calculates distance between two points.
// *
// * @param(p1) Point one
// * @param(p2) Point two
// *
// * @return Distance between two points.
// */
//template<RealType T>
//T Distance(const TPoint4<T>& p1, const TPoint4<T>& p2);
} // phanes::core::math::coretypes
#endif // !POINT_H

View File

@ -0,0 +1,12 @@
# PhanesCore
## Math
### Description
Math lib.
### Notes
- Normals are called normals for a reason.

View File

@ -0,0 +1,938 @@
#pragma once
#include "Core/Core.h"
#include "Core/public/Misc/Boilerplate.h"
#include "Core/public/Math/MathCommon.h"
#include "Core/public/Math/MathAbstractTypes.h"
#include "Core/public/Math/MathFwd.h"
#ifndef P_DEBUG
#pragma warning(disable : 4244)
#endif
#pragma warning(disable: 4661)
#ifndef VECTOR2_H
#define VECTOR2_H
#define PZeroVector2(type) TVector2<##type>(0,0)
#define PVectorSouth2(type) TVector2<##type>(0,-1)
#define PVectorNorth2(type) TVector2<##type>(0,1)
#define PVectorEast2(type) TVector2<##type>(1,0)
#define PVectorWest2(type) TVector2<##type>(-1,0)
namespace Phanes::Core::Math {
/**
* A 2D Vector with components x and y with floating point precision.
*/
template<RealType T>
struct TVector2 {
public:
using Real = T;
// Using in combination with a struct and an array allows us the reflect changes of the x and y variables in the comp array and vise versa.
union
{
struct
{
/** X component of Vector
*
* @see [FIELD]components
* @note x does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
*/
Real x;
/** Y component of Vector
*
* @see [FIELD]components
*
* @note y does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience.
*/
Real y;
};
/** Components array holding the data
*
* @see [FIELD]x
* @see [FIELD]y
*
* @note Components are split into x and y. Access and manipulation is possible by these variables.
*/
Real* comp;
};
public:
/**
* Default constructor without initialization
*/
TVector2() = default;
/**
* Copy constructor
*/
TVector2(const TVector2<Real>& v);
/**
* Move constructor
*/
TVector2(TVector2<Real>&& v);
/**
* Convert other type of vector
*/
template<RealType FloatType>
explicit TVector2(const TVector2<FloatType>& v) : x((T)v.x), y((T)v.y) {};
template<IntType OtherIntType>
explicit TVector2(const TIntVector2<OtherIntType>& v) : x((T)v.x), y((T)v.y) {};
/**
* Construct Vector from xy components.
*
* @param(x) X component
* @param(y) Y component
*/
TVector2(const Real x, const Real y);
/**
* Construct Vector from two component array.
*
* @param(comp) Array of components
*/
explicit TVector2(const Real* comp);
/**
* Constructs a vector pointing from start to end.
*
* @param(start) Startingpoint
* @param(end) Endpoint
*/
TVector2(const TPoint2<Real>& start, const TPoint2<Real>& end);
/**
* Construct Vector from 3D Vector's xy.
*
* @param(v) 3D Vector to copy from
*/
explicit TVector2(const TVector3<Real>& v);
/**
* Construct Vector from 4D Vector's xy.
*
* @param(v) 4D Vector to copy from
*/
//TVector2(const TVector4<Real>& v);
/**
* Construct Vector from 2D integer Vector's xy.
*
* @param(v) 2D IntVector to copy from
*/
//TVector2(const TIntVector2<Real>& v);
/**
* Construct Vector from 3D integer Vector's xy.
*
* @param(v) 3D IntVector to copy from
*/
//TVector2(const TIntVector3<Real>& v);
/**
* Construct Vector from 4D integer Vector's xy.
*
* @param(v) 4D IntVector to copy from
*/
//TVector2(const TIntVector4<Real>& v);
/**
* Construct Vector from 2D Point's xy.
*
* @param(v) 2D Point to copy from
*/
//TVector2(const TPoint2<Real>& v);
};
// template struct TVector2<float>;
// ====================== //
// TVector2 operators //
// ====================== //
/**
* Addition operation on same TVector2<T> (this) by a floating point value.
*
* @param(v1) Vector to add to
* @param(s) Floating point to add
*/
template<RealType T>
TVector2<T> operator+= (TVector2<T>& v1, T s);
/**
* Addition operation on same TVector2<T> (this) by a another TVector2<T>.
*
* @param(v1) Vector to add to
* @param(v2) Vector to add
*/
template<RealType T>
TVector2<T> operator+= (TVector2<T>& v1, const TVector2<T>& v2);
/**
* Substraction operation on same TVector2<T> (this) by a floating point.
*
* @param(v1) Vector to substract from
* @param(v2) Floating point to substract
*/
template<RealType T>
TVector2<T> operator-= (TVector2<T>& v1, T s);
/**
* Substraction operation on same TVector2<T> (this) by a another TVector2<T>.
*
* @param(v1) Vector to substract from
* @param(v2) Vector to substract
*/
template<RealType T>
TVector2<T> operator-= (TVector2<T>& v1, const TVector2<T>& v2);
/**
* Multiplication of TVector2<T> (this) with a floating point.
*
* @param(v1) Vector to multiply with
* @param(s Floating point to multiply with
*/
template<RealType T>
TVector2<T> operator*= (TVector2<T>& v1, T s);
/**
* Devision of Vector (this) by floating point.
*
* @param(v1) Vector to divide with
* @param(s Floating point to divide with
*/
template<RealType T>
TVector2<T> operator/= (TVector2<T>& v1, T s);
/**
* Scale of Vector by floating point. (> Creates a new TVector2<T>)
*
* @param(v1) Vector to multiply with
* @param(s Floating point to multiply with
*
* @return Result Vector
*/
template<RealType T>
TVector2<T> operator* (const TVector2<T>& v1, T s);
/**
* Division of Vector by floating point. (> Creates another TVector2<T>)
*
* @param(v1) Vector to multiply with
* @param(s Floating point to divide with
*
* @return Result Vector
*/
template<RealType T>
TVector2<T> operator/ (const TVector2<T>& v1, T s);
/**
* Scale of Vector by floating point. (> Creates a new TVector2<T>)
*
* @param(v1) Vector to multiply with
* @param(s Floating point to multiply with
*
* @return Result Vector
*/
template<RealType T>
inline TVector2<T> operator* (T s, const TVector2<T>& v1);
/**
* Division of Vector by floating point. (> For convenience not arithmethicaly correct. Works like overloaded counterpart.)
*
* @param(v1) Vector to multiply with
* @param(s Floating point to divide with
*
* @return Result Vector
*/
template<RealType T>
inline TVector2<T> operator/ (T s, const TVector2<T>& v1);
/**
* Dot product between two Vectors.
*
* @see [FUNC]DotP
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @result Dot product
*/
template<RealType T>
T operator* (const TVector2<T>& v1, const TVector2<T>& v2);
/**
* Componentwise addition of Vector with floating point.
*
* @param(v1) Vector to add to
* @param(s Floating point to add
*
* @return Result Vector
*/
template<RealType T>
TVector2<T> operator+ (const TVector2<T>& v1, T s);
/**
* Componentwise addition of Vector with floating point.
*
* @param(v1) Vector to add to
* @param(s Floating point to add
*
* @return Result Vector
*/
template<RealType T>
TVector2<T> operator+ (const TVector2<T>& v1, const TVector2<T>& v2);
/**
* Componentwise substraction of Vector with floating point.
*
* @param(v1) Vector to substract from
* @param(s Floating point to substract
*
* @return Result Vector
*/
template<RealType T>
TVector2<T> operator- (const TVector2<T>& v1, T s);
/**
* Componentwise substraction of Vector with Vector.
*
* @param(v1) Vector to substract from
* @param(s Floating point to substract
*
* @return Result Vector
*/
template<RealType T>
TVector2<T> operator- (const TVector2<T>& v1, const TVector2<T>& v2);
/**
* Negate Vector.
*
* @param(v1) Vector to negate
*/
template<RealType T>
void operator- (TVector2<T>& v1);
/**
* Compare Vector for equality.
*
* @see [FUNC]Equals
*
* @param(v1) Vector to negate
*
* @return true if equal, false if inequal
*/
template<RealType T>
bool operator== (const TVector2<T>& v1, const TVector2<T>& v2);
/**
* Compare Vector for inequality.
*
* @see [FUNC]Equals
*
* @param(v1) Vector to negate
*
* @return true if inequal, false if equal
*/
template<RealType T>
bool operator!= (const TVector2<T>& v1, const TVector2<T>& v2);
// ============================================ //
// TVector2 static function implementation //
// ============================================ //
/**
* Magnitude of Vector
*
* @param(v1) Vector
*
* @return Size of Vector
*/
template<RealType T>
T Magnitude(const TVector2<T>& v1);
/**
* @see [FUNC]Magnitude
*/
template<RealType T>
FORCEINLINE T Length(const TVector2<T>& v1) { return Magnitude(v1); };
/**
* Square of magnitude of Vector
*
* @param(v1) Vector
*
* @return Magnitude without calculating square root
*/
template<RealType T>
T SqrMagnitude(const TVector2<T>& v1);
/**
* @see [FUNC]SqrMagnitude
*/
template<RealType T>
FORCEINLINE T SqrLength(const TVector2<T>& v1) { return SqrMagnitude(v1); };
/**
* Normalize Vector
*
* @param(v1) Vector
*/
template<RealType T>
TVector2<T> NormalizeV(TVector2<T>& v1);
/**
* Normalize Vector
*
* @param(v1) Vector
*
* @note Does not look for zero vector.
*/
template<RealType T>
TVector2<T> UnsafeNormalizeV(TVector2<T>& v1);
/**
* Angle between to Vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*/
template<RealType T>
T Angle(const TVector2<T>& v1, const TVector2<T>& v2);
/**
* Cosine of angle between to Vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*/
template<RealType T>
T CosineAngle(const TVector2<T>& v1, const TVector2<T>& v2);
/**
* Returns signs of components in vector: -1 / +1 / 0.
*
* @param(v1) Vector one
*/
template<RealType T>
TVector2<T> SignVectorV(TVector2<T>& v1);
/**
* Binds a vector to a square with a radius
*
* @param(v1) Vector one
* @param(radius) Radius of square (=> Distance from middle to center of each site.)
*/
template<RealType T>
TVector2<T> BindToSquareV(TVector2<T>& v1, T radius);
/**
* Clamps a vector to a square with a radius
*
* @param(v1) Vector one
* @param(radius) Radius of square (=> Distance from middle to center of each site.)
*/
template<RealType T>
TVector2<T> ClampToSquareV(TVector2<T>& v1, T radius);
/**
* Dot product of two Vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*/
template<RealType T>
T DotP(const TVector2<T>& v1, const TVector2<T>& v2);
/**
* Creates Vector, with component wise largest values.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @note Stores new Vector to v1
*/
template<RealType T>
TVector2<T> MaxV (TVector2<T>& v1, const TVector2<T>& v2);
/**
* Creates Vector, with component wise smallest values.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @note Stores new Vector to v1
*/
template<RealType T>
TVector2<T> MinV (TVector2<T>& v1, const TVector2<T>& v2);
/**
* Gets perpendicular Vector to v1.
*
* @param(v1) Vector one
*
* @note Stores new Vector to v1
*/
template<RealType T>
TVector2<T> GetPerpendicularV (TVector2<T>& v1);
/**
* Gets perpendicular Vector to v1.
*
* @reg [FUNC]PerpendicularV
*
* @param(v1) Vector one
*
* @note Stores new Vector to v1
*/
template<RealType T>
TVector2<T> GetReversePerpendicularV (TVector2<T>& v1);
/**
* Component wise multiplication of Vector
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @note Stores new Vector to v1
*/
template<RealType T>
TVector2<T> ScaleV(TVector2<T>& v1, const TVector2<T>& v2);
/**
* Componentwise inverse of Vector
*
* @param(v1) Vector one
*
* @note Stores new Vector to v1
*/
template<RealType T>
TVector2<T> CompInverseV(TVector2<T>& v1);
/**
* Reflect Vector by normal vector.
*
* @param(v1) Vector one
* @param(normal) Normal of surface
*
* @note Stores new Vector to v1
*/
template<RealType T>
TVector2<T> ReflectV (TVector2<T>& v1, const TVector2<T>& normal);
/**
* Copies one Vector two another
*
* @param(v1) Vector to copy to
* @param(v2) Vector to copy
*/
template<RealType T>
TVector2<T> Set(TVector2<T>& v1, const TVector2<T>& v2);
/**
* Sets components of a vector.
*
* @param(v1) Vector to copy to
* @param(v2) Vector to copy
*/
template<RealType T>
TVector2<T> Set(TVector2<T>& v1, T x, T y);
/**
* Anti-clockwise vector rotation.
*
* @param(v1) Vector to rotate
*
* @note Angle is not clamped
*/
template<RealType T>
TVector2<T> RotateV(TVector2<T>& v1, T angle);
/**
* Clockwise vector rotation.
*
* @param(v1) Vector to rotate
*
* @note Angle is not clamped
*/
template<RealType T>
FORCEINLINE TVector2<T> ClockwiseRotateV(TVector2<T>& v1, T angle);
/**
* Negates Vector
*
* @param(v1) Vector one
*/
template<RealType T>
TVector2<T> NegateV(TVector2<T>& v1);
/**
* Tests if vector is a unity vector.
*
* @param(v1) Vector one
* @param(threshold) Threshold to zero
*
* @return true if unit vector, false if not
*/
template<RealType T>
inline bool IsNormalized(const TVector2<T>& v1, T threshold = P_FLT_INAC);
/**
* Tests if 2 vectors are perpendicular to each other.
*
* @param(v1) Vector one
* @param(v2) Vector two
* @param(threshold) Threshold to zero
*
* @return true if perpendicular, false if not
*
* @note Requires v1 and v2 to be normal vectors.
*/
template<RealType T>
inline bool IsPerpendicular(const TVector2<T>& v1, const TVector2<T>& v2, T threshold = P_FLT_INAC);
/**
* Tests if 2 vectors are parallel to each other. (Angle is close to zero.)
*
* @param(v1) Vector one
* @param(v2) Vector two
* @param(t) threshold Threshold from one (e.g. 0.98f)
*
* @return true if parallel, false if not
*
* @note Requires v1 and v2 to be normal vectors.
*/
template<RealType T>
inline bool IsParallel(const TVector2<T>& v1, const TVector2<T>& v2, T threshold = 1.0f - P_FLT_INAC);
/**
* Tests if 2 vectors are coincident. (Are parallel and point in the same direction.)
*
* @param(v1) Vector one
* @param(v2) Vector two
* @param(threshold) from one (e.g. 0.98f)
*
* @return true if coincident, false if not
*
* @note Requires v1 and v2 to be normal vectors.
*/
template<RealType T>
inline bool IsCoincident(const TVector2<T>& v1, const TVector2<T>& v2, T threshold = 1.0f - P_FLT_INAC);
/**
* Gets outer product of to vectors.
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Resulting matrix
*/
//
//Matrix2 OuterProduct(const TVector2<T>& v1, const TVector2<T>& v2);
// ============================================================== //
// TVector2 static function implementation with return values //
// ============================================================== //
/**
* Reflects a vector on a normal
*
* @param(v1) Vector one
* @param(normal) Normal of surface
*
* @return Reflected vector
*/
template<RealType T>
TVector2<T> Reflect(const TVector2<T>& v1, const TVector2<T>& normal);
/**
* Scales a vector component wise
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Reflected vector
*/
template<RealType T>
TVector2<T> Scale(const TVector2<T>& v1, const TVector2<T>& v2);
/**
* Componentwise inverse of a vector
*
* @param(v1) Vector one
*
* @return Componentwise inverted vector
*/
template<RealType T>
TVector2<T> CompInverse(const TVector2<T>& v1);
/**
* Negates Vector
*
* @param(v1) Vector one
*
* @return Componentwise inverted vector
*/
template<RealType T>
TVector2<T> Negate(const TVector2<T>& v1);
/**
* Gets the perpendicular vector of v1
*
* @param(v1) Vector one
*
* @return Perpendicular vector
*/
template<RealType T>
TVector2<T> GetPerpendicular(const TVector2<T>& v1);
/**
* Gets reverse of the perpendicular vector of v1
*
* @param(v1) Vector one
*
* @return Reversed perpendicular vector
*/
template<RealType T>
TVector2<T> GetReversePerpendicular(const TVector2<T>& v1);
/**
* Creates a new Vector by the component wise minimals of both vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Minimal vector
*/
template<RealType T>
TVector2<T> Min(const TVector2<T>& v1, const TVector2<T>& v2);
/**
* Creates a new Vector by the component wise maxima of both vectors
*
* @param(v1) Vector one
* @param(v2) Vector two
*
* @return Maximal vector
*/
template<RealType T>
TVector2<T> Max(const TVector2<T>& v1, const TVector2<T>& v2);
/**
* Creates a normalized instance of the vector
*
* @param(v1) Vector to normalize
*
* @return Unit vector
*/
template<RealType T>
TVector2<T> Normalize(const TVector2<T>& v1);
/**
* Creates a normalized instance of the vector
*
* @param(v1) Vector to normalize
*
* @return Unit vector
* @note Does not test for zero vector
*/
template<RealType T>
TVector2<T> UnsafeNormalize(const TVector2<T>& v1);
/**
* Returns signs of components in vector: -1 / +1 / 0.
*
* @param(v1) Vector one
*
* @return Vector with signs as components
*/
template<RealType T>
TVector2<T> SignVector(const TVector2<T>& v1);
/**
* Binds a vector to a square with a radius
*
* @param(v1) Vector one
* @param(radius) Radius of square (=> Distance from middle to center of each site.)
*
* @return Bound vector
*/
template<RealType T>
TVector2<T> BindToSquare(const TVector2<T>& v1, T radius);
/**
* Clamps a vector to a square with a radius
*
* @param(v1) Vector one
* @param(radius) Radius of square (=> Distance from middle to center of each site.)
*
* @return Clamped vector. If the length of the vector fits the square, then the vector is returned.
*/
template<RealType T>
TVector2<T> ClampToSquare(const TVector2<T>& v1, T radius);
/**
* Interpolates between to vectors.
*
* @param(startVec) Start vector (t = 0)
* @param(destVec) Destination vector (t = 1)
* @param(t) Interpolation value
*
* @return Interpolated vector
*
* @note Interpolation is clamped between 0 - 1.
*/
template<RealType T>
TVector2<T> Lerp(const TVector2<T>& startVec, const TVector2<T>& destVec, T t);
/**
* Interpolates between to vectors.
*
* @param(startVec) Start vector (t = 0)
* @param(destVec) Destination vector (t = 1)
* @param(t) Interpolation value
*
* @return Interpolated vector
*
* @note Interpolation is not clamped. Make shure t is between 0.0f and 1.0f
*/
template<RealType T>
TVector2<T> LerpUnclamped(const TVector2<T>& startVec, const TVector2<T>& destVec, T t);
/**
* Anti-clockwise vector rotation.
*
* @param(v1) Vector to rotate
* @param(angle) Angle to rotate
*
* @return Rotated vector
*
* @note Angle is not clamped
*/
template<RealType T>
TVector2<T> Rotate(const TVector2<T>& v1, T angle);
/**
* Clockwise vector rotation.
*
* @param(v1) Vector to rotate
*
* @return Rotated vector
*
* @note Angle is not clamped
*/
template<RealType T>
TVector2<T> ClockwiseRotate(const TVector2<T>& v1, T angle);
} // phanes::core::math::coretypes
#endif // !VECTOR2_H

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,26 @@
#pragma once
// Entry point for Phanes game
#if defined(P_WIN_BUILD) && defined(P_BUILD_LIB)
#if defined(P_WIN_BUILD)
extern Phanes::Core::Application::PhanesGame* Phanes::Core::Application::CreatePhanesGame();
extern Phanes::Core::Application::PhanesProject* Phanes::Core::Application::CreatePhanesGame();
int main(int argc, char** argv)
{
Phanes::Core::Logging::Init();
PENGINE_LOG_INFO("Logger initialized!");
PENGINE_LOG_INFO("Welcome to PhanesEngine!");
auto phanes_game = Phanes::Core::Application::CreatePhanesGame();
PENGINE_LOG_INFO("Loading project {0}...", phanes_game->GetName());
phanes_game->Run();
delete phanes_game;
return 0;
}
#endif

View File

@ -1,24 +1,36 @@
#pragma once
#include "PhanesEnginePCH.h"
#include "Core/Core.h"
// Entrypoint class for any Phanes game.
namespace Phanes::Core::Application
{
class PhanesGame
class PHANES_CORE PhanesProject
{
private:
std::string projectName;
public:
PhanesGame();
virtual ~PhanesGame();
PhanesProject(std::string _ProjectName);
virtual ~PhanesProject();
/**
* PhanesEngine main loop.
*/
void Run();
/**
* Getter for project name;
*/
FORCEINLINE std::string GetName();
};
@ -26,5 +38,5 @@ namespace Phanes::Core::Application
* Function to be overwriten by client.
*/
PhanesGame* CreatePhanesGame();
PhanesProject* CreatePhanesGame();
}

View File

@ -8,7 +8,7 @@
#ifndef PHANES_CORE_PCH_H
// STL
#include <cmath>
#include <stdint.h>
@ -17,12 +17,10 @@
#include <type_traits>
#include <string>
#include<iostream>
#include <iostream>
#include <stdio.h>
#include <chrono>
#include <thread>
@ -32,6 +30,10 @@
#endif
// spdlog
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>
#endif // !PHANES_CORE_PCH_H

View File

@ -1,10 +1,13 @@
#define P_USE_NAMESPACE_ALIAS
#include <Phanes.h>
class DevPlayground : public PApp::PhanesGame {};
PApp::PhanesGame* PApp::CreatePhanesGame()
class DevPlayground : public PApp::PhanesProject
{
return new DevPlayground();
using PhanesProject::PhanesProject;
};
PApp::PhanesProject* PApp::CreatePhanesGame()
{
return new DevPlayground("DevPlayground");
}