updated project

This commit is contained in:
Jorijn van der Graaf 2025-05-07 19:18:58 +02:00
commit 0c215df939
14 changed files with 461 additions and 20 deletions

View file

@ -1,3 +1,23 @@
/*
Crafter.Math
Copyright (C) 2025 Catcrafts
Catcrafts.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
module;
#include <type_traits>
@ -6,10 +26,12 @@ module;
#include <string>
#include <sstream>
#include <iostream>
#include <cmath>
export module Crafter.Math:Vector;
import :BasicTypes;
import :Misc;
namespace Crafter {
template <typename T, uint32_t Len>
@ -33,6 +55,10 @@ namespace Crafter {
T x, y;
};
};
VectorBase<T, 2>(float x, float y): x(x), y(y) {
}
VectorBase<T, 2>() = default;
};
template <typename T>
@ -43,9 +69,10 @@ namespace Crafter {
T x, y, z;
};
};
VectorBase<T, 3>(float x = 0, float y = 0, float z = 0): x(x), y(y), z(z) {
VectorBase<T, 3>(float x, float y, float z): x(x), y(y), z(z) {
}
VectorBase<T, 3>() = default;
};
template <typename T>
@ -56,14 +83,198 @@ namespace Crafter {
T x, y, z, w;
};
};
VectorBase<T, 4>(float x, float y, float z, float w): x(x), y(y), z(z), w(w) {
}
VectorBase<T, 4>() = default;
};
export template <typename T, uint32_t Len>
class Vector : public VectorBase<T, Len> {
public:
Vector(float x = 0, float y = 0, float z = 0) requires(std::same_as<T, float> && Len == 3) : VectorBase<T, Len>(x, y, z) {
Vector(float x, float y, float z, float w ) requires(std::same_as<T, float> && Len == 4) : VectorBase<T, Len>(x, y, z, w) {
}
Vector(float x, float y, float z) requires(std::same_as<T, float> && Len == 3) : VectorBase<T, Len>(x, y, z) {
}
Vector(float x, float y) requires(std::same_as<T, float> && Len == 2) : VectorBase<T, Len>(x, y) {
}
Vector() = default;
static Vector<T, Len> QuaternionRotationRollPitchYaw(float Pitch, float Yaw, float Roll) requires(Len == 4) {
const float halfpitch = Pitch * 0.5f;
float cp = cosf(halfpitch);
float sp = sinf(halfpitch);
const float halfyaw = Yaw * 0.5f;
float cy = cosf(halfyaw);
float sy = sinf(halfyaw);
const float halfroll = Roll * 0.5f;
float cr = cosf(halfroll);
float sr = sinf(halfroll);
return Vector<T, Len>(
cr * sp * cy + sr * cp * sy,
cr * cp * sy - sr * sp * cy,
sr * cp * cy - cr * sp * sy,
cr * cp * cy + sr * sp * sy
);
}
template <uint32_t Blen>
Vector<T, Len> operator+(Vector<T, Blen> b){
Vector<T, Len> resultVector;
for(uint32_t i = 0; i < std::min(Len, Blen); i++) {
resultVector.v[i] = this->v[i]+b.v[i];
}
return resultVector;
}
template <uint32_t Blen>
Vector<T, Len> operator-(Vector<T, Blen> b){
Vector<T, Len> resultVector;
for(uint32_t i = 0; i < std::min(Len, Blen); i++) {
resultVector.v[i] = this->v[i]-b.v[i];
}
return resultVector;
}
Vector<T, Len> operator-(){
Vector<T, Len> resultVector;
for(uint32_t i = 0; i < Len; i++) {
resultVector.v[i] = -this->v[i];
}
return resultVector;
}
template <uint32_t Blen>
Vector<T, Len> operator*(Vector<T, Blen> b){
Vector<T, Len> resultVector;
for(uint32_t i = 0; i < std::min(Len, Blen); i++) {
resultVector.v[i] = this->v[i]*b.v[i];
}
return resultVector;
}
template <uint32_t Blen>
Vector<T, Len> operator/(Vector<T, Blen> b){
Vector<T, Len> resultVector;
for(uint32_t i = 0; i < std::min(Len, Blen); i++) {
resultVector.v[i] = this->v[i]/b.v[i];
}
return resultVector;
}
Vector<T, Len> Rotate(Vector<T, 4> rotation) requires(Len == 3) {
Vector<T, 4> q = rotation.QuaternionConjugate();
Vector<T, 4> result = q.QuaternionMultiply(Vector<T, 4>(this->x, this->y, this->z, 0));
return Vector<T, Len>(result.x, result.y, result.z);
}
Vector<T, Len> Normalize() requires(Len == 3) {
float fLength = Length();
// Prevent divide by zero
if (fLength > 0)
{
fLength = 1.0f / fLength;
}
return Vector<T, Len>(this->v[0] * fLength, this->v[1] * fLength, this->v[2] * fLength);
}
Vector<T, Len> Normalize() requires(Len == 4) {
float fLength = Length();
// Prevent divide by zero
if (fLength > 0)
{
fLength = 1.0f / fLength;
}
return Vector<T, Len>(this->v[0] * fLength, this->v[1] * fLength, this->v[2] * fLength, this->v[3] * fLength);
}
float Length()
{
float Result = LengthSq();
return sqrtf(Result);
}
Vector<T, Len> ReciprocalLength() requires(Len == 3) {
Vector<T, Len> Result = LengthSq();
Result = ReciprocalSqrt(Result);
return Result;
}
Vector<T, Len> ReciprocalSqrt() requires(Len == 3)
{
return Vector<T, Len>(
1.f / sqrtf(this->v[0]),
1.f / sqrtf(this->v[1]),
1.f / sqrtf(this->v[2])
);
}
float LengthSq()
{
return Dot(*this);
}
float Dot(Vector<T, Len> v2) requires(Len == 3)
{
return this->v[0] * v2.v[0] + this->v[1] * v2.v[1] + this->v[2] * v2.v[2];
}
float Dot(Vector<T, Len> v2) requires(Len == 4)
{
return this->v[0] * v2.v[0] + this->v[1] * v2.v[1] + this->v[2] * v2.v[2] + this->v[3] * v2.v[3];
}
Vector<T, Len> Cross(Vector<T, Len> v2) requires(Len == 3) {
return Vector<T, Len>(
(this->v[1] * v2.v[2]) - (this->v[2] * v2.v[1]),
(this->v[2] * v2.v[0]) - (this->v[0] * v2.v[2]),
(this->v[0] * v2.v[1]) - (this->v[1] * v2.v[0])
);
};
Vector<T, Len> QuaternionConjugate() requires(Len == 4) {
return Vector<T, Len>(
-this->x,
-this->y,
-this->z,
this->w
);
}
Vector<T, Len> QuaternionMultiply(Vector<T, Len> q2) requires(Len == 4) {
return Vector<T, Len>(
(q2.v[3] * this->v[0]) + (q2.v[0] * this->v[3]) + (q2.v[1] * this->v[2]) - (q2.v[2] * this->v[1]),
(q2.v[3] * this->v[1]) - (q2.v[0] * this->v[2]) + (q2.v[1] * this->v[3]) + (q2.v[2] * this->v[0]),
(q2.v[3] * this->v[2]) + (q2.v[0] * this->v[1]) - (q2.v[1] * this->v[0]) + (q2.v[2] * this->v[3]),
(q2.v[3] * this->v[3]) - (q2.v[0] * this->v[0]) - (q2.v[1] * this->v[1]) - (q2.v[2] * this->v[2])
);
}
Vector<T, 4> QuaternionRotationAxis(float angle) requires(Len == 3) {
Vector<T, 3> Normal = Normalize();
return Normal.QuaternionRotationNormal(angle);
}
Vector<T, 4> QuaternionRotationNormal(float angle) requires(Len == 3) {
Vector<T, 4> N = Vector<T, 4>(this->x, this->y, this->z, 1);
float SinV, CosV;
XMScalarSinCos(&SinV, &CosV, 0.5f * angle);
Vector<T, 4> Scale = Vector<T, 4>(SinV, SinV, SinV, CosV);
return N * Scale;
}
// typedef
// typename std::conditional<(sizeof(T)* len > 32 && (std::same_as<T, int64_t> || std::same_as<T, int32_t> || std::same_as<T, int16_t> || std::same_as<T, int8_t> || std::same_as<T, uint64_t> || std::same_as<T, uint32_t> || std::same_as<T, uint16_t> || std::same_as<T, uint8_t>)), __m512i,