Compare commits

...

18 Commits

Author SHA1 Message Date
655ca9e036 Add CTransform::quickInverse, toCStyleMatrix 2025-04-14 09:13:57 -06:00
3f0f1bf338 Fix CColor::toRGBA 2025-04-14 09:13:36 -06:00
d63744eb07 Add CVector2i header 2023-12-15 14:29:01 -08:00
316d937f11 Minor compile fixes and corrections 2023-10-22 17:18:03 -07:00
e9ec10a382 Add simd_none implementation 2022-08-03 18:15:45 -04:00
ac7d83009d CMatrix4f: Explicit operator==/!= 2022-06-03 01:52:41 -04:00
6547f76752 Remove error-causing constexprs 2022-05-31 20:17:23 -04:00
8410394d4b Add toRGBA and toRGB5A3 to CColor 2022-05-13 23:46:19 -07:00
8e4dfb022a CMatrix3f: Remove normalize from CQuaternion ctor 2022-05-12 12:05:29 -04:00
f3e649716a Revert change to CAABox closestPointAlongVector / furthestPointAlongVector 2022-03-20 16:22:06 -04:00
11606d3676 Fix constexpr in CQuaternion 2022-03-12 09:49:30 -08:00
fc33e18b4a constexpr fixes 2022-03-12 09:03:27 -08:00
82a3a0def9 Fix floorPowerOfTwo 2022-03-02 23:50:07 -08:00
e9c0fe7a6e Remove athena types 2022-02-27 20:46:10 -08:00
e53b380f42 Add CVector2d/4d 2022-02-20 18:41:54 -08:00
ec125acf29 CColor: Fix COLOR macro (again) 2021-10-25 22:54:47 -04:00
6e865b656a MSVC build fix for COLOR macro 2021-10-25 19:17:25 -04:00
f3630be9de Add CVector3f->CEulerAngles constructor to CEulerAngles 2021-07-11 17:56:32 -07:00
26 changed files with 722 additions and 255 deletions

View File

