LF line endings

Basic, Vector, VectorF16 and VectorF32 were stored with CRLF; convert them
to LF like the rest of the tree. No other change to their content.
.gitattributes keeps text files LF from here on.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-10-06 16:59:52 +02:00
commit 751a896d10
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
5 changed files with 4023 additions and 4022 deletions

1
.gitattributes vendored Normal file
View file

@ -0,0 +1 @@
* text=auto eol=lf

View file

@ -1,18 +1,18 @@
//SPDX-License-Identifier: LGPL-3.0-only //SPDX-License-Identifier: LGPL-3.0-only
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts® //SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
export module Crafter.Math:Basic; export module Crafter.Math:Basic;
import std; import std;
import :VectorF32; import :VectorF32;
namespace Crafter { namespace Crafter {
template<typename T> template<typename T>
constexpr T ToRadian(T degrees) { constexpr T ToRadian(T degrees) {
return degrees * (std::numbers::pi / 180); return degrees * (std::numbers::pi / 180);
} }
#if (defined(__x86_64) && !defined(__AVX512FP16__)) || defined(__riscv_vector) || !defined(__FLT16_MAX__) #if (defined(__x86_64) && !defined(__AVX512FP16__)) || defined(__riscv_vector) || !defined(__FLT16_MAX__)
export template <std::uint32_t Len, std::uint32_t Packing> export template <std::uint32_t Len, std::uint32_t Packing>
using VectorF16 = VectorF32<Len, Packing>; using VectorF16 = VectorF32<Len, Packing>;
#endif #endif
} }

View file