@@ -37,9 +37,11 @@ add_library(zeus
include/zeus/zeus.hpp
include/zeus/CVector2i.hpp
include/zeus/CVector2f.hpp
include/zeus/CVector2d.hpp
include/zeus/CVector3f.hpp
include/zeus/CVector3d.hpp
include/zeus/CVector4f.hpp
include/zeus/CVector4d.hpp
include/zeus/CRectangle.hpp
include/zeus/CMatrix4f.hpp
include/zeus/CFrustum.hpp
@@ -58,10 +60,5 @@ add_library(zeus
include/zeus/simd/parallelism_v2_simd.hpp)
target_include_directories(zeus PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
if(TARGET athena-core)
target_link_libraries(zeus PUBLIC athena-core)
target_compile_definitions(zeus PUBLIC ZE_ATHENA_TYPES=1)
endif()
add_subdirectory(test)

View File

@@ -9,10 +9,6 @@
#include "zeus/CVector3f.hpp"
#include "zeus/Math.hpp"
#if ZE_ATHENA_TYPES
#include <athena/IStreamReader.hpp>
#endif
namespace zeus {
class CAABox {
public:
@@ -40,21 +36,6 @@ public:
constexpr CAABox(float minX, float minY, float minZ, float maxX, float maxY, float maxZ)
: min(minX, minY, minZ), max(maxX, maxY, maxZ) {}
#if ZE_ATHENA_TYPES
void readBoundingBoxBig(athena::io::IStreamReader& in) {
min.readBig(in);
max.readBig(in);
}
[[nodiscard]] static CAABox ReadBoundingBoxBig(athena::io::IStreamReader& in) {
CAABox ret;
ret.readBoundingBoxBig(in);
return ret;
}
#endif
[[nodiscard]] bool intersects(const CAABox& other) const {
const auto mmax = max >= other.min;
const auto mmin = min <= other.max;

View File

@@ -8,20 +8,15 @@
#include "zeus/Global.hpp"
#include "zeus/Math.hpp"
#if ZE_ATHENA_TYPES
#include <athena/FileReader.hpp>
#include <athena/FileWriter.hpp>
#endif
#undef min
#undef max
#if BYTE_ORDER == __ORDER_LITTLE_ENDIAN__
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define COLOR(rgba) \
(unsigned)(((rgba)&0x000000FF) << 24 | ((rgba)&0x0000FF00) << 8 | ((rgba)&0x00FF0000) >> 8 | \
((rgba)&0xFF000000) >> 24)
(zeus::Comp32)(((rgba)&0x000000FF) << 24 | ((rgba)&0x0000FF00) << 8 | ((rgba)&0x00FF0000) >> 8 | \
((rgba)&0xFF000000) >> 24)
#else
#define COLOR(rgba) rgba
#define COLOR(rgba) (zeus::Comp32)(rgba)
#endif
namespace zeus {
@@ -48,21 +43,12 @@ public:
constexpr CColor(float r, float g, float b, float a = 1.0f) : mSimd(r, g, b, a) {}
#if ZE_ATHENA_TYPES
constexpr CColor(Comp32 rgba)
: mSimd(((COLOR(rgba) >> 0) & 0xff) * OneOver255, ((COLOR(rgba) >> 8) & 0xff) * OneOver255,
((COLOR(rgba) >> 16) & 0xff) * OneOver255, ((COLOR(rgba) >> 24) & 0xff) * OneOver255) {}
constexpr CColor(const atVec4f& vec) : mSimd(vec.simd) {}
#endif
constexpr CColor(Comp32 rgba) : mSimd(((COLOR(rgba) >> 0) & 0xff) * OneOver255,
((COLOR(rgba) >> 8) & 0xff) * OneOver255,
((COLOR(rgba) >> 16) & 0xff) * OneOver255,
((COLOR(rgba) >> 24) & 0xff) * OneOver255) {}
constexpr CColor(const Comp8* rgba) : mSimd(rgba[0] * OneOver255,
rgba[1] * OneOver255,
rgba[2] * OneOver255,
rgba[3] * OneOver255) {}
constexpr CColor(const Comp8* rgba)
: mSimd(rgba[0] * OneOver255, rgba[1] * OneOver255, rgba[2] * OneOver255, rgba[3] * OneOver255) {}
constexpr CColor(const CVector4f& other) : mSimd(other.mSimd) {}
@@ -259,6 +245,28 @@ public:
ao = Comp8(a() * 255);
}
Comp32 toRGBA() const {
RGBA32 ret;
ret.r = r() * 255;
ret.g = g() * 255;
ret.b = b() * 255;
ret.a = a() * 255;
return COLOR(ret.rgba);
}
[[nodiscard]] unsigned short toRGB5A3() const {
Comp8 r;
Comp8 g;
Comp8 b;
Comp8 a;
toRGBA8(r, g, b, a);
if (a == 255) {
return static_cast<unsigned short>((r & 0xf8) << 7 | (g & 0xf8) << 2 | b >> 3 | 0x8000);
}
return static_cast<unsigned short>((r & 0xf0) << 4 | (g & 0xf0) | b >> 4 | (a & 0xe0) << 7);
}
/**
* @brief Assigns rgba from hsv
* @param h[0-1] The hue percentage of the color.
@@ -351,4 +359,4 @@ struct hash<zeus::CColor> {
return ret;
}
};
}
} // namespace std

View File

@@ -9,8 +9,9 @@ class CTransform;
class CEulerAngles : public CVector3f {
public:
constexpr CEulerAngles(float x, float y, float z) : CVector3f(x, y, z) {}
CEulerAngles(const CQuaternion& quat);
CEulerAngles(const CTransform& xf);
explicit CEulerAngles(const CQuaternion& quat);
explicit CEulerAngles(const CTransform& xf);
explicit CEulerAngles(const CVector3f& vec) : CVector3f(vec) {}
};
} // namespace zeus

View File

@@ -23,13 +23,13 @@ public:
constexpr CMatrix3f(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22)
: m{{{m00, m10, m20}, {m01, m11, m21}, {m02, m12, m22}}} {}
constexpr CMatrix3f(const CVector3f& scaleVec) {
CMatrix3f(const CVector3f& scaleVec) {
m[0][0] = scaleVec[0];
m[1][1] = scaleVec[1];
m[2][2] = scaleVec[2];
}
constexpr CMatrix3f(float scale) : CMatrix3f(CVector3f(scale)) {}
CMatrix3f(float scale) : CMatrix3f(CVector3f(scale)) {}
constexpr CMatrix3f(const CVector3f& r0, const CVector3f& r1, const CVector3f& r2) : m{{r0, r1, r2}} {}

View File

@@ -51,6 +51,14 @@ public:
constexpr CMatrix4f& operator=(const CMatrix4f& other) = default;
[[nodiscard]] bool operator==(const CMatrix4f& rhs) const {
return m[0] == rhs.m[0] && m[1] == rhs.m[1] && m[2] == rhs.m[2] && m[3] == rhs.m[3];
}
[[nodiscard]] bool operator!=(const CMatrix4f& rhs) const {
return m[0] != rhs.m[0] || m[1] != rhs.m[1] || m[2] != rhs.m[2] || m[3] != rhs.m[3];
}
[[nodiscard]] CVector4f operator*(const CVector4f& other) const {
return m[0].mSimd * other.mSimd.shuffle<0, 0, 0, 0>() + m[1].mSimd * other.mSimd.shuffle<1, 1, 1, 1>() +
m[2].mSimd * other.mSimd.shuffle<2, 2, 2, 2>() + m[3].mSimd * other.mSimd.shuffle<3, 3, 3, 3>();

View File

@@ -4,28 +4,9 @@
#include "zeus/CTransform.hpp"
#include "zeus/CVector3f.hpp"
#if ZE_ATHENA_TYPES
#include <athena/IStreamReader.hpp>
#endif
namespace zeus {
class COBBox {
public:
#if ZE_ATHENA_TYPES
void readBig(athena::io::IStreamReader& in) {
transform.read34RowMajor(in);
extents.readBig(in);
}
[[nodiscard]] static COBBox ReadBig(athena::io::IStreamReader& in) {
COBBox out;
out.readBig(in);
return out;
}
#endif
CTransform transform;
CVector3f extents;

View File

@@ -38,7 +38,7 @@ public:
mSimd[3] = nd * mag;
}
[[nodiscard]] float pointToPlaneDist(const CVector3f& pos) const { return pos.dot(normal()) - d(); }
[[nodiscard]] float pointToPlaneDist(const CVector3f& pos) const { return normal().dot(pos) - d(); }
[[nodiscard]] bool rayPlaneIntersection(const CVector3f& from, const CVector3f& to, CVector3f& point) const;

View File

@@ -10,10 +10,6 @@
#include "zeus/CVector4f.hpp"
#include "zeus/Global.hpp"
#if ZE_ATHENA_TYPES
#include <athena/IStreamReader.hpp>
#endif
namespace zeus {
class CNUQuaternion;
@@ -32,25 +28,6 @@ public:
template <typename T>
constexpr CQuaternion(const simd<T>& s) : mSimd(s) {}
#if ZE_ATHENA_TYPES
void readBig(athena::io::IStreamReader& input) {
simd_floats f;
f[0] = input.readFloatBig();
f[1] = input.readFloatBig();
f[2] = input.readFloatBig();
f[3] = input.readFloatBig();
mSimd.copy_from(f);
}
constexpr CQuaternion(const atVec4f& vec) : mSimd(vec.simd) {}
operator atVec4f&() { return *reinterpret_cast<atVec4f*>(this); }
operator const atVec4f&() const { return *reinterpret_cast<const atVec4f*>(this); }
#endif
CQuaternion(const CMatrix3f& mat);
CQuaternion(const CVector3f& vec) { fromVector3f(vec); }
@@ -75,9 +52,16 @@ public:
[[nodiscard]] CQuaternion operator-(const CQuaternion& q) const { return mSimd - q.mSimd; }
[[nodiscard]] CQuaternion operator*(const CQuaternion& q) const;
[[nodiscard]] CQuaternion operator*(const CQuaternion& q) const {
return CQuaternion(w() * q.w() - CVector3f(x(), y(), z()).dot({q.x(), q.y(), q.z()}),
y() * q.z() - z() * q.y() + w() * q.x() + x() * q.w(),
z() * q.x() - x() * q.z() + w() * q.y() + y() * q.w(),
x() * q.y() - y() * q.x() + w() * q.z() + z() * q.w());
}
[[nodiscard]] CQuaternion operator/(const CQuaternion& q) const;
[[nodiscard]] CQuaternion operator/(const CQuaternion& q) const {
return *this * q.inverse();
}
[[nodiscard]] CQuaternion operator*(float scale) const { return mSimd * simd<float>(scale); }
@@ -234,9 +218,9 @@ public:
*/
class CNUQuaternion {
public:
CNUQuaternion() : mSimd(1.f, 0.f, 0.f, 0.f) {}
constexpr CNUQuaternion() : mSimd(1.f, 0.f, 0.f, 0.f) {}
CNUQuaternion(float wi, float xi, float yi, float zi) : mSimd(wi, xi, yi, zi) {}
constexpr CNUQuaternion(float wi, float xi, float yi, float zi) : mSimd(wi, xi, yi, zi) {}
CNUQuaternion(float win, const zeus::CVector3f& vec) : mSimd(vec.mSimd.shuffle<0, 0, 1, 2>()) { w() = win; }
@@ -244,7 +228,7 @@ public:
CNUQuaternion(const CMatrix3f& mtx) : CNUQuaternion(CQuaternion(mtx)) {}
CNUQuaternion(const simd<float>& s) : mSimd(s) {}
constexpr CNUQuaternion(const simd<float>& s) : mSimd(s) {}
[[nodiscard]] static CNUQuaternion fromAxisAngle(const CUnitVector3f& axis, const CRelAngle& angle) {
return CNUQuaternion(CQuaternion::fromAxisAngle(axis, angle));
@@ -264,7 +248,12 @@ public:
return mSimd * simd<float>(magDiv);
}
[[nodiscard]] CNUQuaternion operator*(const CNUQuaternion& q) const;
[[nodiscard]] CNUQuaternion operator*(const CNUQuaternion& q) const {
return CNUQuaternion(w() * q.w() - CVector3f(x(), y(), z()).dot({q.x(), q.y(), q.z()}),
y() * q.z() - z() * q.y() + w() * q.x() + x() * q.w(),
z() * q.x() - x() * q.z() + w() * q.y() + y() * q.w(),
x() * q.y() - y() * q.x() + w() * q.z() + z() * q.w());
}
[[nodiscard]] CNUQuaternion operator*(float f) const { return mSimd * simd<float>(f); }

View File

@@ -14,24 +14,7 @@ class CTransform {
public:
constexpr CTransform() : basis(false) {}
constexpr CTransform(const CMatrix3f& basis, const CVector3f& offset = {})
: basis(basis), origin(offset) {}
#if ZE_ATHENA_TYPES
CTransform(const atVec4f* mtx)
: basis(mtx[0], mtx[1], mtx[2]), origin(mtx[0].simd[3], mtx[1].simd[3], mtx[2].simd[3]) {}
void read34RowMajor(athena::io::IStreamReader& r) {
atVec4f r0 = r.readVec4fBig();
atVec4f r1 = r.readVec4fBig();
atVec4f r2 = r.readVec4fBig();
basis = CMatrix3f(r0, r1, r2);
basis.transpose();
origin = CVector3f(r0.simd[3], r1.simd[3], r2.simd[3]);
}
#endif
constexpr CTransform(const CMatrix3f& basis, const CVector3f& offset = {}) : basis(basis), origin(offset) {}
/* Column constructor */
constexpr CTransform(const CVector3f& c0, const CVector3f& c1, const CVector3f& c2, const CVector3f& c3)
@@ -52,6 +35,15 @@ public:
return CTransform(inv, inv * -origin);
}
[[nodiscard]] CTransform quickInverse() const {
return CTransform{basis.transposed(),
CVector3f{
basis[0][0] * -origin.x() - basis[0][1] * origin.y() - basis[0][2] * origin.z(),
basis[1][0] * -origin.x() - basis[1][1] * origin.y() - basis[1][2] * origin.z(),
basis[2][0] * -origin.x() - basis[2][1] * origin.y() - basis[2][2] * origin.z(),
}};
}
[[nodiscard]] static CTransform Translate(const CVector3f& position) { return {CMatrix3f(), position}; }
[[nodiscard]] static CTransform Translate(float x, float y, float z) { return Translate({x, y, z}); }
@@ -194,6 +186,24 @@ public:
return ret;
}
/**
* Outputs the matrix to a C-style array (column-major, GX style)
*/
void toCStyleMatrix(float mtx[3][4]) const {
mtx[0][0] = basis[0][0];
mtx[0][1] = basis[1][0];
mtx[0][2] = basis[2][0];
mtx[0][3] = origin.x();
mtx[1][0] = basis[0][1];
mtx[1][1] = basis[1][1];
mtx[1][2] = basis[2][1];
mtx[1][3] = origin.y();
mtx[2][0] = basis[0][2];
mtx[2][1] = basis[1][2];
mtx[2][2] = basis[2][2];
mtx[2][3] = origin.z();
}
[[nodiscard]] CVector3f upVector() const { return basis.m[2]; }
[[nodiscard]] CVector3f frontVector() const { return basis.m[1]; }

191
include/zeus/CVector2d.hpp Normal file
View File

@@ -0,0 +1,191 @@
#pragma once
#include <cassert>
#include "zeus/Global.hpp"
#include "zeus/Math.hpp"
namespace zeus {
class CVector2d {
public:
simd<double> mSimd;
constexpr CVector2d() : mSimd() {}
template <typename T>
constexpr CVector2d(const simd<T>& s) : mSimd(s) {}
explicit constexpr CVector2d(double xy) : mSimd(xy) {}
constexpr void assign(double x, double y) {
mSimd.set(x, y);
}
constexpr CVector2d(double x, double y) : mSimd(x, y, 0.f, 0.f) {}
[[nodiscard]] bool operator==(const CVector2d& rhs) const {
return mSimd[0] == rhs.mSimd[0] && mSimd[1] == rhs.mSimd[1];
}
[[nodiscard]] bool operator!=(const CVector2d& rhs) const {
return mSimd[0] != rhs.mSimd[0] || mSimd[1] != rhs.mSimd[1];
}
[[nodiscard]] bool operator<(const CVector2d& rhs) const {
return mSimd[0] < rhs.mSimd[0] && mSimd[1] < rhs.mSimd[1];
}
[[nodiscard]] bool operator<=(const CVector2d& rhs) const {
return mSimd[0] <= rhs.mSimd[0] && mSimd[1] <= rhs.mSimd[1];
}
[[nodiscard]] bool operator>(const CVector2d& rhs) const {
return mSimd[0] > rhs.mSimd[0] && mSimd[1] > rhs.mSimd[1];
}
[[nodiscard]] bool operator>=(const CVector2d& rhs) const {
return mSimd[0] >= rhs.mSimd[0] && mSimd[1] >= rhs.mSimd[1];
}
[[nodiscard]] CVector2d operator+(const CVector2d& rhs) const { return mSimd + rhs.mSimd; }
[[nodiscard]] CVector2d operator-(const CVector2d& rhs) const { return mSimd - rhs.mSimd; }
[[nodiscard]] CVector2d operator-() const { return -mSimd; }
[[nodiscard]] CVector2d operator*(const CVector2d& rhs) const { return mSimd * rhs.mSimd; }
[[nodiscard]] CVector2d operator/(const CVector2d& rhs) const { return mSimd / rhs.mSimd; }
[[nodiscard]] CVector2d operator+(double val) const { return mSimd + simd<double>(val); }
[[nodiscard]] CVector2d operator-(double val) const { return mSimd - simd<double>(val); }
[[nodiscard]] CVector2d operator*(double val) const { return mSimd * simd<double>(val); }
[[nodiscard]] CVector2d operator/(double val) const {
double ooval = 1.0 / val;
return mSimd * simd<double>(ooval);
}
const CVector2d& operator+=(const CVector2d& rhs) {
mSimd += rhs.mSimd;
return *this;
}
const CVector2d& operator-=(const CVector2d& rhs) {
mSimd -= rhs.mSimd;
return *this;
}
const CVector2d& operator*=(const CVector2d& rhs) {
mSimd *= rhs.mSimd;
return *this;
}
const CVector2d& operator/=(const CVector2d& rhs) {
mSimd /= rhs.mSimd;
return *this;
}
const CVector2d& operator+=(double rhs) {
mSimd += simd<double>(rhs);
return *this;
}
const CVector2d& operator-=(double rhs) {
mSimd -= simd<double>(rhs);
return *this;
}
const CVector2d& operator*=(double rhs) {
mSimd *= simd<double>(rhs);
return *this;
}
const CVector2d& operator/=(double rhs) {
double oorhs = 1.0 / rhs;
mSimd *= simd<double>(oorhs);
return *this;
}
void normalize() {
double mag = magnitude();
mag = 1.f / mag;
*this *= CVector2d(mag);
}
[[nodiscard]] CVector2d normalized() const {
double mag = magnitude();
mag = 1.f / mag;
return *this * mag;
}
[[nodiscard]] constexpr CVector2d perpendicularVector() const { return {-y(), x()}; }
[[nodiscard]] constexpr double cross(const CVector2d& rhs) const { return (x() * rhs.y()) - (y() * rhs.x()); }
[[nodiscard]] constexpr double dot(const CVector2d& rhs) const { return mSimd.dot2(rhs.mSimd); }
[[nodiscard]] constexpr double magSquared() const { return mSimd.dot2(mSimd); }
[[nodiscard]] double magnitude() const { return std::sqrt(magSquared()); }
constexpr void zeroOut() { mSimd = 0.f; }
constexpr void splat(double xy) { mSimd = xy; }
[[nodiscard]] static double getAngleDiff(const CVector2d& a, const CVector2d& b);
[[nodiscard]] static CVector2d lerp(const CVector2d& a, const CVector2d& b, double t) {
return zeus::simd<double>(1.f - t) * a.mSimd + b.mSimd * zeus::simd<double>(t);
}
[[nodiscard]] static CVector2d nlerp(const CVector2d& a, const CVector2d& b, double t) {
return lerp(a, b, t).normalized();
}
[[nodiscard]] static CVector2d slerp(const CVector2d& a, const CVector2d& b, double t);
[[nodiscard]] bool isNormalized() const { return std::fabs(1.0 - magSquared()) < 0.01; }
[[nodiscard]] bool canBeNormalized() const {
if (std::isinf(x()) || std::isinf(y()))
return false;
return std::fabs(x()) >= DBL_EPSILON || std::fabs(y()) >= DBL_EPSILON;
}
[[nodiscard]] bool isZero() const { return mSimd[0] == 0.f && mSimd[1] == 0.f; }
[[nodiscard]] bool isEqu(const CVector2d& other, double epsilon = FLT_EPSILON) const {
const CVector2d diffVec = other - *this;
return (diffVec.x() <= epsilon && diffVec.y() <= epsilon);
}
[[nodiscard]] simd<double>::reference operator[](size_t idx) {
assert(idx < 2);
return mSimd[idx];
}
[[nodiscard]] constexpr double operator[](size_t idx) const {
assert(idx < 2);
return mSimd[idx];
}
[[nodiscard]] constexpr double x() const { return mSimd[0]; }
[[nodiscard]] constexpr double y() const { return mSimd[1]; }
[[nodiscard]] simd<double>::reference x() { return mSimd[0]; }
[[nodiscard]] simd<double>::reference y() { return mSimd[1]; }
};
constexpr inline CVector2d skOne2d(1.0);
constexpr inline CVector2d skNegOne2d(-1.0);
constexpr inline CVector2d skZero2d(0.0);
[[nodiscard]] inline CVector2d operator+(double lhs, const CVector2d& rhs) { return zeus::simd<double>(lhs) + rhs.mSimd; }
[[nodiscard]] inline CVector2d operator-(double lhs, const CVector2d& rhs) { return zeus::simd<double>(lhs) - rhs.mSimd; }
[[nodiscard]] inline CVector2d operator*(double lhs, const CVector2d& rhs) { return zeus::simd<double>(lhs) * rhs.mSimd; }
[[nodiscard]] inline CVector2d operator/(double lhs, const CVector2d& rhs) { return zeus::simd<double>(lhs) / rhs.mSimd; }
} // namespace zeus

View File

@@ -5,10 +5,6 @@
#include "zeus/Global.hpp"
#include "zeus/Math.hpp"
#if ZE_ATHENA_TYPES
#include <athena/IStreamReader.hpp>
#endif
namespace zeus {
class CVector2f {
public:
@@ -18,29 +14,6 @@ public:
template <typename T>
constexpr CVector2f(const simd<T>& s) : mSimd(s) {}
#if ZE_ATHENA_TYPES
constexpr CVector2f(const atVec2f& vec) : mSimd(vec.simd) {}
operator atVec2f&() { return *reinterpret_cast<atVec2f*>(this); }
operator const atVec2f&() const { return *reinterpret_cast<const atVec2f*>(this); }
void readBig(athena::io::IStreamReader& input) {
mSimd[0] = input.readFloatBig();
mSimd[1] = input.readFloatBig();
mSimd[2] = 0.0f;
mSimd[3] = 0.0f;
}
[[nodiscard]] static CVector2f ReadBig(athena::io::IStreamReader& input) {
CVector2f ret;
ret.readBig(input);
return ret;
}
#endif
explicit constexpr CVector2f(float xy) : mSimd(xy) {}
constexpr void assign(float x, float y) {

View File

@@ -5,10 +5,6 @@
#include "zeus/CVector3f.hpp"
#include "zeus/Global.hpp"
#if ZE_ATHENA_TYPES
#include <athena/Types.hpp>
#endif
namespace zeus {
class CVector3d {
@@ -19,10 +15,6 @@ public:
template <typename T>
constexpr CVector3d(const simd<T>& s) : mSimd(s) {}
#if ZE_ATHENA_TYPES
constexpr CVector3d(const atVec3d& vec) : mSimd(vec.simd) {}
#endif
explicit constexpr CVector3d(double xyz) : mSimd(xyz) {}
CVector3d(const CVector3f& vec) : mSimd(vec.mSimd) {}

View File

@@ -8,10 +8,6 @@
#include "zeus/Global.hpp"
#include "zeus/Math.hpp"
#if ZE_ATHENA_TYPES
#include <athena/IStreamReader.hpp>
#endif
namespace zeus {
class CVector3d;
class CRelAngle;
@@ -24,31 +20,6 @@ public:
template <typename T>
constexpr CVector3f(const simd<T>& s) : mSimd(s) {}
#if ZE_ATHENA_TYPES
constexpr CVector3f(const atVec3f& vec) : mSimd(vec.simd) {}
operator atVec3f&() { return *reinterpret_cast<atVec3f*>(this); }
operator const atVec3f&() const { return *reinterpret_cast<const atVec3f*>(this); }
void readBig(athena::io::IStreamReader& input) {
simd_floats f;
f[0] = input.readFloatBig();
f[1] = input.readFloatBig();
f[2] = input.readFloatBig();
f[3] = 0.0f;
mSimd.copy_from(f);
}
[[nodiscard]] static CVector3f ReadBig(athena::io::IStreamReader& input) {
CVector3f ret;
ret.readBig(input);
return ret;
}
#endif
inline CVector3f(const CVector3d& vec);
explicit constexpr CVector3f(float xyz) : mSimd(xyz) {}

189
include/zeus/CVector4d.hpp Normal file
View File

@@ -0,0 +1,189 @@
#pragma once
#include <cassert>
#include <cfloat>
#include <cmath>
#include "zeus/CVector3f.hpp"
#include "zeus/Global.hpp"
#if ZE_ATHENA_TYPES
#include <athena/IStreamReader.hpp>
#endif
namespace zeus {
class CColor;
class CVector4d {
public:
zeus::simd<double> mSimd;
constexpr CVector4d() : mSimd() {}
template <typename T>
constexpr CVector4d(const simd<T>& s) : mSimd(s) {}
explicit constexpr CVector4d(double xyzw) : mSimd(xyzw) {}
void assign(double x, double y, double z, double w) { mSimd = simd<double>(x, y, z, w); }
constexpr CVector4d(double x, double y, double z, double w) : mSimd(x, y, z, w) {}
constexpr CVector4d(const CColor& other);
CVector4d(const CVector3f& other, double wIn = 1.0) : mSimd(other.mSimd) { mSimd[3] = wIn; }
[[nodiscard]] static CVector4d ToClip(const zeus::CVector3f& v, double w) { return CVector4d(v * w, w); }
[[nodiscard]] CVector3f toVec3f() const { return CVector3f(mSimd); }
constexpr CVector4d& operator=(const CColor& other);
[[nodiscard]] bool operator==(const CVector4d& rhs) const {
auto eq_mask = mSimd == rhs.mSimd;
return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3];
}
[[nodiscard]] bool operator!=(const CVector4d& rhs) const {
auto eq_mask = mSimd != rhs.mSimd;
return eq_mask[0] || eq_mask[1] || eq_mask[2] || eq_mask[3];
}
[[nodiscard]] bool operator<(const CVector4d& rhs) const {
auto eq_mask = mSimd < rhs.mSimd;
return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3];
}
[[nodiscard]] bool operator<=(const CVector4d& rhs) const {
auto eq_mask = mSimd <= rhs.mSimd;
return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3];
}
[[nodiscard]] bool operator>(const CVector4d& rhs) const {
auto eq_mask = mSimd > rhs.mSimd;
return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3];
}
[[nodiscard]] bool operator>=(const CVector4d& rhs) const {
auto eq_mask = mSimd >= rhs.mSimd;
return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3];
}
[[nodiscard]] CVector4d operator+(const CVector4d& rhs) const { return mSimd + rhs.mSimd; }
[[nodiscard]] CVector4d operator-(const CVector4d& rhs) const { return mSimd - rhs.mSimd; }
[[nodiscard]] CVector4d operator-() const { return -mSimd; }
[[nodiscard]] CVector4d operator*(const CVector4d& rhs) const { return mSimd * rhs.mSimd; }
[[nodiscard]] CVector4d operator/(const CVector4d& rhs) const { return mSimd / rhs.mSimd; }
[[nodiscard]] CVector4d operator+(double val) const { return mSimd + zeus::simd<double>(val); }
[[nodiscard]] CVector4d operator-(double val) const { return mSimd - zeus::simd<double>(val); }
[[nodiscard]] CVector4d operator*(double val) const { return mSimd * zeus::simd<double>(val); }
[[nodiscard]] CVector4d operator/(double val) const {
double ooval = 1.0 / val;
return mSimd * zeus::simd<double>(ooval);
}
const CVector4d& operator+=(const CVector4d& rhs) {
mSimd += rhs.mSimd;
return *this;
}
const CVector4d& operator-=(const CVector4d& rhs) {
mSimd -= rhs.mSimd;
return *this;
}
const CVector4d& operator*=(const CVector4d& rhs) {
mSimd *= rhs.mSimd;
return *this;
}
const CVector4d& operator/=(const CVector4d& rhs) {
mSimd /= rhs.mSimd;
return *this;
}
void normalize() {
double mag = magnitude();
mag = 1.0 / mag;
*this *= CVector4d(mag);
}
[[nodiscard]] CVector4d normalized() const {
double mag = magnitude();
mag = 1.0 / mag;
return *this * mag;
}
[[nodiscard]] double dot(const CVector4d& rhs) const { return mSimd.dot4(rhs.mSimd); }
[[nodiscard]] double magSquared() const { return mSimd.dot4(mSimd); }
[[nodiscard]] double magnitude() const { return std::sqrt(magSquared()); }
void zeroOut() { mSimd = zeus::simd<double>(0.0); }
void splat(double xyzw) { mSimd = zeus::simd<double>(xyzw); }
[[nodiscard]] static CVector4d lerp(const CVector4d& a, const CVector4d& b, double t) {
return zeus::simd<double>(1.0 - t) * a.mSimd + b.mSimd * zeus::simd<double>(t);
}
[[nodiscard]] static CVector4d nlerp(const CVector4d& a, const CVector4d& b, double t) {
return lerp(a, b, t).normalized();
}
[[nodiscard]] bool isNormalized() const { return std::fabs(1.0 - magSquared()) < 0.01f; }
[[nodiscard]] bool canBeNormalized() const {
if (std::isinf(x()) || std::isinf(y()) || std::isinf(z()) || std::isinf(w()))
return false;
return std::fabs(x()) >= FLT_EPSILON || std::fabs(y()) >= FLT_EPSILON || std::fabs(z()) >= FLT_EPSILON ||
std::fabs(w()) >= FLT_EPSILON;
}
[[nodiscard]] bool isEqu(const CVector4d& other, double epsilon = FLT_EPSILON) const {
const CVector4d diffVec = other - *this;
return (diffVec.x() <= epsilon && diffVec.y() <= epsilon && diffVec.z() <= epsilon && diffVec.w() <= epsilon);
}
[[nodiscard]] simd<double>::reference operator[](size_t idx) {
assert(idx < 4);
return mSimd[idx];
}
[[nodiscard]] double operator[](size_t idx) const {
assert(idx < 4);
return mSimd[idx];
}
[[nodiscard]] double x() const { return mSimd[0]; }
[[nodiscard]] double y() const { return mSimd[1]; }
[[nodiscard]] double z() const { return mSimd[2]; }
[[nodiscard]] double w() const { return mSimd[3]; }
[[nodiscard]] simd<double>::reference x() { return mSimd[0]; }
[[nodiscard]] simd<double>::reference y() { return mSimd[1]; }
[[nodiscard]] simd<double>::reference z() { return mSimd[2]; }
[[nodiscard]] simd<double>::reference w() { return mSimd[3]; }
};
constexpr CVector4d skOne4d(1.0);
constexpr CVector4d skNegOne4d(-1.0);
constexpr CVector4d skZero4d(0.0);
[[nodiscard]] inline CVector4d operator+(double lhs, const CVector4d& rhs) { return zeus::simd<double>(lhs) + rhs.mSimd; }
[[nodiscard]] inline CVector4d operator-(double lhs, const CVector4d& rhs) { return zeus::simd<double>(lhs) - rhs.mSimd; }
[[nodiscard]] inline CVector4d operator*(double lhs, const CVector4d& rhs) { return zeus::simd<double>(lhs) * rhs.mSimd; }
[[nodiscard]] inline CVector4d operator/(double lhs, const CVector4d& rhs) { return zeus::simd<double>(lhs) / rhs.mSimd; }
} // namespace zeus

View File

@@ -23,25 +23,6 @@ public:
template <typename T>
constexpr CVector4f(const simd<T>& s) : mSimd(s) {}
#if ZE_ATHENA_TYPES
constexpr CVector4f(const atVec4f& vec) : mSimd(vec.simd) {}
operator atVec4f&() { return *reinterpret_cast<atVec4f*>(this); }
operator const atVec4f&() const { return *reinterpret_cast<const atVec4f*>(this); }
void readBig(athena::io::IStreamReader& input) {
simd_floats f;
f[0] = input.readFloatBig();
f[1] = input.readFloatBig();
f[2] = input.readFloatBig();
f[3] = input.readFloatBig();
mSimd.copy_from(f);
}
#endif
explicit constexpr CVector4f(float xyzw) : mSimd(xyzw) {}
void assign(float x, float y, float z, float w) { mSimd = simd<float>(x, y, z, w); }

View File

@@ -1,20 +1,8 @@
#pragma once
#if ZE_ATHENA_TYPES
#include "athena/IStreamReader.hpp"
#include "athena/simd/simd.hpp"
#else
#include "simd/simd.hpp"
#endif
namespace zeus {
#if ZE_ATHENA_TYPES
template <typename T>
using simd = athena::simd<T>;
using simd_floats = athena::simd_floats;
using simd_doubles = athena::simd_doubles;
#endif
template <typename SizeT>
constexpr void hash_combine_impl(SizeT& seed, SizeT value) noexcept {
seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2);

View File

@@ -184,10 +184,10 @@ template <typename E>
[[nodiscard]] bool close_enough(const CVector2f& a, const CVector2f& b, float epsilon = FLT_EPSILON);
[[nodiscard]] inline bool close_enough(float a, float b, double epsilon = FLT_EPSILON) {
return std::fabs(a - b) < epsilon;
return std::fabs(a - b) <= epsilon;
}
[[nodiscard]] inline bool close_enough(double a, double b, double epsilon = FLT_EPSILON) {
return std::fabs(a - b) < epsilon;
return std::fabs(a - b) <= epsilon;
}
} // namespace zeus

View File

@@ -1477,6 +1477,9 @@ private:
friend class simd_mask;
public:
constexpr __simd_storage(_Tp __rv) : __storage_{__rv, __rv, __rv, __rv} {}
constexpr __simd_storage(_Tp a, _Tp b, _Tp c, _Tp d) : __storage_{a, b, c, d} {}
constexpr _Tp __get(size_t __index) const noexcept { return __storage_[__index]; };
constexpr void __set(size_t __index, _Tp __val) noexcept { __storage_[__index] = __val; }
constexpr std::enable_if_t<__num_element >= 4> __set4(float a, float b, float c, float d) noexcept {

View File

@@ -18,7 +18,7 @@ using namespace std;
#elif __ARM_NEON
#include "simd_neon.hpp"
#else
namespace simd_abi {
namespace zeus::_simd::simd_abi {
template <typename T>
struct zeus_native {};
template <>
@@ -29,7 +29,8 @@ template <>
struct zeus_native<double> {
using type = fixed_size<4>;
};
} // namespace simd_abi
} // namespace zeus::_simd::simd_abi
#include "simd_none.hpp"
#endif
#ifdef __GNUC__
#pragma GCC diagnostic pop

View File

@@ -0,0 +1,224 @@
#pragma once
#ifndef _ZEUS_SIMD_INCLUDED
#error simd_none.hpp must not be included directly. Include simd.hpp instead.
#endif
namespace zeus::_simd {
using m128_abi = __simd_abi<_StorageKind::_Array, 4>;
using m128d_abi = __simd_abi<_StorageKind::_Array, 4>;
// m128 ABI
template <>
inline simd<float, m128_abi> simd<float, m128_abi>::operator-() const {
return {-__s_.__storage_[0], -__s_.__storage_[1], -__s_.__storage_[2], -__s_.__storage_[3]};
}
inline simd<float, m128_abi> operator+(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
return {a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]};
}
inline simd<float, m128_abi> operator-(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
return {a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3]};
}
inline simd<float, m128_abi> operator*(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
return {a[0] * b[0], a[1] * b[1], a[2] * b[2], a[3] * b[3]};
}
inline simd<float, m128_abi> operator/(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
return {a[0] / b[0], a[1] / b[1], a[2] / b[2], a[3] / b[3]};
}
inline simd<float, m128_abi>& operator+=(simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
a[0] += b[0];
a[1] += b[1];
a[2] += b[2];
a[3] += b[3];
return a;
}
inline simd<float, m128_abi>& operator-=(simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
a[0] -= b[0];
a[1] -= b[1];
a[2] -= b[2];
a[3] -= b[3];
return a;
}
inline simd<float, m128_abi>& operator*=(simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
a[0] *= b[0];
a[1] *= b[1];
a[2] *= b[2];
a[3] *= b[3];
return a;
}
inline simd<float, m128_abi>& operator/=(simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
a[0] /= b[0];
a[1] /= b[1];
a[2] /= b[2];
a[3] /= b[3];
return a;
}
inline simd<float, m128_abi>::mask_type operator==(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi>::mask_type ret;
ret[0] = a[0] == b[0];
ret[1] = a[1] == b[1];
ret[2] = a[2] == b[2];
ret[3] = a[3] == b[3];
return ret;
}
inline simd<float, m128_abi>::mask_type operator!=(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi>::mask_type ret;
ret[0] = a[0] != b[0];
ret[1] = a[1] != b[1];
ret[2] = a[2] != b[2];
ret[3] = a[3] != b[3];
return ret;
}
inline simd<float, m128_abi>::mask_type operator>=(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi>::mask_type ret;
ret[0] = a[0] >= b[0];
ret[1] = a[1] >= b[1];
ret[2] = a[2] >= b[2];
ret[3] = a[3] >= b[3];
return ret;
}
inline simd<float, m128_abi>::mask_type operator<=(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi>::mask_type ret;
ret[0] = a[0] <= b[0];
ret[1] = a[1] <= b[1];
ret[2] = a[2] <= b[2];
ret[3] = a[3] <= b[3];
return ret;
}
inline simd<float, m128_abi>::mask_type operator>(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi>::mask_type ret;
ret[0] = a[0] > b[0];
ret[1] = a[1] > b[1];
ret[2] = a[2] > b[2];
ret[3] = a[3] > b[3];
return ret;
}
inline simd<float, m128_abi>::mask_type operator<(const simd<float, m128_abi>& a, const simd<float, m128_abi>& b) {
simd<float, m128_abi>::mask_type ret;
ret[0] = a[0] < b[0];
ret[1] = a[1] < b[1];
ret[2] = a[2] < b[2];
ret[3] = a[3] < b[3];
return ret;
}
// m128d ABI
template <>
inline simd<double, m128d_abi> simd<double, m128d_abi>::operator-() const {
return {-__s_.__storage_[0], -__s_.__storage_[1], -__s_.__storage_[2], -__s_.__storage_[3]};
}
inline simd<double, m128d_abi> operator+(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
return {a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]};
}
inline simd<double, m128d_abi> operator-(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
return {a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3]};
}
inline simd<double, m128d_abi> operator*(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
return {a[0] * b[0], a[1] * b[1], a[2] * b[2], a[3] * b[3]};
}
inline simd<double, m128d_abi> operator/(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
return {a[0] / b[0], a[1] / b[1], a[2] / b[2], a[3] / b[3]};
}
inline simd<double, m128d_abi>& operator+=(simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
a[0] += b[0];
a[1] += b[1];
a[2] += b[2];
a[3] += b[3];
return a;
}
inline simd<double, m128d_abi>& operator-=(simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
a[0] -= b[0];
a[1] -= b[1];
a[2] -= b[2];
a[3] -= b[3];
return a;
}
inline simd<double, m128d_abi>& operator*=(simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
a[0] *= b[0];
a[1] *= b[1];
a[2] *= b[2];
a[3] *= b[3];
return a;
}
inline simd<double, m128d_abi>& operator/=(simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
a[0] /= b[0];
a[1] /= b[1];
a[2] /= b[2];
a[3] /= b[3];
return a;
}
inline simd<double, m128d_abi>::mask_type operator==(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
simd<double, m128d_abi>::mask_type ret;
ret[0] = a[0] == b[0];
ret[1] = a[1] == b[1];
ret[2] = a[2] == b[2];
ret[3] = a[3] == b[3];
return ret;
}
inline simd<double, m128d_abi>::mask_type operator!=(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
simd<double, m128d_abi>::mask_type ret;
ret[0] = a[0] != b[0];
ret[1] = a[1] != b[1];
ret[2] = a[2] != b[2];
ret[3] = a[3] != b[3];
return ret;
}
inline simd<double, m128d_abi>::mask_type operator>=(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
simd<double, m128d_abi>::mask_type ret;
ret[0] = a[0] >= b[0];
ret[1] = a[1] >= b[1];
ret[2] = a[2] >= b[2];
ret[3] = a[3] >= b[3];
return ret;
}
inline simd<double, m128d_abi>::mask_type operator<=(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
simd<double, m128d_abi>::mask_type ret;
ret[0] = a[0] <= b[0];
ret[1] = a[1] <= b[1];
ret[2] = a[2] <= b[2];
ret[3] = a[3] <= b[3];
return ret;
}
inline simd<double, m128d_abi>::mask_type operator>(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
simd<double, m128d_abi>::mask_type ret;
ret[0] = a[0] > b[0];
ret[1] = a[1] > b[1];
ret[2] = a[2] > b[2];
ret[3] = a[3] > b[3];
return ret;
}
inline simd<double, m128d_abi>::mask_type operator<(const simd<double, m128d_abi>& a, const simd<double, m128d_abi>& b) {
simd<double, m128d_abi>::mask_type ret;
ret[0] = a[0] < b[0];
ret[1] = a[1] < b[1];
ret[2] = a[2] < b[2];
ret[3] = a[3] < b[3];
return ret;
}
} // namespace zeus::_simd

View File

@@ -1,4 +1,5 @@
#pragma once
#include <cstdint>
#ifndef _ZEUS_SIMD_INCLUDED
#error simd_sse.hpp must not be included directly. Include simd.hpp instead.
#endif

View File

@@ -18,8 +18,11 @@
#include "zeus/CTransform.hpp"
#include "zeus/CUnitVector.hpp"
#include "zeus/CVector2f.hpp"
#include "zeus/CVector3d.hpp"
#include "zeus/CVector2i.hpp"
#include "zeus/CVector2d.hpp"
#include "zeus/CVector3f.hpp"
#include "zeus/CVector3d.hpp"
#include "zeus/CVector4f.hpp"
#include "zeus/CVector4d.hpp"
#include "zeus/Global.hpp"
#include "zeus/Math.hpp"

View File

@@ -4,8 +4,7 @@
namespace zeus {
CMatrix3f::CMatrix3f(const CQuaternion& quat) {
CQuaternion nq = quat.normalized();
CMatrix3f::CMatrix3f(const CQuaternion& nq) {
float x2 = nq.x() * nq.x();
float y2 = nq.y() * nq.y();
float z2 = nq.z() * nq.z();
@@ -47,15 +46,15 @@ void CMatrix3f::transpose() {
float tmp;
tmp = m[0][1];
m[0][1] = m[1][0];
m[0][1] = m[1][0].operator float();
m[1][0] = tmp;
tmp = m[0][2];
m[0][2] = m[2][0];
m[0][2] = m[2][0].operator float();
m[2][0] = tmp;
tmp = m[1][2];
m[1][2] = m[2][1];
m[1][2] = m[2][1].operator float();
m[2][1] = tmp;
#endif
}
@@ -81,15 +80,15 @@ CMatrix3f CMatrix3f::transposed() const {
float tmp;
tmp = ret.m[0][1];
ret.m[0][1] = ret.m[1][0];
ret.m[0][1] = ret.m[1][0].operator float();
ret.m[1][0] = tmp;
tmp = m[0][2];
ret.m[0][2] = ret.m[2][0];
ret.m[0][2] = ret.m[2][0].operator float();
ret.m[2][0] = tmp;
tmp = m[1][2];
ret.m[1][2] = ret.m[2][1];
ret.m[1][2] = ret.m[2][1].operator float();
ret.m[2][1] = tmp;
return ret;

View File

@@ -79,25 +79,6 @@ void CQuaternion::fromVector3f(const CVector3f& vec) {
mSimd.copy_from(f);
}
CQuaternion CQuaternion::operator*(const CQuaternion& q) const {
return CQuaternion(w() * q.w() - CVector3f(x(), y(), z()).dot({q.x(), q.y(), q.z()}),
y() * q.z() - z() * q.y() + w() * q.x() + x() * q.w(),
z() * q.x() - x() * q.z() + w() * q.y() + y() * q.w(),
x() * q.y() - y() * q.x() + w() * q.z() + z() * q.w());
}
CNUQuaternion CNUQuaternion::operator*(const CNUQuaternion& q) const {
return CNUQuaternion(w() * q.w() - CVector3f(x(), y(), z()).dot({q.x(), q.y(), q.z()}),
y() * q.z() - z() * q.y() + w() * q.x() + x() * q.w(),
z() * q.x() - x() * q.z() + w() * q.y() + y() * q.w(),
x() * q.y() - y() * q.x() + w() * q.z() + z() * q.w());
}
CQuaternion CQuaternion::operator/(const CQuaternion& q) const {
CQuaternion p(q);
p.invert();
return *this * p;
}
const CQuaternion& CQuaternion::operator*=(const CQuaternion& q) {
CQuaternion orig = *this;

View File

@@ -183,19 +183,14 @@ CTransform lookAt(const CVector3f& pos, const CVector3f& lookPos, const CVector3
CVector3f getBezierPoint(const CVector3f& a, const CVector3f& b, const CVector3f& c, const CVector3f& d, float t) {
const float omt = 1.f - t;
return ((a * omt + b * t) * omt + (b * omt + c * t) * t) * omt +
return (((a * omt) + b * t) * omt + (b * omt + c * t) * t) * omt +
((b * omt + c * t) * omt + (c * omt + d * t) * t) * t;
}
int floorPowerOfTwo(int x) {
if (x == 0)
return 0;
/*
* we want to ensure that we always get the previous power,
* but if we have values like 256, we'll always get the same value,
* x-1 ensures that we always get the previous power.
*/
x = (x - 1) | (x >> 1);
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
@@ -277,11 +272,11 @@ CVector3f baryToWorld(const CVector3f& p0, const CVector3f& p1, const CVector3f&
}
bool close_enough(const CVector3f& a, const CVector3f& b, float epsilon) {
return std::fabs(a.x() - b.x()) < epsilon && std::fabs(a.y() - b.y()) < epsilon && std::fabs(a.z() - b.z()) < epsilon;
return std::fabs(a.x() - b.x()) <= epsilon && std::fabs(a.y() - b.y()) <= epsilon && std::fabs(a.z() - b.z()) <= epsilon;
}
bool close_enough(const CVector2f& a, const CVector2f& b, float epsilon) {
return std::fabs(a.x() - b.x()) < epsilon && std::fabs(a.y() - b.y()) < epsilon;
return std::fabs(a.x() - b.x()) <= epsilon && std::fabs(a.y() - b.y()) <= epsilon;
}
template <>