@ -1,469 +1,469 @@
//SPDX-License-Identifier: LGPL-3.0-only //SPDX-License-Identifier: LGPL-3.0-only
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts® //SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
export module Crafter.Math:Vector; export module Crafter.Math:Vector;
import std; import std;
namespace Crafter { namespace Crafter {
template <typename T, std::uint32_t Len, std::uint32_t Aligment> template <typename T, std::uint32_t Len, std::uint32_t Aligment>
struct __attribute__((packed)) VectorBase { struct __attribute__((packed)) VectorBase {
T v[Aligment]; T v[Aligment];
}; };
template <typename T, std::uint32_t Aligment> template <typename T, std::uint32_t Aligment>
struct __attribute__((packed)) VectorBase<T, 1, Aligment> { struct __attribute__((packed)) VectorBase<T, 1, Aligment> {
union { union {
T v[Aligment]; T v[Aligment];
T x, r; T x, r;
}; };
}; };
template <typename T, std::uint32_t Aligment> template <typename T, std::uint32_t Aligment>
struct __attribute__((packed)) VectorBase<T, 2, Aligment> { struct __attribute__((packed)) VectorBase<T, 2, Aligment> {
union { union {
T v[Aligment]; T v[Aligment];
struct __attribute__((packed)) { struct __attribute__((packed)) {
T x, y; T x, y;
}; };
struct __attribute__((packed)) { struct __attribute__((packed)) {
T r, g; T r, g;
}; };
}; };
constexpr VectorBase<T, 2, Aligment>(T x, T y): x(x), y(y) { constexpr VectorBase<T, 2, Aligment>(T x, T y): x(x), y(y) {
} }
constexpr VectorBase<T, 2, Aligment>() = default; constexpr VectorBase<T, 2, Aligment>() = default;
}; };
template <typename T, std::uint32_t Aligment> template <typename T, std::uint32_t Aligment>
struct __attribute__((packed)) VectorBase<T, 3, Aligment> { struct __attribute__((packed)) VectorBase<T, 3, Aligment> {
union { union {
T v[Aligment]; T v[Aligment];
struct __attribute__((packed)) { struct __attribute__((packed)) {
T x, y, z; T x, y, z;
}; };
struct __attribute__((packed)) { struct __attribute__((packed)) {
T r, g, b; T r, g, b;
}; };
}; };
constexpr VectorBase<T, 3, Aligment>(T x, T y, T z): x(x), y(y), z(z) { constexpr VectorBase<T, 3, Aligment>(T x, T y, T z): x(x), y(y), z(z) {
} }
constexpr VectorBase<T, 3, Aligment>() = default; constexpr VectorBase<T, 3, Aligment>() = default;
}; };
template <typename T, std::uint32_t Aligment> template <typename T, std::uint32_t Aligment>
struct __attribute__((packed)) VectorBase<T, 4, Aligment> { struct __attribute__((packed)) VectorBase<T, 4, Aligment> {
union { union {
T v[Aligment]; T v[Aligment];
struct __attribute__((packed)) { struct __attribute__((packed)) {
T x, y, z, w; T x, y, z, w;
}; };
struct __attribute__((packed)) { struct __attribute__((packed)) {
T r, g, b, a; T r, g, b, a;
}; };
}; };
constexpr VectorBase<T, 4, Aligment>(T x, T y, T z, T w): x(x), y(y), z(z), w(w) { constexpr VectorBase<T, 4, Aligment>(T x, T y, T z, T w): x(x), y(y), z(z), w(w) {
} }
constexpr VectorBase<T, 4, Aligment>() = default; constexpr VectorBase<T, 4, Aligment>() = default;
}; };
template <typename T, std::uint32_t Len> template <typename T, std::uint32_t Len>
struct VectorBase<T, Len, 0> { struct VectorBase<T, Len, 0> {
T v[Len]; T v[Len];
}; };
template <typename T> template <typename T>
struct VectorBase<T, 1, 0> { struct VectorBase<T, 1, 0> {
union { union {
T v[1]; T v[1];
T x, r; T x, r;
}; };
}; };
template <typename T> template <typename T>
struct VectorBase<T, 2, 0> { struct VectorBase<T, 2, 0> {
union { union {
T v[2]; T v[2];
struct { struct {
T x, y; T x, y;
}; };
struct { struct {
T r, g; T r, g;
}; };
}; };
constexpr VectorBase<T, 2, 0>(T x, T y): x(x), y(y) { constexpr VectorBase<T, 2, 0>(T x, T y): x(x), y(y) {
} }
constexpr VectorBase<T, 2, 0>() = default; constexpr VectorBase<T, 2, 0>() = default;
}; };
template <typename T> template <typename T>
struct VectorBase<T, 3, 0> { struct VectorBase<T, 3, 0> {
union { union {
T v[3]; T v[3];
struct { struct {
T x, y, z; T x, y, z;
}; };
struct { struct {
T r, g, b; T r, g, b;
}; };
}; };
constexpr VectorBase<T, 3, 0>(T x, T y, T z): x(x), y(y), z(z) { constexpr VectorBase<T, 3, 0>(T x, T y, T z): x(x), y(y), z(z) {
} }
constexpr VectorBase<T, 3, 0>() = default; constexpr VectorBase<T, 3, 0>() = default;
}; };
template <typename T> template <typename T>
struct VectorBase<T, 4, 0> { struct VectorBase<T, 4, 0> {
union { union {
T v[4]; T v[4];
struct { struct {
T x, y, z, w; T x, y, z, w;
}; };
struct { struct {
T r, g, b, a; T r, g, b, a;
}; };
}; };
constexpr VectorBase<T, 4, 0>(T x, T y, T z, T w): x(x), y(y), z(z), w(w) { constexpr VectorBase<T, 4, 0>(T x, T y, T z, T w): x(x), y(y), z(z), w(w) {
} }
constexpr VectorBase<T, 4, 0>() = default; constexpr VectorBase<T, 4, 0>() = default;
}; };
export template <typename T, std::uint32_t Len, std::uint32_t Aligment = 0> export template <typename T, std::uint32_t Len, std::uint32_t Aligment = 0>
class Vector : public VectorBase<T, Len, Aligment> { class Vector : public VectorBase<T, Len, Aligment> {
public: public:
constexpr Vector(T x, T y, T z, T w ) requires(std::same_as<T, T> && Len == 4) : VectorBase<T, Len, Aligment>(x, y, z, w) { constexpr Vector(T x, T y, T z, T w ) requires(std::same_as<T, T> && Len == 4) : VectorBase<T, Len, Aligment>(x, y, z, w) {
} }
constexpr Vector(T x, T y, T z) requires(std::same_as<T, T> && Len == 3) : VectorBase<T, Len, Aligment>(x, y, z) { constexpr Vector(T x, T y, T z) requires(std::same_as<T, T> && Len == 3) : VectorBase<T, Len, Aligment>(x, y, z) {
} }
constexpr Vector(T x, T y) requires(std::same_as<T, T> && Len == 2) : VectorBase<T, Len, Aligment>(x, y) { constexpr Vector(T x, T y) requires(std::same_as<T, T> && Len == 2) : VectorBase<T, Len, Aligment>(x, y) {
} }
constexpr Vector() = default; constexpr Vector() = default;
template <std::uint32_t BAlignment> template <std::uint32_t BAlignment>
constexpr operator Vector<T, Len, BAlignment>() const { constexpr operator Vector<T, Len, BAlignment>() const {
Vector<T, Len, BAlignment> returnVector; Vector<T, Len, BAlignment> returnVector;
for(std::uint32_t i = 0; i < Len; i++) { for(std::uint32_t i = 0; i < Len; i++) {
returnVector.v[i] = this->v[i]; returnVector.v[i] = this->v[i];
} }
return returnVector; return returnVector;
} }
template <std::uint32_t Blen, std::uint32_t BAlignment> template <std::uint32_t Blen, std::uint32_t BAlignment>
constexpr Vector<T, Len, Aligment> operator+(Vector<T, Blen, BAlignment> b) const { constexpr Vector<T, Len, Aligment> operator+(Vector<T, Blen, BAlignment> b) const {
Vector<T, Len, Aligment> resultVector; Vector<T, Len, Aligment> resultVector;
for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) { for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) {
resultVector.v[i] = this->v[i]+b.v[i]; resultVector.v[i] = this->v[i]+b.v[i];
} }
return resultVector; return resultVector;
} }
template <std::uint32_t Blen, std::uint32_t BAlignment> template <std::uint32_t Blen, std::uint32_t BAlignment>
constexpr Vector<T, Len, Aligment> operator-(Vector<T, Blen, BAlignment> b) const { constexpr Vector<T, Len, Aligment> operator-(Vector<T, Blen, BAlignment> b) const {
Vector<T, Len, Aligment> resultVector; Vector<T, Len, Aligment> resultVector;
for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) { for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) {
resultVector.v[i] = this->v[i]-b.v[i]; resultVector.v[i] = this->v[i]-b.v[i];
} }
return resultVector; return resultVector;
} }
constexpr Vector<T, Len, Aligment> operator-(){ constexpr Vector<T, Len, Aligment> operator-(){
Vector<T, Len, Aligment> resultVector; Vector<T, Len, Aligment> resultVector;
for(std::uint32_t i = 0; i < Len; i++) { for(std::uint32_t i = 0; i < Len; i++) {
resultVector.v[i] = -this->v[i]; resultVector.v[i] = -this->v[i];
} }
return resultVector; return resultVector;
} }
template <std::uint32_t Blen, std::uint32_t BAlignment> template <std::uint32_t Blen, std::uint32_t BAlignment>
constexpr Vector<T, Len, Aligment> operator*(Vector<T, Blen, BAlignment> b) const { constexpr Vector<T, Len, Aligment> operator*(Vector<T, Blen, BAlignment> b) const {
Vector<T, Len, Aligment> resultVector; Vector<T, Len, Aligment> resultVector;
for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) { for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) {
resultVector.v[i] = this->v[i]*b.v[i]; resultVector.v[i] = this->v[i]*b.v[i];
} }
return resultVector; return resultVector;
} }
template <std::uint32_t Blen, std::uint32_t BAlignment> template <std::uint32_t Blen, std::uint32_t BAlignment>
constexpr Vector<T, Len, Aligment> operator/(Vector<T, Blen, BAlignment> b) const { constexpr Vector<T, Len, Aligment> operator/(Vector<T, Blen, BAlignment> b) const {
Vector<T, Len, Aligment> resultVector; Vector<T, Len, Aligment> resultVector;
for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) { for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) {
resultVector.v[i] = this->v[i]/b.v[i]; resultVector.v[i] = this->v[i]/b.v[i];
} }
return resultVector; return resultVector;
} }
template <std::uint32_t Blen, std::uint32_t BAlignment> template <std::uint32_t Blen, std::uint32_t BAlignment>
constexpr void operator+=(Vector<T, Blen, BAlignment> b){ constexpr void operator+=(Vector<T, Blen, BAlignment> b){
for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) { for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) {
this->v[i]+=b.v[i]; this->v[i]+=b.v[i];
} }
} }
template <std::uint32_t Blen, std::uint32_t BAlignment> template <std::uint32_t Blen, std::uint32_t BAlignment>
constexpr void operator-=(Vector<T, Blen, BAlignment> b){ constexpr void operator-=(Vector<T, Blen, BAlignment> b){
for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) { for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) {
this->v[i]-=b.v[i]; this->v[i]-=b.v[i];
} }
} }
template <std::uint32_t Blen, std::uint32_t BAlignment> template <std::uint32_t Blen, std::uint32_t BAlignment>
constexpr void operator*=(Vector<T, Blen, BAlignment> b){ constexpr void operator*=(Vector<T, Blen, BAlignment> b){
for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) { for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) {
this->v[i]*=b.v[i]; this->v[i]*=b.v[i];
} }
} }
template <std::uint32_t Blen, std::uint32_t BAlignment> template <std::uint32_t Blen, std::uint32_t BAlignment>
constexpr void operator/=(Vector<T, Blen, BAlignment> b){ constexpr void operator/=(Vector<T, Blen, BAlignment> b){
for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) { for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) {
this->v[i]/=b.v[i]; this->v[i]/=b.v[i];
} }
} }
template <typename BT> template <typename BT>
constexpr Vector<T, Len, Aligment> operator+(BT b) const requires std::is_arithmetic_v<BT> { constexpr Vector<T, Len, Aligment> operator+(BT b) const requires std::is_arithmetic_v<BT> {
Vector<T, Len, Aligment> resultVector; Vector<T, Len, Aligment> resultVector;
for(std::uint32_t i = 0; i < Len; i++) { for(std::uint32_t i = 0; i < Len; i++) {
resultVector.v[i] = this->v[i] + b; resultVector.v[i] = this->v[i] + b;
} }
return resultVector; return resultVector;
} }
template <typename BT> template <typename BT>
constexpr Vector<T, Len, Aligment> operator-(BT b) const requires std::is_arithmetic_v<BT> { constexpr Vector<T, Len, Aligment> operator-(BT b) const requires std::is_arithmetic_v<BT> {
Vector<T, Len, Aligment> resultVector; Vector<T, Len, Aligment> resultVector;
for(std::uint32_t i = 0; i < Len; i++) { for(std::uint32_t i = 0; i < Len; i++) {
resultVector.v[i] = this->v[i] - b; resultVector.v[i] = this->v[i] - b;
} }
return resultVector; return resultVector;
} }
template <typename BT> template <typename BT>
constexpr Vector<T, Len, Aligment> operator*(BT b) const requires std::is_arithmetic_v<BT> { constexpr Vector<T, Len, Aligment> operator*(BT b) const requires std::is_arithmetic_v<BT> {
Vector<T, Len, Aligment> resultVector; Vector<T, Len, Aligment> resultVector;
for(std::uint32_t i = 0; i < Len; i++) { for(std::uint32_t i = 0; i < Len; i++) {
resultVector.v[i] = this->v[i] * b; resultVector.v[i] = this->v[i] * b;
} }
return resultVector; return resultVector;
} }
template <typename BT> template <typename BT>
constexpr Vector<T, Len, Aligment> operator/(BT b) const requires std::is_arithmetic_v<BT> { constexpr Vector<T, Len, Aligment> operator/(BT b) const requires std::is_arithmetic_v<BT> {
Vector<T, Len, Aligment> resultVector; Vector<T, Len, Aligment> resultVector;
for(std::uint32_t i = 0; i < Len; i++) { for(std::uint32_t i = 0; i < Len; i++) {
resultVector.v[i] = this->v[i] / b; resultVector.v[i] = this->v[i] / b;
} }
return resultVector; return resultVector;
} }
template <typename BT> template <typename BT>
constexpr void operator+=(BT b) requires std::is_arithmetic_v<BT>{ constexpr void operator+=(BT b) requires std::is_arithmetic_v<BT>{
for(std::uint32_t i = 0; i < Len; i++) { for(std::uint32_t i = 0; i < Len; i++) {
this->v[i] += b; this->v[i] += b;
} }
} }
template <typename BT> template <typename BT>
constexpr void operator-=(BT b) requires std::is_arithmetic_v<BT>{ constexpr void operator-=(BT b) requires std::is_arithmetic_v<BT>{
for(std::uint32_t i = 0; i < Len; i++) { for(std::uint32_t i = 0; i < Len; i++) {
this->v[i] -= b; this->v[i] -= b;
} }
} }
template <typename BT> template <typename BT>
constexpr void operator*=(BT b) requires std::is_arithmetic_v<BT>{ constexpr void operator*=(BT b) requires std::is_arithmetic_v<BT>{
for(std::uint32_t i = 0; i < Len; i++) { for(std::uint32_t i = 0; i < Len; i++) {
this->v[i] *= b; this->v[i] *= b;
} }
} }
template <typename BT> template <typename BT>
constexpr void operator/=(BT b) requires std::is_arithmetic_v<BT>{ constexpr void operator/=(BT b) requires std::is_arithmetic_v<BT>{
for(std::uint32_t i = 0; i < Len; i++) { for(std::uint32_t i = 0; i < Len; i++) {
this->v[i] /= b; this->v[i] /= b;
} }
} }
template <typename BT, std::uint32_t Blen, std::uint32_t BAlignment> template <typename BT, std::uint32_t Blen, std::uint32_t BAlignment>
constexpr bool operator==(Vector<BT, Blen, BAlignment> b) const { constexpr bool operator==(Vector<BT, Blen, BAlignment> b) const {
for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) { for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) {
if(this->v[i] != b.v[i]) { if(this->v[i] != b.v[i]) {
return false; return false;
} }
} }
return true; return true;
} }
template <typename BT, std::uint32_t Blen, std::uint32_t BAlignment> template <typename BT, std::uint32_t Blen, std::uint32_t BAlignment>
constexpr bool operator!=(Vector<BT, Blen, BAlignment> b) const { constexpr bool operator!=(Vector<BT, Blen, BAlignment> b) const {
for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) { for(std::uint32_t i = 0; i < std::min(Len, Blen); i++) {
if(this->v[i] != b.v[i]) { if(this->v[i] != b.v[i]) {
return true; return true;
} }
} }
return false; return false;
} }
constexpr void Normalize() { constexpr void Normalize() {
T fLength = Length(); T fLength = Length();
fLength = 1.0f / fLength; fLength = 1.0f / fLength;
for(std::uint32_t i = 0; i < Len; i++) { for(std::uint32_t i = 0; i < Len; i++) {
this->v[i] *= fLength; this->v[i] *= fLength;
} }
} }
constexpr void Invert() { constexpr void Invert() {
for(std::uint32_t i = 0; i < Len; i++) { for(std::uint32_t i = 0; i < Len; i++) {
this->v[i] = -this->v[i]; this->v[i] = -this->v[i];
} }
} }
constexpr T Length() const { constexpr T Length() const {
T Result = LengthSq(); T Result = LengthSq();
return std::sqrtf(Result); return std::sqrtf(Result);
} }
constexpr T LengthSq() const { constexpr T LengthSq() const {
return Dot(*this, *this); return Dot(*this, *this);
} }
template <typename AT, std::uint32_t Alen, std::uint32_t AAlignment, typename BT, std::uint32_t Blen, std::uint32_t BAlignment> template <typename AT, std::uint32_t Alen, std::uint32_t AAlignment, typename BT, std::uint32_t Blen, std::uint32_t BAlignment>
constexpr static Vector<T, Len, Aligment> Cross(Vector<AT, Alen, AAlignment> a, Vector<BT, Blen, BAlignment> b) requires(Len == 3 && Alen >= 3 && Blen >= 3) { constexpr static Vector<T, Len, Aligment> Cross(Vector<AT, Alen, AAlignment> a, Vector<BT, Blen, BAlignment> b) requires(Len == 3 && Alen >= 3 && Blen >= 3) {
return Vector<T, Len, Aligment>( return Vector<T, Len, Aligment>(
(a.v[1] * b.v[2]) - (a.v[2] * b.v[1]), (a.v[1] * b.v[2]) - (a.v[2] * b.v[1]),
(a.v[2] * b.v[0]) - (a.v[0] * b.v[2]), (a.v[2] * b.v[0]) - (a.v[0] * b.v[2]),
(a.v[0] * b.v[1]) - (a.v[1] * b.v[0]) (a.v[0] * b.v[1]) - (a.v[1] * b.v[0])
); );
} }
template <typename AT, std::uint32_t Alen, std::uint32_t AAlignment> template <typename AT, std::uint32_t Alen, std::uint32_t AAlignment>
constexpr static Vector<T, Len, Aligment> Normalize(Vector<AT, Alen, AAlignment> a) requires(Len == Alen) { constexpr static Vector<T, Len, Aligment> Normalize(Vector<AT, Alen, AAlignment> a) requires(Len == Alen) {
Vector<T, 3, 0> returned; Vector<T, 3, 0> returned;
T fLength = a.Length(); T fLength = a.Length();
if (fLength > 0) { if (fLength > 0) {
fLength = 1.0f / fLength; fLength = 1.0f / fLength;
} }
for(std::uint32_t i = 0; i < Len; i++) { for(std::uint32_t i = 0; i < Len; i++) {
returned.v[i] = a.v[i] * fLength; returned.v[i] = a.v[i] * fLength;
} }
return returned; return returned;
} }
template <typename AT, std::uint32_t Alen, std::uint32_t AAlignment, typename BT, std::uint32_t Blen, std::uint32_t BAlignment> template <typename AT, std::uint32_t Alen, std::uint32_t AAlignment, typename BT, std::uint32_t Blen, std::uint32_t BAlignment>
constexpr static T Dot(Vector<AT, Alen, AAlignment> a, Vector<BT, Blen, BAlignment> b) requires(Alen >= Len && Blen >= Len) { constexpr static T Dot(Vector<AT, Alen, AAlignment> a, Vector<BT, Blen, BAlignment> b) requires(Alen >= Len && Blen >= Len) {
T accumulate = a.v[0] * b.v[0]; T accumulate = a.v[0] * b.v[0];
for(std::uint32_t i = 1; i < Len; i++) { for(std::uint32_t i = 1; i < Len; i++) {
accumulate += a.v[i] * b.v[i]; accumulate += a.v[i] * b.v[i];
} }
return accumulate; return accumulate;
} }
template <typename AT, std::uint32_t AAlignment, typename BT, std::uint32_t BAlignment> template <typename AT, std::uint32_t AAlignment, typename BT, std::uint32_t BAlignment>
constexpr static Vector<T, 3, Aligment> Rotate(Vector<AT, 3, AAlignment> v, Vector<BT, 4, BAlignment> q) requires(Len == 3) { constexpr static Vector<T, 3, Aligment> Rotate(Vector<AT, 3, AAlignment> v, Vector<BT, 4, BAlignment> q) requires(Len == 3) {
Vector<T, 3, 0> qv(q.x, q.y, q.z); Vector<T, 3, 0> qv(q.x, q.y, q.z);
Vector<T, 3, 0> t = Vector<T, 3, Aligment>::Cross(qv, v) * T(2); Vector<T, 3, 0> t = Vector<T, 3, Aligment>::Cross(qv, v) * T(2);
return v + t * q.w + Vector<T, 3, Aligment>::Cross(qv, t); return v + t * q.w + Vector<T, 3, Aligment>::Cross(qv, t);
} }
template <typename AT, std::uint32_t AAlignment, typename BT, std::uint32_t BAlignment, typename PT, std::uint32_t PAlignment> template <typename AT, std::uint32_t AAlignment, typename BT, std::uint32_t BAlignment, typename PT, std::uint32_t PAlignment>
constexpr static Vector<T, 3, Aligment> RotatePivot(Vector<AT, 3, AAlignment> v, Vector<BT, 4, BAlignment> q, Vector<PT, 3, PAlignment> pivot) requires(Len == 3) { constexpr static Vector<T, 3, Aligment> RotatePivot(Vector<AT, 3, AAlignment> v, Vector<BT, 4, BAlignment> q, Vector<PT, 3, PAlignment> pivot) requires(Len == 3) {
Vector<T, 3, 0> translated = v - pivot; Vector<T, 3, 0> translated = v - pivot;
Vector<T, 3, 0> qv(q.x, q.y, q.z); Vector<T, 3, 0> qv(q.x, q.y, q.z);
Vector<T, 3, 0> t = Cross(qv, translated) * T(2); Vector<T, 3, 0> t = Cross(qv, translated) * T(2);
Vector<T, 3, 0> rotated = translated + t * q.w +Cross(qv, t); Vector<T, 3, 0> rotated = translated + t * q.w +Cross(qv, t);
return rotated + pivot; return rotated + pivot;
} }
template <typename AT, std::uint32_t AAlignment, typename BT, std::uint32_t BAlignment, typename CT, std::uint32_t CAlignment> template <typename AT, std::uint32_t AAlignment, typename BT, std::uint32_t BAlignment, typename CT, std::uint32_t CAlignment>
constexpr static Vector<T, 4, Aligment> QuanternionFromBasis(Vector<AT, 3, AAlignment> right, Vector<BT, 3, BAlignment> up, Vector<CT, 3, CAlignment> forward) requires(Len == 4) { constexpr static Vector<T, 4, Aligment> QuanternionFromBasis(Vector<AT, 3, AAlignment> right, Vector<BT, 3, BAlignment> up, Vector<CT, 3, CAlignment> forward) requires(Len == 4) {
T m00 = right.x; T m00 = right.x;
T m01 = up.x; T m01 = up.x;
T m02 = forward.x; T m02 = forward.x;
T m10 = right.y; T m10 = right.y;
T m11 = up.y; T m11 = up.y;
T m12 = forward.y; T m12 = forward.y;
T m20 = right.z; T m20 = right.z;
T m21 = up.z; T m21 = up.z;
T m22 = forward.z; T m22 = forward.z;
T trace = m00 + m11 + m22; T trace = m00 + m11 + m22;
Vector<T, 4, Aligment> q; Vector<T, 4, Aligment> q;
if (trace > std::numeric_limits<T>::epsilon()) { if (trace > std::numeric_limits<T>::epsilon()) {
T s = std::sqrt(trace + T(1)) * T(2); T s = std::sqrt(trace + T(1)) * T(2);
q.w = T(0.25) * s; q.w = T(0.25) * s;
q.x = (m21 - m12) / s; q.x = (m21 - m12) / s;
q.y = (m02 - m20) / s; q.y = (m02 - m20) / s;
q.z = (m10 - m01) / s; q.z = (m10 - m01) / s;
} }
else if ((m00 > m11) && (m00 > m22)) { else if ((m00 > m11) && (m00 > m22)) {
T s = std::sqrt(T(1) + m00 - m11 - m22) * T(2); T s = std::sqrt(T(1) + m00 - m11 - m22) * T(2);
q.w = (m21 - m12) / s; q.w = (m21 - m12) / s;
q.x = T(0.25) * s; q.x = T(0.25) * s;
q.y = (m01 + m10) / s; q.y = (m01 + m10) / s;
q.z = (m02 + m20) / s; q.z = (m02 + m20) / s;
} }
else if (m11 > m22) { else if (m11 > m22) {
T s = std::sqrt(T(1) + m11 - m00 - m22) * T(2); T s = std::sqrt(T(1) + m11 - m00 - m22) * T(2);
q.w = (m02 - m20) / s; q.w = (m02 - m20) / s;
q.x = (m01 + m10) / s; q.x = (m01 + m10) / s;
q.y = T(0.25) * s; q.y = T(0.25) * s;
q.z = (m12 + m21) / s; q.z = (m12 + m21) / s;
} }
else { else {
T s = std::sqrt(T(1) + m22 - m00 - m11) * T(2); T s = std::sqrt(T(1) + m22 - m00 - m11) * T(2);
q.w = (m10 - m01) / s; q.w = (m10 - m01) / s;
q.x = (m02 + m20) / s; q.x = (m02 + m20) / s;
q.y = (m12 + m21) / s; q.y = (m12 + m21) / s;
q.z = T(0.25) * s; q.z = T(0.25) * s;
} }
q.Normalize(); q.Normalize();
return q; return q;
} }
constexpr static Vector<T, 4, Aligment> QuanternionFromEuler(T rollHalf, T pitchHalf, T yawHalf) { constexpr static Vector<T, 4, Aligment> QuanternionFromEuler(T rollHalf, T pitchHalf, T yawHalf) {
T cr = std::cos(rollHalf); T cr = std::cos(rollHalf);
T sr = std::sin(rollHalf); T sr = std::sin(rollHalf);
T cp = std::cos(pitchHalf); T cp = std::cos(pitchHalf);
T sp = std::sin(pitchHalf); T sp = std::sin(pitchHalf);
T cy = std::cos(yawHalf); T cy = std::cos(yawHalf);
T sy = std::sin(yawHalf); T sy = std::sin(yawHalf);
return Vector<T, 4, Aligment>( return Vector<T, 4, Aligment>(
sr * cp * cy - cr * sp * sy, sr * cp * cy - cr * sp * sy,
cr * sp * cy + sr * cp * sy, cr * sp * cy + sr * cp * sy,
cr * cp * sy - sr * sp * cy, cr * cp * sy - sr * sp * cy,
cr * cp * cy + sr * sp * sy cr * cp * cy + sr * sp * sy
); );
} }
}; };
} }
template <typename T, std::uint32_t Len, std::uint32_t Aligment> template <typename T, std::uint32_t Len, std::uint32_t Aligment>
struct std::formatter<Crafter::Vector<T, Len, Aligment>> : std::formatter<std::string> { struct std::formatter<Crafter::Vector<T, Len, Aligment>> : std::formatter<std::string> {
auto format(const Crafter::Vector<T, Len, Aligment>& vec, format_context& ctx) const { auto format(const Crafter::Vector<T, Len, Aligment>& vec, format_context& ctx) const {
std::string out = "{"; std::string out = "{";
for(std::uint32_t i2 = 0; i2 < Len; i2++) { for(std::uint32_t i2 = 0; i2 < Len; i2++) {
#ifdef __x86_64 #ifdef __x86_64
if constexpr(std::same_as<T, _Float16>) { if constexpr(std::same_as<T, _Float16>) {
out += std::format("{}", static_cast<float>(vec.v[i2])); out += std::format("{}", static_cast<float>(vec.v[i2]));
} else } else
#endif #endif
{ {
out += std::format("{}", vec.v[i2]); out += std::format("{}", vec.v[i2]);
} }
if (i2 + 1 < Len) out += ","; if (i2 + 1 < Len) out += ",";
} }
out += "}"; out += "}";
return std::formatter<std::string>::format(out, ctx); return std::formatter<std::string>::format(out, ctx);
} }
}; };
template <typename T, std::uint32_t Len, std::uint32_t Aligment, typename BT> template <typename T, std::uint32_t Len, std::uint32_t Aligment, typename BT>
constexpr Crafter::Vector<T, Len, Aligment> operator*(BT b, const Crafter::Vector<T, Len, Aligment>& v) requires std::is_arithmetic_v<BT> { constexpr Crafter::Vector<T, Len, Aligment> operator*(BT b, const Crafter::Vector<T, Len, Aligment>& v) requires std::is_arithmetic_v<BT> {
return v * b; return v * b;
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff