General: Mark functions as nodiscard where applicable

Given this aims to be a general purpose math library for use in various
other libraries applications for axiodl, we can annotate functions that
return by value or reference with [[nodiscard]] where it's very obvious
that not making use of the return value is a bug.

This allows the compiler to diagnose and emit warnings for these API
misuses at compile-time, preventing silent bugs from occurring.

Any cases where not using the return value is desirable may still be
casted to void in order to silence warnings.
This commit is contained in:
Lioncash 2020-02-29 04:33:29 -05:00
parent 97cec53046
commit 81f9b4a4ee
21 changed files with 474 additions and 414 deletions

View File

@ -47,7 +47,7 @@ public:
max.readBig(in); max.readBig(in);
} }
static CAABox ReadBoundingBoxBig(athena::io::IStreamReader& in) { [[nodiscard]] static CAABox ReadBoundingBoxBig(athena::io::IStreamReader& in) {
CAABox ret; CAABox ret;
ret.readBoundingBoxBig(in); ret.readBoundingBoxBig(in);
return ret; return ret;
@ -55,28 +55,28 @@ public:
#endif #endif
bool intersects(const CAABox& other) const { [[nodiscard]] bool intersects(const CAABox& other) const {
bool x1 = (max[0] >= other.min[0]); const bool x1 = max[0] >= other.min[0];
bool x2 = (min[0] <= other.max[0]); const bool x2 = min[0] <= other.max[0];
bool y1 = (max[1] >= other.min[1]); const bool y1 = max[1] >= other.min[1];
bool y2 = (min[1] <= other.max[1]); const bool y2 = min[1] <= other.max[1];
bool z1 = (max[2] >= other.min[2]); const bool z1 = max[2] >= other.min[2];
bool z2 = (min[2] <= other.max[2]); const bool z2 = min[2] <= other.max[2];
return x1 && x2 && y1 && y2 && z1 && z2; return x1 && x2 && y1 && y2 && z1 && z2;
} }
bool intersects(const CSphere& other) const; [[nodiscard]] bool intersects(const CSphere& other) const;
float intersectionRadius(const CSphere& other) const; [[nodiscard]] float intersectionRadius(const CSphere& other) const;
CAABox booleanIntersection(const CAABox& other) const; [[nodiscard]] CAABox booleanIntersection(const CAABox& other) const;
bool inside(const CAABox& other) const { [[nodiscard]] bool inside(const CAABox& other) const {
bool x = min[0] >= other.min[0] && max[0] <= other.max[0]; const bool x = min[0] >= other.min[0] && max[0] <= other.max[0];
bool y = min[1] >= other.min[1] && max[1] <= other.max[1]; const bool y = min[1] >= other.min[1] && max[1] <= other.max[1];
bool z = min[2] >= other.min[2] && max[2] <= other.max[2]; const bool z = min[2] >= other.min[2] && max[2] <= other.max[2];
return x && y && z; return x && y && z;
} }
bool insidePlane(const CPlane& plane) const { [[nodiscard]] bool insidePlane(const CPlane& plane) const {
CVector3f vmax; CVector3f vmax;
/* X axis */ /* X axis */
if (plane.x() >= 0.f) if (plane.x() >= 0.f)
@ -96,16 +96,16 @@ public:
return plane.normal().dot(vmax) + plane.d() >= 0.f; return plane.normal().dot(vmax) + plane.d() >= 0.f;
} }
CVector3f center() const { return (min + max) * 0.5f; } [[nodiscard]] CVector3f center() const { return (min + max) * 0.5f; }
CVector3f extents() const { return (max - min) * 0.5f; } [[nodiscard]] CVector3f extents() const { return (max - min) * 0.5f; }
float volume() const { [[nodiscard]] float volume() const {
auto delta = max - min; const auto delta = max - min;
return delta.x() * delta.y() * delta.z(); return delta.x() * delta.y() * delta.z();
} }
CLineSeg getEdge(EBoxEdgeId id) const { [[nodiscard]] CLineSeg getEdge(EBoxEdgeId id) const {
switch (id) { switch (id) {
case EBoxEdgeId::Z0: case EBoxEdgeId::Z0:
default: default:
@ -139,9 +139,9 @@ public:
zeus::CPlane x0_plane; zeus::CPlane x0_plane;
zeus::CVector3f x10_verts[3]; zeus::CVector3f x10_verts[3];
}; };
Tri getTri(EBoxFaceId face, int windOffset) const; [[nodiscard]] Tri getTri(EBoxFaceId face, int windOffset) const;
CAABox getTransformedAABox(const CTransform& xfrm) const { [[nodiscard]] CAABox getTransformedAABox(const CTransform& xfrm) const {
CAABox box; CAABox box;
CVector3f point = xfrm * getPoint(0); CVector3f point = xfrm * getPoint(0);
box.accumulateBounds(point); box.accumulateBounds(point);
@ -182,22 +182,22 @@ public:
accumulateBounds(other.max); accumulateBounds(other.max);
} }
bool pointInside(const CVector3f& other) const { [[nodiscard]] bool pointInside(const CVector3f& other) const {
return (min.x() <= other.x() && other.x() <= max.x() && min.y() <= other.y() && other.y() <= max.y() && return (min.x() <= other.x() && other.x() <= max.x() && min.y() <= other.y() && other.y() <= max.y() &&
min.z() <= other.z() && other.z() <= max.z()); min.z() <= other.z() && other.z() <= max.z());
} }
CVector3f closestPointAlongVector(const CVector3f& other) const { [[nodiscard]] CVector3f closestPointAlongVector(const CVector3f& other) const {
return {(other.x() >= 0.f ? min.x() : max.x()), (other.y() >= 0.f ? min.y() : max.y()), return {(other.x() >= 0.f ? min.x() : max.x()), (other.y() >= 0.f ? min.y() : max.y()),
(other.z() >= 0.f ? min.z() : max.z())}; (other.z() >= 0.f ? min.z() : max.z())};
} }
CVector3f furthestPointAlongVector(const CVector3f& other) const { [[nodiscard]] CVector3f furthestPointAlongVector(const CVector3f& other) const {
return {(other.x() >= 0.f ? max.x() : min.x()), (other.y() >= 0.f ? max.y() : min.y()), return {(other.x() >= 0.f ? max.x() : min.x()), (other.y() >= 0.f ? max.y() : min.y()),
(other.z() >= 0.f ? max.z() : min.z())}; (other.z() >= 0.f ? max.z() : min.z())};
} }
float distanceBetween(const CAABox& other) { [[nodiscard]] float distanceBetween(const CAABox& other) const {
int intersects = 0; int intersects = 0;
if (max.x() >= other.min.x() && min.x() <= other.max.x()) if (max.x() >= other.min.x() && min.x() <= other.max.x())
intersects |= 0x1; intersects |= 0x1;
@ -254,12 +254,12 @@ public:
} }
} }
CVector3f getPoint(const int point) const { [[nodiscard]] CVector3f getPoint(const int point) const {
const CVector3f* vecs = &min; const CVector3f* vecs = &min;
return CVector3f(vecs[(point & 1) != 0].x(), vecs[(point & 2) != 0].y(), vecs[(point & 4) != 0].z()); return CVector3f(vecs[(point & 1) != 0].x(), vecs[(point & 2) != 0].y(), vecs[(point & 4) != 0].z());
} }
CVector3f clampToBox(const CVector3f& vec) const { [[nodiscard]] CVector3f clampToBox(const CVector3f& vec) const {
CVector3f ret = vec; CVector3f ret = vec;
ret.x() = clamp(min.x(), float(ret.x()), max.x()); ret.x() = clamp(min.x(), float(ret.x()), max.x());
ret.y() = clamp(min.y(), float(ret.y()), max.y()); ret.y() = clamp(min.y(), float(ret.y()), max.y());
@ -267,7 +267,7 @@ public:
return ret; return ret;
} }
bool projectedPointTest(const CMatrix4f& mvp, const CVector2f& point) const; [[nodiscard]] bool projectedPointTest(const CMatrix4f& mvp, const CVector2f& point) const;
void splitX(CAABox& negX, CAABox& posX) const { void splitX(CAABox& negX, CAABox& posX) const {
float midX = (max.x() - min.x()) * .5f + min.x(); float midX = (max.x() - min.x()) * .5f + min.x();
@ -299,9 +299,9 @@ public:
negZ.min = min; negZ.min = min;
} }
bool invalid() { return (max.x() < min.x() || max.y() < min.y() || max.z() < min.z()); } [[nodiscard]] bool invalid() const { return max.x() < min.x() || max.y() < min.y() || max.z() < min.z(); }
float operator[](size_t idx) const { [[nodiscard]] float operator[](size_t idx) const {
assert(idx < 6); assert(idx < 6);
if (idx < 3) if (idx < 3)
return min[idx]; return min[idx];
@ -312,11 +312,11 @@ public:
constexpr CAABox skInvertedBox; constexpr CAABox skInvertedBox;
constexpr CAABox skNullBox(CVector3f{}, CVector3f{}); constexpr CAABox skNullBox(CVector3f{}, CVector3f{});
inline bool operator==(const CAABox& left, const CAABox& right) { [[nodiscard]] inline bool operator==(const CAABox& left, const CAABox& right) {
return (left.min == right.min && left.max == right.max); return (left.min == right.min && left.max == right.max);
} }
inline bool operator!=(const CAABox& left, const CAABox& right) { [[nodiscard]] inline bool operator!=(const CAABox& left, const CAABox& right) {
return (left.min != right.min || left.max != right.max); return (left.min != right.min || left.max != right.max);
} }
} // namespace zeus } // namespace zeus

View File

@ -9,7 +9,8 @@ struct CAxisAngle : CVector3f {
constexpr CAxisAngle(float x, float y, float z) : CVector3f(x, y, z) {} constexpr CAxisAngle(float x, float y, float z) : CVector3f(x, y, z) {}
CAxisAngle(const CUnitVector3f& axis, float angle) : CVector3f(angle * axis) {} CAxisAngle(const CUnitVector3f& axis, float angle) : CVector3f(angle * axis) {}
constexpr CAxisAngle(const CVector3f& axisAngle) : CVector3f(axisAngle) {} constexpr CAxisAngle(const CVector3f& axisAngle) : CVector3f(axisAngle) {}
float angle() const { return magnitude(); }
const CVector3f& getVector() const { return *this; } [[nodiscard]] float angle() const { return magnitude(); }
[[nodiscard]] const CVector3f& getVector() const { return *this; }
}; };
} // namespace zeus } // namespace zeus

View File

@ -76,7 +76,7 @@ public:
#if ZE_ATHENA_TYPES #if ZE_ATHENA_TYPES
static CColor ReadRGBABig(athena::io::IStreamReader& reader) { [[nodiscard]] static CColor ReadRGBABig(athena::io::IStreamReader& reader) {
CColor ret; CColor ret;
ret.readRGBABig(reader); ret.readRGBABig(reader);
return ret; return ret;
@ -126,27 +126,27 @@ public:
#endif #endif
bool operator==(const CColor& rhs) const { [[nodiscard]] bool operator==(const CColor& rhs) const {
return (r() == rhs.r() && g() == rhs.g() && b() == rhs.b() && a() == rhs.a()); return (r() == rhs.r() && g() == rhs.g() && b() == rhs.b() && a() == rhs.a());
} }
bool operator!=(const CColor& rhs) const { return !(*this == rhs); } [[nodiscard]] bool operator!=(const CColor& rhs) const { return !(*this == rhs); }
CColor operator+(const CColor& rhs) const { return CColor(mSimd + rhs.mSimd).Clamp(); } [[nodiscard]] CColor operator+(const CColor& rhs) const { return CColor(mSimd + rhs.mSimd).Clamp(); }
CColor operator-(const CColor& rhs) const { return CColor(mSimd - rhs.mSimd).Clamp(); } [[nodiscard]] CColor operator-(const CColor& rhs) const { return CColor(mSimd - rhs.mSimd).Clamp(); }
CColor operator*(const CColor& rhs) const { return CColor(mSimd * rhs.mSimd).Clamp(); } [[nodiscard]] CColor operator*(const CColor& rhs) const { return CColor(mSimd * rhs.mSimd).Clamp(); }
CColor operator/(const CColor& rhs) const { return CColor(mSimd / rhs.mSimd).Clamp(); } [[nodiscard]] CColor operator/(const CColor& rhs) const { return CColor(mSimd / rhs.mSimd).Clamp(); }
CColor operator+(float val) const { return CColor(mSimd + simd<float>(val)).Clamp(); } [[nodiscard]] CColor operator+(float val) const { return CColor(mSimd + simd<float>(val)).Clamp(); }
CColor operator-(float val) const { return CColor(mSimd - simd<float>(val)).Clamp(); } [[nodiscard]] CColor operator-(float val) const { return CColor(mSimd - simd<float>(val)).Clamp(); }
CColor operator*(float val) const { return CColor(mSimd * simd<float>(val)).Clamp(); } [[nodiscard]] CColor operator*(float val) const { return CColor(mSimd * simd<float>(val)).Clamp(); }
CColor operator/(float val) const { return CColor(mSimd / simd<float>(val)).Clamp(); } [[nodiscard]] CColor operator/(float val) const { return CColor(mSimd / simd<float>(val)).Clamp(); }
const CColor& operator+=(const CColor& rhs) { const CColor& operator+=(const CColor& rhs) {
mSimd += rhs.mSimd; mSimd += rhs.mSimd;
@ -202,28 +202,28 @@ public:
*this *= mag; *this *= mag;
} }
CColor normalized() const { [[nodiscard]] CColor normalized() const {
float mag = magnitude(); float mag = magnitude();
mag = 1.f / mag; mag = 1.f / mag;
return *this * mag; return *this * mag;
} }
float magSquared() const { return mSimd.dot4(mSimd); } [[nodiscard]] float magSquared() const { return mSimd.dot4(mSimd); }
float magnitude() const { return std::sqrt(magSquared()); } [[nodiscard]] float magnitude() const { return std::sqrt(magSquared()); }
static CColor lerp(const CColor& a, const CColor& b, float t) { [[nodiscard]] static CColor lerp(const CColor& a, const CColor& b, float t) {
return zeus::simd<float>(1.f - t) * a.mSimd + b.mSimd * zeus::simd<float>(t); return zeus::simd<float>(1.f - t) * a.mSimd + b.mSimd * zeus::simd<float>(t);
} }
static CColor nlerp(const CColor& a, const CColor& b, float t) { return lerp(a, b, t).normalized(); } [[nodiscard]] static CColor nlerp(const CColor& a, const CColor& b, float t) { return lerp(a, b, t).normalized(); }
simd<float>::reference operator[](const size_t& idx) { [[nodiscard]] simd<float>::reference operator[](const size_t& idx) {
assert(idx < 4); assert(idx < 4);
return mSimd[idx]; return mSimd[idx];
} }
float operator[](const size_t& idx) const { [[nodiscard]] float operator[](const size_t& idx) const {
assert(idx < 4); assert(idx < 4);
return mSimd[idx]; return mSimd[idx];
} }
@ -233,7 +233,7 @@ public:
mSimd[3] = a; mSimd[3] = a;
} }
float rgbDot(const CColor& rhs) const { return mSimd.dot3(rhs.mSimd); } [[nodiscard]] float rgbDot(const CColor& rhs) const { return mSimd.dot3(rhs.mSimd); }
void fromRGBA8(const Comp8 ri, const Comp8 gi, const Comp8 bi, const Comp8 ai) { void fromRGBA8(const Comp8 ri, const Comp8 gi, const Comp8 bi, const Comp8 ai) {
mSimd = simd<float>(ri * OneOver255, gi * OneOver255, bi * OneOver255, ai * OneOver255); mSimd = simd<float>(ri * OneOver255, gi * OneOver255, bi * OneOver255, ai * OneOver255);
@ -280,7 +280,7 @@ public:
void toHSL(float& h, float& s, float& l) const; void toHSL(float& h, float& s, float& l) const;
CColor toGrayscale() const { return {std::sqrt((r() * r() + g() * g() + b() * b()) / 3), a()}; } [[nodiscard]] CColor toGrayscale() const { return {std::sqrt((r() * r() + g() * g() + b() * b()) / 3), a()}; }
/** /**
* @brief Clamps to GPU-safe RGBA values [0,1] * @brief Clamps to GPU-safe RGBA values [0,1]
@ -293,15 +293,15 @@ public:
return *this; return *this;
} }
float r() const { return mSimd[0]; } [[nodiscard]] float r() const { return mSimd[0]; }
float g() const { return mSimd[1]; } [[nodiscard]] float g() const { return mSimd[1]; }
float b() const { return mSimd[2]; } [[nodiscard]] float b() const { return mSimd[2]; }
float a() const { return mSimd[3]; } [[nodiscard]] float a() const { return mSimd[3]; }
simd<float>::reference r() { return mSimd[0]; } [[nodiscard]] simd<float>::reference r() { return mSimd[0]; }
simd<float>::reference g() { return mSimd[1]; } [[nodiscard]] simd<float>::reference g() { return mSimd[1]; }
simd<float>::reference b() { return mSimd[2]; } [[nodiscard]] simd<float>::reference b() { return mSimd[2]; }
simd<float>::reference a() { return mSimd[3]; } [[nodiscard]] simd<float>::reference a() { return mSimd[3]; }
}; };
constexpr CVector4f::CVector4f(const zeus::CColor& other) : mSimd(other.mSimd) {} constexpr CVector4f::CVector4f(const zeus::CColor& other) : mSimd(other.mSimd) {}
@ -323,13 +323,21 @@ constexpr CColor skYellow(1.f, 1.f, 0.f, 1.f);
constexpr CColor skWhite(1.f, 1.f, 1.f, 1.f); constexpr CColor skWhite(1.f, 1.f, 1.f, 1.f);
constexpr CColor skClear(0.f, 0.f, 0.f, 0.f); constexpr CColor skClear(0.f, 0.f, 0.f, 0.f);
inline CColor operator+(float lhs, const CColor& rhs) { return CColor(simd<float>(lhs) + rhs.mSimd).Clamp(); } [[nodiscard]] inline CColor operator+(float lhs, const CColor& rhs) {
return CColor(simd<float>(lhs) + rhs.mSimd).Clamp();
}
inline CColor operator-(float lhs, const CColor& rhs) { return CColor(simd<float>(lhs) - rhs.mSimd).Clamp(); } [[nodiscard]] inline CColor operator-(float lhs, const CColor& rhs) {
return CColor(simd<float>(lhs) - rhs.mSimd).Clamp();
}
inline CColor operator*(float lhs, const CColor& rhs) { return CColor(simd<float>(lhs) * rhs.mSimd).Clamp(); } [[nodiscard]] inline CColor operator*(float lhs, const CColor& rhs) {
return CColor(simd<float>(lhs) * rhs.mSimd).Clamp();
}
inline CColor operator/(float lhs, const CColor& rhs) { return CColor(simd<float>(lhs) / rhs.mSimd).Clamp(); } [[nodiscard]] inline CColor operator/(float lhs, const CColor& rhs) {
return CColor(simd<float>(lhs) / rhs.mSimd).Clamp();
}
} // namespace zeus } // namespace zeus
namespace std { namespace std {

View File

@ -16,8 +16,8 @@ class CFrustum {
public: public:
void updatePlanes(const CMatrix4f& viewMtx, const CMatrix4f& projection); void updatePlanes(const CMatrix4f& viewMtx, const CMatrix4f& projection);
void updatePlanes(const CTransform& viewPointMtx, const CProjection& projection); void updatePlanes(const CTransform& viewPointMtx, const CProjection& projection);
bool aabbFrustumTest(const CAABox& aabb) const; [[nodiscard]] bool aabbFrustumTest(const CAABox& aabb) const;
bool sphereFrustumTest(const CSphere& sphere) const; [[nodiscard]] bool sphereFrustumTest(const CSphere& sphere) const;
bool pointFrustumTest(const CVector3f& point) const; [[nodiscard]] bool pointFrustumTest(const CVector3f& point) const;
}; };
} // namespace zeus } // namespace zeus

View File

@ -17,7 +17,7 @@ struct CMRay {
dir = invLen * delta; dir = invLen * delta;
} }
CMRay getInvUnscaledTransformRay(const CTransform& xfrm) const { [[nodiscard]] CMRay getInvUnscaledTransformRay(const CTransform& xfrm) const {
const CTransform inv = xfrm.inverse(); const CTransform inv = xfrm.inverse();
return CMRay(inv * start, inv * end, length, invLength); return CMRay(inv * start, inv * end, length, invLength);
} }

View File

@ -61,7 +61,7 @@ public:
m[2][2] = input.readFloatBig(); m[2][2] = input.readFloatBig();
} }
static CMatrix3f ReadBig(athena::io::IStreamReader& input) { [[nodiscard]] static CMatrix3f ReadBig(athena::io::IStreamReader& input) {
CMatrix3f ret; CMatrix3f ret;
ret.readBig(input); ret.readBig(input);
return ret; return ret;
@ -73,22 +73,22 @@ public:
CMatrix3f& operator=(const CMatrix3f& other) = default; CMatrix3f& operator=(const CMatrix3f& other) = default;
CVector3f operator*(const CVector3f& other) const { [[nodiscard]] CVector3f operator*(const CVector3f& other) const {
return m[0].mSimd * other.mSimd.shuffle<0, 0, 0, 0>() + m[1].mSimd * other.mSimd.shuffle<1, 1, 1, 1>() + 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[2].mSimd * other.mSimd.shuffle<2, 2, 2, 2>();
} }
CVector3f& operator[](size_t i) { [[nodiscard]] CVector3f& operator[](size_t i) {
assert(i < m.size()); assert(i < m.size());
return m[i]; return m[i];
} }
const CVector3f& operator[](size_t i) const { [[nodiscard]] const CVector3f& operator[](size_t i) const {
assert(i < m.size()); assert(i < m.size());
return m[i]; return m[i];
} }
CMatrix3f orthonormalized() const { [[nodiscard]] CMatrix3f orthonormalized() const {
CMatrix3f ret; CMatrix3f ret;
ret[0] = m[0].normalized(); ret[0] = m[0].normalized();
ret[2] = ret[0].cross(m[1]); ret[2] = ret[0].cross(m[1]);
@ -97,17 +97,19 @@ public:
return ret; return ret;
} }
bool operator==(const CMatrix3f& other) const { [[nodiscard]] bool operator==(const CMatrix3f& other) const {
return m[0] == other.m[0] && m[1] == other.m[1] && m[2] == other.m[2]; return m[0] == other.m[0] && m[1] == other.m[1] && m[2] == other.m[2];
} }
[[nodiscard]] bool operator!=(const CMatrix3f& other) const { return !operator==(other); }
void transpose(); void transpose();
CMatrix3f transposed() const; [[nodiscard]] CMatrix3f transposed() const;
void invert() { *this = inverted(); } void invert() { *this = inverted(); }
CMatrix3f inverted() const; [[nodiscard]] CMatrix3f inverted() const;
void addScaledMatrix(const CMatrix3f& other, float scale) { void addScaledMatrix(const CMatrix3f& other, float scale) {
CVector3f scaleVec(scale); CVector3f scaleVec(scale);
@ -116,28 +118,28 @@ public:
m[2] += other.m[2] * scaleVec; m[2] += other.m[2] * scaleVec;
} }
static CMatrix3f RotateX(float theta) { [[nodiscard]] static CMatrix3f RotateX(float theta) {
float sinT = std::sin(theta); float sinT = std::sin(theta);
float cosT = std::cos(theta); float cosT = std::cos(theta);
return CMatrix3f(simd<float>{1.f, 0.f, 0.f, 0.f}, simd<float>{0.f, cosT, sinT, 0.f}, return CMatrix3f(simd<float>{1.f, 0.f, 0.f, 0.f}, simd<float>{0.f, cosT, sinT, 0.f},
simd<float>{0.f, -sinT, cosT, 0.f}); simd<float>{0.f, -sinT, cosT, 0.f});
} }
static CMatrix3f RotateY(float theta) { [[nodiscard]] static CMatrix3f RotateY(float theta) {
float sinT = std::sin(theta); float sinT = std::sin(theta);
float cosT = std::cos(theta); float cosT = std::cos(theta);
return CMatrix3f(simd<float>{cosT, 0.f, -sinT, 0.f}, simd<float>{0.f, 1.f, 0.f, 0.f}, return CMatrix3f(simd<float>{cosT, 0.f, -sinT, 0.f}, simd<float>{0.f, 1.f, 0.f, 0.f},
simd<float>{sinT, 0.f, cosT, 0.f}); simd<float>{sinT, 0.f, cosT, 0.f});
} }
static CMatrix3f RotateZ(float theta) { [[nodiscard]] static CMatrix3f RotateZ(float theta) {
float sinT = std::sin(theta); float sinT = std::sin(theta);
float cosT = std::cos(theta); float cosT = std::cos(theta);
return CMatrix3f(simd<float>{cosT, sinT, 0.f, 0.f}, simd<float>{-sinT, cosT, 0.f, 0.f}, return CMatrix3f(simd<float>{cosT, sinT, 0.f, 0.f}, simd<float>{-sinT, cosT, 0.f, 0.f},
simd<float>{0.f, 0.f, 1.f, 0.f}); simd<float>{0.f, 0.f, 1.f, 0.f});
} }
float determinant() const { [[nodiscard]] float determinant() const {
return m[1][0] * (m[2][1] * m[0][2] - m[0][1] * m[2][2]) + m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) + return m[1][0] * (m[2][1] * m[0][2] - m[0][1] * m[2][2]) + m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) +
m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]); m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
} }
@ -145,7 +147,7 @@ public:
std::array<CVector3f, 3> m; std::array<CVector3f, 3> m;
}; };
inline CMatrix3f operator*(const CMatrix3f& lhs, const CMatrix3f& rhs) { [[nodiscard]] inline CMatrix3f operator*(const CMatrix3f& lhs, const CMatrix3f& rhs) {
std::array<simd<float>, 3> v; std::array<simd<float>, 3> v;
for (size_t i = 0; i < v.size(); ++i) { for (size_t i = 0; i < v.size(); ++i) {
v[i] = lhs.m[0].mSimd * rhs[i].mSimd.shuffle<0, 0, 0, 0>() + lhs.m[1].mSimd * rhs[i].mSimd.shuffle<1, 1, 1, 1>() + v[i] = lhs.m[0].mSimd * rhs[i].mSimd.shuffle<0, 0, 0, 0>() + lhs.m[1].mSimd * rhs[i].mSimd.shuffle<1, 1, 1, 1>() +

View File

@ -51,29 +51,29 @@ public:
constexpr CMatrix4f& operator=(const CMatrix4f& other) = default; constexpr CMatrix4f& operator=(const CMatrix4f& other) = default;
CVector4f operator*(const CVector4f& other) const { [[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>() + 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>(); m[2].mSimd * other.mSimd.shuffle<2, 2, 2, 2>() + m[3].mSimd * other.mSimd.shuffle<3, 3, 3, 3>();
} }
CVector4f& operator[](size_t i) { [[nodiscard]] CVector4f& operator[](size_t i) {
assert(i < m.size()); assert(i < m.size());
return m[i]; return m[i];
} }
const CVector4f& operator[](size_t i) const { [[nodiscard]] const CVector4f& operator[](size_t i) const {
assert(i < m.size()); assert(i < m.size());
return m[i]; return m[i];
} }
CMatrix4f transposed() const; [[nodiscard]] CMatrix4f transposed() const;
CVector3f multiplyOneOverW(const CVector3f& point) const { [[nodiscard]] CVector3f multiplyOneOverW(const CVector3f& point) const {
CVector4f xfVec = *this * point; CVector4f xfVec = *this * point;
return xfVec.toVec3f() / xfVec.w(); return xfVec.toVec3f() / xfVec.w();
} }
CVector3f multiplyOneOverW(const CVector3f& point, float& wOut) const { [[nodiscard]] CVector3f multiplyOneOverW(const CVector3f& point, float& wOut) const {
CVector4f xfVec = *this * point; CVector4f xfVec = *this * point;
wOut = xfVec.w(); wOut = xfVec.w();
return xfVec.toVec3f() / xfVec.w(); return xfVec.toVec3f() / xfVec.w();
@ -83,7 +83,7 @@ public:
}; };
extern const CMatrix4f skIdentityMatrix4f; extern const CMatrix4f skIdentityMatrix4f;
inline CMatrix4f operator*(const CMatrix4f& lhs, const CMatrix4f& rhs) { [[nodiscard]] inline CMatrix4f operator*(const CMatrix4f& lhs, const CMatrix4f& rhs) {
std::array<simd<float>, 4> v; std::array<simd<float>, 4> v;
for (size_t i = 0; i < v.size(); ++i) { for (size_t i = 0; i < v.size(); ++i) {
v[i] = lhs.m[0].mSimd * rhs[i].mSimd.shuffle<0, 0, 0, 0>() + lhs.m[1].mSimd * rhs[i].mSimd.shuffle<1, 1, 1, 1>() + v[i] = lhs.m[0].mSimd * rhs[i].mSimd.shuffle<0, 0, 0, 0>() + lhs.m[1].mSimd * rhs[i].mSimd.shuffle<1, 1, 1, 1>() +

View File

@ -18,7 +18,7 @@ public:
extents.readBig(in); extents.readBig(in);
} }
static COBBox ReadBig(athena::io::IStreamReader& in) { [[nodiscard]] static COBBox ReadBig(athena::io::IStreamReader& in) {
COBBox out; COBBox out;
out.readBig(in); out.readBig(in);
return out; return out;
@ -35,17 +35,19 @@ public:
constexpr COBBox(const CTransform& xf, const CVector3f& extents) : transform(xf), extents(extents) {} constexpr COBBox(const CTransform& xf, const CVector3f& extents) : transform(xf), extents(extents) {}
CAABox calculateAABox(const CTransform& worldXf = CTransform()) const; [[nodiscard]] CAABox calculateAABox(const CTransform& worldXf = CTransform()) const;
static COBBox FromAABox(const CAABox& box, const CTransform& xf) { [[nodiscard]] static COBBox FromAABox(const CAABox& box, const CTransform& xf) {
CVector3f center = box.center(); const CVector3f center = box.center();
const CVector3f extents = box.max - center; const CVector3f extents = box.max - center;
const CTransform newXf = xf * CTransform::Translate(center); const CTransform newXf = xf * CTransform::Translate(center);
return COBBox(newXf, extents); return COBBox(newXf, extents);
} }
bool OBBIntersectsBox(const COBBox& other) const; [[nodiscard]] bool OBBIntersectsBox(const COBBox& other) const;
bool AABoxIntersectsBox(const CAABox& other) const { return OBBIntersectsBox(FromAABox(other, CTransform())); } [[nodiscard]] bool AABoxIntersectsBox(const CAABox& other) const {
return OBBIntersectsBox(FromAABox(other, CTransform()));
}
}; };
} // namespace zeus } // namespace zeus

View File

@ -23,9 +23,9 @@ public:
mSimd[3] = displacement; mSimd[3] = displacement;
} }
float clipLineSegment(const CVector3f& a, const CVector3f& b) { [[nodiscard]] float clipLineSegment(const CVector3f& a, const CVector3f& b) {
float mag = (b - a).dot(normal()); const float mag = (b - a).dot(normal());
float dis = (-(y() - d())) / mag; const float dis = (-(y() - d())) / mag;
return clamp(0.0f, dis, 1.0f); return clamp(0.0f, dis, 1.0f);
} }
@ -38,31 +38,31 @@ public:
mSimd[3] = nd * mag; mSimd[3] = nd * mag;
} }
float pointToPlaneDist(const CVector3f& pos) const { return pos.dot(normal()) - d(); } [[nodiscard]] float pointToPlaneDist(const CVector3f& pos) const { return pos.dot(normal()) - d(); }
bool rayPlaneIntersection(const CVector3f& from, const CVector3f& to, CVector3f& point) const; [[nodiscard]] bool rayPlaneIntersection(const CVector3f& from, const CVector3f& to, CVector3f& point) const;
CVector3f normal() const { return mSimd; } [[nodiscard]] CVector3f normal() const { return mSimd; }
zeus::simd<float>::reference operator[](size_t idx) { [[nodiscard]] zeus::simd<float>::reference operator[](size_t idx) {
assert(idx < 4); assert(idx < 4);
return mSimd[idx]; return mSimd[idx];
} }
float operator[](size_t idx) const { [[nodiscard]] float operator[](size_t idx) const {
assert(idx < 4); assert(idx < 4);
return mSimd[idx]; return mSimd[idx];
} }
float x() const { return mSimd[0]; } [[nodiscard]] float x() const { return mSimd[0]; }
float y() const { return mSimd[1]; } [[nodiscard]] float y() const { return mSimd[1]; }
float z() const { return mSimd[2]; } [[nodiscard]] float z() const { return mSimd[2]; }
float d() const { return mSimd[3]; } [[nodiscard]] float d() const { return mSimd[3]; }
simd<float>::reference x() { return mSimd[0]; } [[nodiscard]] simd<float>::reference x() { return mSimd[0]; }
simd<float>::reference y() { return mSimd[1]; } [[nodiscard]] simd<float>::reference y() { return mSimd[1]; }
simd<float>::reference z() { return mSimd[2]; } [[nodiscard]] simd<float>::reference z() { return mSimd[2]; }
simd<float>::reference d() { return mSimd[3]; } [[nodiscard]] simd<float>::reference d() { return mSimd[3]; }
zeus::simd<float> mSimd; zeus::simd<float> mSimd;
}; };

View File

@ -63,9 +63,9 @@ public:
_updateCachedMatrix(); _updateCachedMatrix();
} }
EProjType getType() const { return m_projType; } [[nodiscard]] EProjType getType() const { return m_projType; }
const SProjOrtho& getOrtho() const { [[nodiscard]] const SProjOrtho& getOrtho() const {
#ifndef NDEBUG #ifndef NDEBUG
if (m_projType != EProjType::Orthographic) { if (m_projType != EProjType::Orthographic) {
std::fprintf(stderr, "attempted to access orthographic structure of non-ortho projection"); std::fprintf(stderr, "attempted to access orthographic structure of non-ortho projection");
@ -75,7 +75,7 @@ public:
return m_ortho; return m_ortho;
} }
const SProjPersp& getPersp() const { [[nodiscard]] const SProjPersp& getPersp() const {
#ifndef NDEBUG #ifndef NDEBUG
if (m_projType != EProjType::Perspective) { if (m_projType != EProjType::Perspective) {
std::fprintf(stderr, "attempted to access perspective structure of non-persp projection"); std::fprintf(stderr, "attempted to access perspective structure of non-persp projection");
@ -85,7 +85,7 @@ public:
return m_persp; return m_persp;
} }
const CMatrix4f& getCachedMatrix() const { return m_mtx; } [[nodiscard]] const CMatrix4f& getCachedMatrix() const { return m_mtx; }
protected: protected:
/* Projection type */ /* Projection type */

View File

@ -71,19 +71,19 @@ public:
return *this; return *this;
} }
CQuaternion operator+(const CQuaternion& q) const { return mSimd + q.mSimd; } [[nodiscard]] CQuaternion operator+(const CQuaternion& q) const { return mSimd + q.mSimd; }
CQuaternion operator-(const CQuaternion& q) const { return mSimd - q.mSimd; } [[nodiscard]] CQuaternion operator-(const CQuaternion& q) const { return mSimd - q.mSimd; }
CQuaternion operator*(const CQuaternion& q) const; [[nodiscard]] CQuaternion operator*(const CQuaternion& q) const;
CQuaternion operator/(const CQuaternion& q) const; [[nodiscard]] CQuaternion operator/(const CQuaternion& q) const;
CQuaternion operator*(float scale) const { return mSimd * simd<float>(scale); } [[nodiscard]] CQuaternion operator*(float scale) const { return mSimd * simd<float>(scale); }
CQuaternion operator/(float scale) const { return mSimd / simd<float>(scale); } [[nodiscard]] CQuaternion operator/(float scale) const { return mSimd / simd<float>(scale); }
CQuaternion operator-() const { return -mSimd; } [[nodiscard]] CQuaternion operator-() const { return -mSimd; }
const CQuaternion& operator+=(const CQuaternion& q) { const CQuaternion& operator+=(const CQuaternion& q) {
mSimd += q.mSimd; mSimd += q.mSimd;
@ -107,19 +107,19 @@ public:
return *this; return *this;
} }
float magnitude() const { return std::sqrt(magSquared()); } [[nodiscard]] float magnitude() const { return std::sqrt(magSquared()); }
float magSquared() const { return mSimd.dot4(mSimd); } [[nodiscard]] float magSquared() const { return mSimd.dot4(mSimd); }
void normalize() { *this /= magnitude(); } void normalize() { *this /= magnitude(); }
CQuaternion normalized() const { return *this / magnitude(); } [[nodiscard]] CQuaternion normalized() const { return *this / magnitude(); }
static constexpr simd<float> InvertQuat = {1.f, -1.f, -1.f, -1.f}; static constexpr simd<float> InvertQuat = {1.f, -1.f, -1.f, -1.f};
void invert() { mSimd *= InvertQuat; } void invert() { mSimd *= InvertQuat; }
CQuaternion inverse() const { return mSimd * InvertQuat; } [[nodiscard]] CQuaternion inverse() const { return mSimd * InvertQuat; }
/** /**
* @brief Set the rotation using axis angle notation * @brief Set the rotation using axis angle notation
@ -127,7 +127,7 @@ public:
* @param angle The magnitude of the rotation in radians * @param angle The magnitude of the rotation in radians
* @return * @return
*/ */
static CQuaternion fromAxisAngle(const CUnitVector3f& axis, const CRelAngle& angle) { [[nodiscard]] static CQuaternion fromAxisAngle(const CUnitVector3f& axis, const CRelAngle& angle) {
return CQuaternion(std::cos(angle / 2.f), axis * std::sin(angle / 2.f)); return CQuaternion(std::cos(angle / 2.f), axis * std::sin(angle / 2.f));
} }
@ -137,93 +137,96 @@ public:
void rotateZ(const CRelAngle& angle) { *this *= fromAxisAngle({0.0f, 0.0f, 1.0f}, angle); } void rotateZ(const CRelAngle& angle) { *this *= fromAxisAngle({0.0f, 0.0f, 1.0f}, angle); }
static CVector3f rotate(const CQuaternion& rotation, const CAxisAngle& v) { [[nodiscard]] static CVector3f rotate(const CQuaternion& rotation, const CAxisAngle& v) {
CQuaternion q = rotation * v; CQuaternion q = rotation * v;
q *= rotation.inverse(); q *= rotation.inverse();
return {q.mSimd.shuffle<1, 2, 3, 3>()}; return {q.mSimd.shuffle<1, 2, 3, 3>()};
} }
static CQuaternion lookAt(const CUnitVector3f& source, const CUnitVector3f& dest, const CRelAngle& maxAng); [[nodiscard]] static CQuaternion lookAt(const CUnitVector3f& source, const CUnitVector3f& dest,
const CRelAngle& maxAng);
CVector3f transform(const CVector3f& v) const { [[nodiscard]] CVector3f transform(const CVector3f& v) const {
CQuaternion r(0.f, v); const CQuaternion r(0.f, v);
return (*this * r * inverse()).getImaginary(); return (*this * r * inverse()).getImaginary();
} }
CQuaternion log() const; [[nodiscard]] CQuaternion log() const;
CQuaternion exp() const; [[nodiscard]] CQuaternion exp() const;
CTransform toTransform() const { return CTransform(CMatrix3f(*this)); } [[nodiscard]] CTransform toTransform() const { return CTransform(CMatrix3f(*this)); }
CTransform toTransform(const zeus::CVector3f& origin) const { return CTransform(CMatrix3f(*this), origin); } [[nodiscard]] CTransform toTransform(const zeus::CVector3f& origin) const {
return CTransform(CMatrix3f(*this), origin);
}
float dot(const CQuaternion& rhs) const { return mSimd.dot4(rhs.mSimd); } [[nodiscard]] float dot(const CQuaternion& rhs) const { return mSimd.dot4(rhs.mSimd); }
static CQuaternion lerp(const CQuaternion& a, const CQuaternion& b, double t); [[nodiscard]] static CQuaternion lerp(const CQuaternion& a, const CQuaternion& b, double t);
static CQuaternion slerp(const CQuaternion& a, const CQuaternion& b, double t); [[nodiscard]] static CQuaternion slerp(const CQuaternion& a, const CQuaternion& b, double t);
static CQuaternion slerpShort(const CQuaternion& a, const CQuaternion& b, double t); [[nodiscard]] static CQuaternion slerpShort(const CQuaternion& a, const CQuaternion& b, double t);
static CQuaternion nlerp(const CQuaternion& a, const CQuaternion& b, double t); [[nodiscard]] static CQuaternion nlerp(const CQuaternion& a, const CQuaternion& b, double t);
static CQuaternion shortestRotationArc(const zeus::CVector3f& v0, const zeus::CVector3f& v1); [[nodiscard]] static CQuaternion shortestRotationArc(const zeus::CVector3f& v0, const zeus::CVector3f& v1);
static CQuaternion clampedRotateTo(const zeus::CUnitVector3f& v0, const zeus::CUnitVector3f& v1, [[nodiscard]] static CQuaternion clampedRotateTo(const zeus::CUnitVector3f& v0, const zeus::CUnitVector3f& v1,
const zeus::CRelAngle& angle); const zeus::CRelAngle& angle);
float roll() const { [[nodiscard]] float roll() const {
simd_floats f(mSimd); simd_floats f(mSimd);
return std::asin(-2.f * (f[1] * f[3] - f[0] * f[2])); return std::asin(-2.f * (f[1] * f[3] - f[0] * f[2]));
} }
float pitch() const { [[nodiscard]] float pitch() const {
simd_floats f(mSimd); simd_floats f(mSimd);
return std::atan2(2.f * (f[2] * f[3] + f[0] * f[1]), f[0] * f[0] - f[1] * f[1] - f[2] * f[2] + f[3] * f[3]); return std::atan2(2.f * (f[2] * f[3] + f[0] * f[1]), f[0] * f[0] - f[1] * f[1] - f[2] * f[2] + f[3] * f[3]);
} }
float yaw() const { [[nodiscard]] float yaw() const {
simd_floats f(mSimd); simd_floats f(mSimd);
return std::atan2(2.f * (f[1] * f[2] + f[0] * f[3]), f[0] * f[0] + f[1] * f[1] - f[2] * f[2] - f[3] * f[3]); return std::atan2(2.f * (f[1] * f[2] + f[0] * f[3]), f[0] * f[0] + f[1] * f[1] - f[2] * f[2] - f[3] * f[3]);
} }
CQuaternion buildEquivalent() const; [[nodiscard]] CQuaternion buildEquivalent() const;
zeus::CVector3f getImaginary() const { return mSimd.shuffle<1, 2, 3, 3>(); } [[nodiscard]] CVector3f getImaginary() const { return mSimd.shuffle<1, 2, 3, 3>(); }
void setImaginary(const zeus::CVector3f& i) { void setImaginary(const CVector3f& i) {
x() = i.x(); x() = i.x();
y() = i.y(); y() = i.y();
z() = i.z(); z() = i.z();
} }
CRelAngle angleFrom(const zeus::CQuaternion& other) const; [[nodiscard]] CRelAngle angleFrom(const CQuaternion& other) const;
simd<float>::reference operator[](size_t idx) { [[nodiscard]] simd<float>::reference operator[](size_t idx) {
assert(idx < 4); assert(idx < 4);
return mSimd[idx]; return mSimd[idx];
} }
float operator[](size_t idx) const { [[nodiscard]] float operator[](size_t idx) const {
assert(idx < 4); assert(idx < 4);
return mSimd[idx]; return mSimd[idx];
} }
float w() const { return mSimd[0]; } [[nodiscard]] float w() const { return mSimd[0]; }
float x() const { return mSimd[1]; } [[nodiscard]] float x() const { return mSimd[1]; }
float y() const { return mSimd[2]; } [[nodiscard]] float y() const { return mSimd[2]; }
float z() const { return mSimd[3]; } [[nodiscard]] float z() const { return mSimd[3]; }
simd<float>::reference w() { return mSimd[0]; } [[nodiscard]] simd<float>::reference w() { return mSimd[0]; }
simd<float>::reference x() { return mSimd[1]; } [[nodiscard]] simd<float>::reference x() { return mSimd[1]; }
simd<float>::reference y() { return mSimd[2]; } [[nodiscard]] simd<float>::reference y() { return mSimd[2]; }
simd<float>::reference z() { return mSimd[3]; } [[nodiscard]] simd<float>::reference z() { return mSimd[3]; }
simd<float> mSimd; simd<float> mSimd;
static CQuaternion fromNUQuaternion(const CNUQuaternion& q); [[nodiscard]] static CQuaternion fromNUQuaternion(const CNUQuaternion& q);
}; };
/** Non-unit quaternion, no guarantee that it's normalized. /** Non-unit quaternion, no guarantee that it's normalized.
@ -243,52 +246,52 @@ public:
CNUQuaternion(const simd<float>& s) : mSimd(s) {} CNUQuaternion(const simd<float>& s) : mSimd(s) {}
static CNUQuaternion fromAxisAngle(const CUnitVector3f& axis, const CRelAngle& angle) { [[nodiscard]] static CNUQuaternion fromAxisAngle(const CUnitVector3f& axis, const CRelAngle& angle) {
return CNUQuaternion(CQuaternion::fromAxisAngle(axis, angle)); return CNUQuaternion(CQuaternion::fromAxisAngle(axis, angle));
} }
float magnitude() const { return std::sqrt(magSquared()); } [[nodiscard]] float magnitude() const { return std::sqrt(magSquared()); }
float magSquared() const { return mSimd.dot4(mSimd); } [[nodiscard]] float magSquared() const { return mSimd.dot4(mSimd); }
void normalize() { void normalize() {
float magDiv = 1.f / magnitude(); float magDiv = 1.f / magnitude();
mSimd *= magDiv; mSimd *= magDiv;
} }
CNUQuaternion normalized() const { [[nodiscard]] CNUQuaternion normalized() const {
float magDiv = 1.f / magnitude(); float magDiv = 1.f / magnitude();
return mSimd * simd<float>(magDiv); return mSimd * simd<float>(magDiv);
} }
CNUQuaternion operator*(const CNUQuaternion& q) const; [[nodiscard]] CNUQuaternion operator*(const CNUQuaternion& q) const;
CNUQuaternion operator*(float f) const { return mSimd * simd<float>(f); } [[nodiscard]] CNUQuaternion operator*(float f) const { return mSimd * simd<float>(f); }
const CNUQuaternion& operator+=(const CNUQuaternion& q) { const CNUQuaternion& operator+=(const CNUQuaternion& q) {
mSimd += q.mSimd; mSimd += q.mSimd;
return *this; return *this;
} }
zeus::simd<float>::reference operator[](size_t idx) { [[nodiscard]] simd<float>::reference operator[](size_t idx) {
assert(idx < 4); assert(idx < 4);
return mSimd[idx]; return mSimd[idx];
} }
float operator[](size_t idx) const { [[nodiscard]] float operator[](size_t idx) const {
assert(idx < 4); assert(idx < 4);
return mSimd[idx]; return mSimd[idx];
} }
float w() const { return mSimd[0]; } [[nodiscard]] float w() const { return mSimd[0]; }
float x() const { return mSimd[1]; } [[nodiscard]] float x() const { return mSimd[1]; }
float y() const { return mSimd[2]; } [[nodiscard]] float y() const { return mSimd[2]; }
float z() const { return mSimd[3]; } [[nodiscard]] float z() const { return mSimd[3]; }
simd<float>::reference w() { return mSimd[0]; } [[nodiscard]] simd<float>::reference w() { return mSimd[0]; }
simd<float>::reference x() { return mSimd[1]; } [[nodiscard]] simd<float>::reference x() { return mSimd[1]; }
simd<float>::reference y() { return mSimd[2]; } [[nodiscard]] simd<float>::reference y() { return mSimd[2]; }
simd<float>::reference z() { return mSimd[3]; } [[nodiscard]] simd<float>::reference z() { return mSimd[3]; }
simd<float> mSimd; simd<float> mSimd;
}; };
@ -298,11 +301,11 @@ inline CQuaternion CQuaternion::fromNUQuaternion(const CNUQuaternion& q) {
return norm.mSimd; return norm.mSimd;
} }
CQuaternion operator+(float lhs, const CQuaternion& rhs); [[nodiscard]] CQuaternion operator+(float lhs, const CQuaternion& rhs);
CQuaternion operator-(float lhs, const CQuaternion& rhs); [[nodiscard]] CQuaternion operator-(float lhs, const CQuaternion& rhs);
CQuaternion operator*(float lhs, const CQuaternion& rhs); [[nodiscard]] CQuaternion operator*(float lhs, const CQuaternion& rhs);
CNUQuaternion operator*(float lhs, const CNUQuaternion& rhs); [[nodiscard]] CNUQuaternion operator*(float lhs, const CNUQuaternion& rhs);
} // namespace zeus } // namespace zeus

View File

@ -9,7 +9,7 @@ public:
constexpr CRectangle(float x, float y, float w, float h) : position(x, y), size(w, h) {} constexpr CRectangle(float x, float y, float w, float h) : position(x, y), size(w, h) {}
bool contains(const CVector2f& point) const { [[nodiscard]] bool contains(const CVector2f& point) const {
if (point.x() < position.x() || point.x() > position.x() + size.x()) if (point.x() < position.x() || point.x() > position.x() + size.x())
return false; return false;
if (point.y() < position.y() || point.y() > position.y() + size.y()) if (point.y() < position.y() || point.y() > position.y() + size.y())
@ -18,7 +18,7 @@ public:
return true; return true;
} }
bool intersects(const CRectangle& rect) const { [[nodiscard]] bool intersects(const CRectangle& rect) const {
return !(position.x() > rect.position.x() + rect.size.x() || rect.position.x() > position.x() + size.x() || return !(position.x() > rect.position.x() + rect.size.x() || rect.position.x() > position.x() + size.x() ||
position.y() > rect.position.y() + rect.size.y() || rect.position.y() > position.y() + size.y()); position.y() > rect.position.y() + rect.size.y() || rect.position.y() > position.y() + size.y());
} }

View File

@ -12,7 +12,7 @@ class CRelAngle {
float angle = 0.f; float angle = 0.f;
public: public:
static float MakeRelativeAngle(float angle) noexcept { [[nodiscard]] static float MakeRelativeAngle(float angle) noexcept {
float ret = angle - std::trunc(angle / (2.f * M_PIF)) * (2.f * M_PIF); float ret = angle - std::trunc(angle / (2.f * M_PIF)) * (2.f * M_PIF);
if (ret < 0.f) if (ret < 0.f)
ret += 2.f * M_PIF; ret += 2.f * M_PIF;
@ -32,13 +32,13 @@ public:
constexpr CRelAngle& operator=(const CRelAngle& ang) noexcept = default; constexpr CRelAngle& operator=(const CRelAngle& ang) noexcept = default;
constexpr float asDegrees() const noexcept { return radToDeg(angle); } [[nodiscard]] constexpr float asDegrees() const noexcept { return radToDeg(angle); }
constexpr float asRadians() const noexcept { return angle; } [[nodiscard]] constexpr float asRadians() const noexcept { return angle; }
float arcCosine() const noexcept { return std::acos(angle); } [[nodiscard]] float arcCosine() const noexcept { return std::acos(angle); }
static constexpr CRelAngle FromDegrees(float angle) noexcept { [[nodiscard]] static constexpr CRelAngle FromDegrees(float angle) noexcept {
CRelAngle ret; CRelAngle ret;
ret.angle = degToRad(angle); ret.angle = degToRad(angle);
return ret; return ret;
@ -46,9 +46,9 @@ public:
constexpr operator float() const noexcept { return angle; } constexpr operator float() const noexcept { return angle; }
static constexpr CRelAngle FromRadians(float angle) noexcept { return CRelAngle(angle); } [[nodiscard]] static constexpr CRelAngle FromRadians(float angle) noexcept { return CRelAngle(angle); }
constexpr bool operator<(const CRelAngle& other) const noexcept { return angle < other.angle; } [[nodiscard]] constexpr bool operator<(const CRelAngle& other) const noexcept { return angle < other.angle; }
constexpr CRelAngle& operator+=(const CRelAngle& other) noexcept { constexpr CRelAngle& operator+=(const CRelAngle& other) noexcept {
angle += other.angle; angle += other.angle;
@ -92,6 +92,6 @@ public:
void makeRel() noexcept { angle = MakeRelativeAngle(angle); } void makeRel() noexcept { angle = MakeRelativeAngle(angle); }
CRelAngle asRel() const noexcept { return CRelAngle(MakeRelativeAngle(angle)); } [[nodiscard]] CRelAngle asRel() const noexcept { return CRelAngle(MakeRelativeAngle(angle)); }
}; };
} // namespace zeus } // namespace zeus

View File

@ -7,10 +7,10 @@ class CSphere {
public: public:
constexpr CSphere(const CVector3f& position, float radius) : position(position), radius(radius) {} constexpr CSphere(const CVector3f& position, float radius) : position(position), radius(radius) {}
CVector3f getSurfaceNormal(const CVector3f& coord) const { return (coord - position).normalized(); } [[nodiscard]] CVector3f getSurfaceNormal(const CVector3f& coord) const { return (coord - position).normalized(); }
bool intersects(const CSphere& other) const { [[nodiscard]] bool intersects(const CSphere& other) const {
float dist = (position - other.position).magnitude(); const float dist = (position - other.position).magnitude();
return dist < (radius + other.radius); return dist < (radius + other.radius);
} }

View File

@ -37,22 +37,26 @@ public:
constexpr CTransform(const CVector3f& c0, const CVector3f& c1, const CVector3f& c2, const CVector3f& c3) constexpr CTransform(const CVector3f& c0, const CVector3f& c1, const CVector3f& c2, const CVector3f& c3)
: basis(c0, c1, c2), origin(c3) {} : basis(c0, c1, c2), origin(c3) {}
bool operator==(const CTransform& other) const { return origin == other.origin && basis == other.basis; } [[nodiscard]] bool operator==(const CTransform& other) const {
return origin == other.origin && basis == other.basis;
}
CTransform operator*(const CTransform& rhs) const { [[nodiscard]] bool operator!=(const CTransform& other) const { return !operator==(other); }
[[nodiscard]] CTransform operator*(const CTransform& rhs) const {
return CTransform(basis * rhs.basis, origin + (basis * rhs.origin)); return CTransform(basis * rhs.basis, origin + (basis * rhs.origin));
} }
CTransform inverse() const { [[nodiscard]] CTransform inverse() const {
CMatrix3f inv = basis.inverted(); CMatrix3f inv = basis.inverted();
return CTransform(inv, inv * -origin); return CTransform(inv, inv * -origin);
} }
static CTransform Translate(const CVector3f& position) { return {CMatrix3f(), position}; } [[nodiscard]] static CTransform Translate(const CVector3f& position) { return {CMatrix3f(), position}; }
static CTransform Translate(float x, float y, float z) { return Translate({x, y, z}); } [[nodiscard]] static CTransform Translate(float x, float y, float z) { return Translate({x, y, z}); }
CTransform operator+(const CVector3f& other) const { return CTransform(basis, origin + other); } [[nodiscard]] CTransform operator+(const CVector3f& other) const { return CTransform(basis, origin + other); }
CTransform& operator+=(const CVector3f& other) { CTransform& operator+=(const CVector3f& other) {
origin += other; origin += other;
@ -66,25 +70,25 @@ public:
return *this; return *this;
} }
zeus::CVector3f rotate(const CVector3f& vec) const { return basis * vec; } [[nodiscard]] CVector3f rotate(const CVector3f& vec) const { return basis * vec; }
static CTransform RotateX(float theta) { [[nodiscard]] static CTransform RotateX(float theta) {
float sinT = std::sin(theta); const float sinT = std::sin(theta);
float cosT = std::cos(theta); const float cosT = std::cos(theta);
return CTransform(CMatrix3f(simd<float>{1.f, 0.f, 0.f, 0.f}, simd<float>{0.f, cosT, sinT, 0.f}, return CTransform(CMatrix3f(simd<float>{1.f, 0.f, 0.f, 0.f}, simd<float>{0.f, cosT, sinT, 0.f},
simd<float>{0.f, -sinT, cosT, 0.f})); simd<float>{0.f, -sinT, cosT, 0.f}));
} }
static CTransform RotateY(float theta) { [[nodiscard]] static CTransform RotateY(float theta) {
float sinT = std::sin(theta); const float sinT = std::sin(theta);
float cosT = std::cos(theta); const float cosT = std::cos(theta);
return CTransform(CMatrix3f(simd<float>{cosT, 0.f, -sinT, 0.f}, simd<float>{0.f, 1.f, 0.f, 0.f}, return CTransform(CMatrix3f(simd<float>{cosT, 0.f, -sinT, 0.f}, simd<float>{0.f, 1.f, 0.f, 0.f},
simd<float>{sinT, 0.f, cosT, 0.f})); simd<float>{sinT, 0.f, cosT, 0.f}));
} }
static CTransform RotateZ(float theta) { [[nodiscard]] static CTransform RotateZ(float theta) {
float sinT = std::sin(theta); const float sinT = std::sin(theta);
float cosT = std::cos(theta); const float cosT = std::cos(theta);
return CTransform(CMatrix3f(simd<float>{cosT, sinT, 0.f, 0.f}, simd<float>{-sinT, cosT, 0.f, 0.f}, return CTransform(CMatrix3f(simd<float>{cosT, sinT, 0.f, 0.f}, simd<float>{-sinT, cosT, 0.f, 0.f},
simd<float>{0.f, 0.f, 1.f, 0.f})); simd<float>{0.f, 0.f, 1.f, 0.f}));
} }
@ -134,7 +138,7 @@ public:
basis[1] -= b0; basis[1] -= b0;
} }
CVector3f transposeRotate(const CVector3f& in) const { [[nodiscard]] CVector3f transposeRotate(const CVector3f& in) const {
return CVector3f(basis[0].dot(in), basis[1].dot(in), basis[2].dot(in)); return CVector3f(basis[0].dot(in), basis[1].dot(in), basis[2].dot(in));
} }
@ -143,26 +147,26 @@ public:
*this = *this * xfrm; *this = *this * xfrm;
} }
static CTransform Scale(const CVector3f& factor) { [[nodiscard]] static CTransform Scale(const CVector3f& factor) {
return CTransform(CMatrix3f(simd<float>{factor.x(), 0.f, 0.f, 0.f}, simd<float>{0.f, factor.y(), 0.f, 0.f}, return CTransform(CMatrix3f(simd<float>{factor.x(), 0.f, 0.f, 0.f}, simd<float>{0.f, factor.y(), 0.f, 0.f},
simd<float>{0.f, 0.f, factor.z(), 0.f})); simd<float>{0.f, 0.f, factor.z(), 0.f}));
} }
static CTransform Scale(float x, float y, float z) { [[nodiscard]] static CTransform Scale(float x, float y, float z) {
return CTransform( return CTransform(
CMatrix3f(simd<float>{x, 0.f, 0.f, 0.f}, simd<float>{0.f, y, 0.f, 0.f}, simd<float>{0.f, 0.f, z, 0.f})); CMatrix3f(simd<float>{x, 0.f, 0.f, 0.f}, simd<float>{0.f, y, 0.f, 0.f}, simd<float>{0.f, 0.f, z, 0.f}));
} }
static CTransform Scale(float factor) { [[nodiscard]] static CTransform Scale(float factor) {
return CTransform(CMatrix3f(simd<float>{factor, 0.f, 0.f, 0.f}, simd<float>{0.f, factor, 0.f, 0.f}, return CTransform(CMatrix3f(simd<float>{factor, 0.f, 0.f, 0.f}, simd<float>{0.f, factor, 0.f, 0.f},
simd<float>{0.f, 0.f, factor, 0.f})); simd<float>{0.f, 0.f, factor, 0.f}));
} }
CTransform multiplyIgnoreTranslation(const CTransform& rhs) const { [[nodiscard]] CTransform multiplyIgnoreTranslation(const CTransform& rhs) const {
return CTransform(basis * rhs.basis, origin + rhs.origin); return CTransform(basis * rhs.basis, origin + rhs.origin);
} }
CTransform getRotation() const { [[nodiscard]] CTransform getRotation() const {
CTransform ret = *this; CTransform ret = *this;
ret.origin.zeroOut(); ret.origin.zeroOut();
return ret; return ret;
@ -177,11 +181,11 @@ public:
* buildMatrix3f is here for compliance with Retro's Math API * buildMatrix3f is here for compliance with Retro's Math API
* @return The Matrix (Neo, you are the one) * @return The Matrix (Neo, you are the one)
*/ */
const CMatrix3f& buildMatrix3f() const { return basis; } [[nodiscard]] const CMatrix3f& buildMatrix3f() const { return basis; }
CVector3f operator*(const CVector3f& other) const { return origin + basis * other; } [[nodiscard]] CVector3f operator*(const CVector3f& other) const { return origin + basis * other; }
CMatrix4f toMatrix4f() const { [[nodiscard]] CMatrix4f toMatrix4f() const {
CMatrix4f ret(basis[0], basis[1], basis[2], origin); CMatrix4f ret(basis[0], basis[1], basis[2], origin);
ret[0][3] = 0.0f; ret[0][3] = 0.0f;
ret[1][3] = 0.0f; ret[1][3] = 0.0f;
@ -190,11 +194,11 @@ public:
return ret; return ret;
} }
CVector3f upVector() const { return basis.m[2]; } [[nodiscard]] CVector3f upVector() const { return basis.m[2]; }
CVector3f frontVector() const { return basis.m[1]; } [[nodiscard]] CVector3f frontVector() const { return basis.m[1]; }
CVector3f rightVector() const { return basis.m[0]; } [[nodiscard]] CVector3f rightVector() const { return basis.m[0]; }
void orthonormalize() { void orthonormalize() {
basis[0].normalize(); basis[0].normalize();
@ -213,7 +217,7 @@ public:
basis[1][2], basis[2][2], origin[2], 0.f, 0.f, 0.f, 1.f); basis[1][2], basis[2][2], origin[2], 0.f, 0.f, 0.f, 1.f);
} }
static zeus::CTransform MakeRotationsBasedOnY(const CUnitVector3f& uVec) { [[nodiscard]] static CTransform MakeRotationsBasedOnY(const CUnitVector3f& uVec) {
uint32_t i; uint32_t i;
if (uVec.y() < uVec.x() || uVec.z() < uVec.y() || uVec.z() < uVec.x()) if (uVec.y() < uVec.x() || uVec.z() < uVec.y() || uVec.z() < uVec.x())
i = 2; i = 2;
@ -230,13 +234,15 @@ public:
CVector3f origin; CVector3f origin;
}; };
inline CTransform CTransformFromScaleVector(const CVector3f& scale) { return CTransform(CMatrix3f(scale)); } [[nodiscard]] inline CTransform CTransformFromScaleVector(const CVector3f& scale) {
return CTransform(CMatrix3f(scale));
}
CTransform CTransformFromEditorEuler(const CVector3f& eulerVec); [[nodiscard]] CTransform CTransformFromEditorEuler(const CVector3f& eulerVec);
CTransform CTransformFromEditorEulers(const CVector3f& eulerVec, const CVector3f& origin); [[nodiscard]] CTransform CTransformFromEditorEulers(const CVector3f& eulerVec, const CVector3f& origin);
CTransform CTransformFromAxisAngle(const CVector3f& axis, float angle); [[nodiscard]] CTransform CTransformFromAxisAngle(const CVector3f& axis, float angle);
CTransform lookAt(const CVector3f& pos, const CVector3f& lookPos, const CVector3f& up = skUp); [[nodiscard]] CTransform lookAt(const CVector3f& pos, const CVector3f& lookPos, const CVector3f& up = skUp);
} // namespace zeus } // namespace zeus

View File

@ -33,7 +33,7 @@ public:
mSimd[3] = 0.0f; mSimd[3] = 0.0f;
} }
static CVector2f ReadBig(athena::io::IStreamReader& input) { [[nodiscard]] static CVector2f ReadBig(athena::io::IStreamReader& input) {
CVector2f ret; CVector2f ret;
ret.readBig(input); ret.readBig(input);
return ret; return ret;
@ -52,35 +52,47 @@ public:
constexpr CVector2f(float x, float y) : mSimd(x, y, 0.f, 0.f) {} constexpr CVector2f(float x, float y) : mSimd(x, y, 0.f, 0.f) {}
bool operator==(const CVector2f& rhs) const { return mSimd[0] == rhs.mSimd[0] && mSimd[1] == rhs.mSimd[1]; } [[nodiscard]] bool operator==(const CVector2f& rhs) const {
return mSimd[0] == rhs.mSimd[0] && mSimd[1] == rhs.mSimd[1];
}
bool operator!=(const CVector2f& rhs) const { return mSimd[0] != rhs.mSimd[0] || mSimd[1] != rhs.mSimd[1]; } [[nodiscard]] bool operator!=(const CVector2f& rhs) const {
return mSimd[0] != rhs.mSimd[0] || mSimd[1] != rhs.mSimd[1];
}
bool operator<(const CVector2f& rhs) const { return mSimd[0] < rhs.mSimd[0] && mSimd[1] < rhs.mSimd[1]; } [[nodiscard]] bool operator<(const CVector2f& rhs) const {
return mSimd[0] < rhs.mSimd[0] && mSimd[1] < rhs.mSimd[1];
}
bool operator<=(const CVector2f& rhs) const { return mSimd[0] <= rhs.mSimd[0] && mSimd[1] <= rhs.mSimd[1]; } [[nodiscard]] bool operator<=(const CVector2f& rhs) const {
return mSimd[0] <= rhs.mSimd[0] && mSimd[1] <= rhs.mSimd[1];
}
bool operator>(const CVector2f& rhs) const { return mSimd[0] > rhs.mSimd[0] && mSimd[1] > rhs.mSimd[1]; } [[nodiscard]] bool operator>(const CVector2f& rhs) const {
return mSimd[0] > rhs.mSimd[0] && mSimd[1] > rhs.mSimd[1];
}
bool operator>=(const CVector2f& rhs) const { return mSimd[0] >= rhs.mSimd[0] && mSimd[1] >= rhs.mSimd[1]; } [[nodiscard]] bool operator>=(const CVector2f& rhs) const {
return mSimd[0] >= rhs.mSimd[0] && mSimd[1] >= rhs.mSimd[1];
}
CVector2f operator+(const CVector2f& rhs) const { return mSimd + rhs.mSimd; } [[nodiscard]] CVector2f operator+(const CVector2f& rhs) const { return mSimd + rhs.mSimd; }
CVector2f operator-(const CVector2f& rhs) const { return mSimd - rhs.mSimd; } [[nodiscard]] CVector2f operator-(const CVector2f& rhs) const { return mSimd - rhs.mSimd; }
CVector2f operator-() const { return -mSimd; } [[nodiscard]] CVector2f operator-() const { return -mSimd; }
CVector2f operator*(const CVector2f& rhs) const { return mSimd * rhs.mSimd; } [[nodiscard]] CVector2f operator*(const CVector2f& rhs) const { return mSimd * rhs.mSimd; }
CVector2f operator/(const CVector2f& rhs) const { return mSimd / rhs.mSimd; } [[nodiscard]] CVector2f operator/(const CVector2f& rhs) const { return mSimd / rhs.mSimd; }
CVector2f operator+(float val) const { return mSimd + simd<float>(val); } [[nodiscard]] CVector2f operator+(float val) const { return mSimd + simd<float>(val); }
CVector2f operator-(float val) const { return mSimd - simd<float>(val); } [[nodiscard]] CVector2f operator-(float val) const { return mSimd - simd<float>(val); }
CVector2f operator*(float val) const { return mSimd * simd<float>(val); } [[nodiscard]] CVector2f operator*(float val) const { return mSimd * simd<float>(val); }
CVector2f operator/(float val) const { [[nodiscard]] CVector2f operator/(float val) const {
float ooval = 1.f / val; float ooval = 1.f / val;
return mSimd * simd<float>(ooval); return mSimd * simd<float>(ooval);
} }
@ -132,76 +144,78 @@ public:
*this *= CVector2f(mag); *this *= CVector2f(mag);
} }
CVector2f normalized() const { [[nodiscard]] CVector2f normalized() const {
float mag = magnitude(); float mag = magnitude();
mag = 1.f / mag; mag = 1.f / mag;
return *this * mag; return *this * mag;
} }
CVector2f perpendicularVector() const { return {-y(), x()}; } [[nodiscard]] CVector2f perpendicularVector() const { return {-y(), x()}; }
float cross(const CVector2f& rhs) const { return (x() * rhs.y()) - (y() * rhs.x()); } [[nodiscard]] float cross(const CVector2f& rhs) const { return (x() * rhs.y()) - (y() * rhs.x()); }
float dot(const CVector2f& rhs) const { return mSimd.dot2(rhs.mSimd); } [[nodiscard]] float dot(const CVector2f& rhs) const { return mSimd.dot2(rhs.mSimd); }
float magSquared() const { return mSimd.dot2(mSimd); } [[nodiscard]] float magSquared() const { return mSimd.dot2(mSimd); }
float magnitude() const { return std::sqrt(magSquared()); } [[nodiscard]] float magnitude() const { return std::sqrt(magSquared()); }
void zeroOut() { mSimd = zeus::simd<float>(0.f); } void zeroOut() { mSimd = zeus::simd<float>(0.f); }
void splat(float xy) { mSimd = zeus::simd<float>(xy); } void splat(float xy) { mSimd = zeus::simd<float>(xy); }
static float getAngleDiff(const CVector2f& a, const CVector2f& b); [[nodiscard]] static float getAngleDiff(const CVector2f& a, const CVector2f& b);
static CVector2f lerp(const CVector2f& a, const CVector2f& b, float t) { [[nodiscard]] static CVector2f lerp(const CVector2f& a, const CVector2f& b, float t) {
return zeus::simd<float>(1.f - t) * a.mSimd + b.mSimd * zeus::simd<float>(t); return zeus::simd<float>(1.f - t) * a.mSimd + b.mSimd * zeus::simd<float>(t);
} }
static CVector2f nlerp(const CVector2f& a, const CVector2f& b, float t) { return lerp(a, b, t).normalized(); } [[nodiscard]] static CVector2f nlerp(const CVector2f& a, const CVector2f& b, float t) {
return lerp(a, b, t).normalized();
}
static CVector2f slerp(const CVector2f& a, const CVector2f& b, float t); [[nodiscard]] static CVector2f slerp(const CVector2f& a, const CVector2f& b, float t);
bool isNormalized() const { return std::fabs(1.f - magSquared()) < 0.01f; } [[nodiscard]] bool isNormalized() const { return std::fabs(1.f - magSquared()) < 0.01f; }
bool canBeNormalized() const { [[nodiscard]] bool canBeNormalized() const {
if (std::isinf(x()) || std::isinf(y())) if (std::isinf(x()) || std::isinf(y()))
return false; return false;
return std::fabs(x()) >= FLT_EPSILON || std::fabs(y()) >= FLT_EPSILON; return std::fabs(x()) >= FLT_EPSILON || std::fabs(y()) >= FLT_EPSILON;
} }
bool isZero() const { return magSquared() <= FLT_EPSILON; } [[nodiscard]] bool isZero() const { return magSquared() <= FLT_EPSILON; }
bool isEqu(const CVector2f& other, float epsilon = FLT_EPSILON) const { [[nodiscard]] bool isEqu(const CVector2f& other, float epsilon = FLT_EPSILON) const {
const CVector2f diffVec = other - *this; const CVector2f diffVec = other - *this;
return (diffVec.x() <= epsilon && diffVec.y() <= epsilon); return (diffVec.x() <= epsilon && diffVec.y() <= epsilon);
} }
zeus::simd<float>::reference operator[](size_t idx) { [[nodiscard]] simd<float>::reference operator[](size_t idx) {
assert(idx < 2); assert(idx < 2);
return mSimd[idx]; return mSimd[idx];
} }
float operator[](size_t idx) const { [[nodiscard]] float operator[](size_t idx) const {
assert(idx < 2); assert(idx < 2);
return mSimd[idx]; return mSimd[idx];
} }
float x() const { return mSimd[0]; } [[nodiscard]] float x() const { return mSimd[0]; }
float y() const { return mSimd[1]; } [[nodiscard]] float y() const { return mSimd[1]; }
simd<float>::reference x() { return mSimd[0]; } [[nodiscard]] simd<float>::reference x() { return mSimd[0]; }
simd<float>::reference y() { return mSimd[1]; } [[nodiscard]] simd<float>::reference y() { return mSimd[1]; }
}; };
constexpr CVector2f skOne2f(1.f); constexpr CVector2f skOne2f(1.f);
constexpr CVector2f skNegOne2f(-1.f); constexpr CVector2f skNegOne2f(-1.f);
constexpr CVector2f skZero2f(0.f); constexpr CVector2f skZero2f(0.f);
inline CVector2f operator+(float lhs, const CVector2f& rhs) { return zeus::simd<float>(lhs) + rhs.mSimd; } [[nodiscard]] inline CVector2f operator+(float lhs, const CVector2f& rhs) { return zeus::simd<float>(lhs) + rhs.mSimd; }
inline CVector2f operator-(float lhs, const CVector2f& rhs) { return zeus::simd<float>(lhs) - rhs.mSimd; } [[nodiscard]] inline CVector2f operator-(float lhs, const CVector2f& rhs) { return zeus::simd<float>(lhs) - rhs.mSimd; }
inline CVector2f operator*(float lhs, const CVector2f& rhs) { return zeus::simd<float>(lhs) * rhs.mSimd; } [[nodiscard]] inline CVector2f operator*(float lhs, const CVector2f& rhs) { return zeus::simd<float>(lhs) * rhs.mSimd; }
inline CVector2f operator/(float lhs, const CVector2f& rhs) { return zeus::simd<float>(lhs) / rhs.mSimd; } [[nodiscard]] inline CVector2f operator/(float lhs, const CVector2f& rhs) { return zeus::simd<float>(lhs) / rhs.mSimd; }
} // namespace zeus } // namespace zeus

View File

@ -16,17 +16,27 @@ public:
CVector2i(const CVector2f& vec) noexcept : x(int32_t(vec.x())), y(int32_t(vec.y())) {} CVector2i(const CVector2f& vec) noexcept : x(int32_t(vec.x())), y(int32_t(vec.y())) {}
constexpr CVector2f toVec2f() const noexcept { return CVector2f(float(x), float(y)); } [[nodiscard]] constexpr CVector2f toVec2f() const noexcept { return CVector2f(float(x), float(y)); }
constexpr CVector2i operator+(const CVector2i& val) const noexcept { return CVector2i(x + val.x, y + val.y); } [[nodiscard]] constexpr CVector2i operator+(const CVector2i& val) const noexcept {
constexpr CVector2i operator-(const CVector2i& val) const noexcept { return CVector2i(x - val.x, y - val.y); } return CVector2i(x + val.x, y + val.y);
constexpr CVector2i operator*(const CVector2i& val) const noexcept { return CVector2i(x * val.x, y * val.y); } }
constexpr CVector2i operator/(const CVector2i& val) const noexcept { return CVector2i(x / val.x, y / val.y); } [[nodiscard]] constexpr CVector2i operator-(const CVector2i& val) const noexcept {
return CVector2i(x - val.x, y - val.y);
}
[[nodiscard]] constexpr CVector2i operator*(const CVector2i& val) const noexcept {
return CVector2i(x * val.x, y * val.y);
}
[[nodiscard]] constexpr CVector2i operator/(const CVector2i& val) const noexcept {
return CVector2i(x / val.x, y / val.y);
}
constexpr bool operator==(const CVector2i& other) const noexcept { return x == other.x && y == other.y; } [[nodiscard]] constexpr bool operator==(const CVector2i& other) const noexcept {
constexpr bool operator!=(const CVector2i& other) const noexcept { return !operator==(other); } return x == other.x && y == other.y;
}
[[nodiscard]] constexpr bool operator!=(const CVector2i& other) const noexcept { return !operator==(other); }
constexpr CVector2i operator*(int32_t val) const noexcept { return CVector2i(x * val, y * val); } [[nodiscard]] constexpr CVector2i operator*(int32_t val) const noexcept { return CVector2i(x * val, y * val); }
}; };
static_assert(sizeof(CVector2i) == sizeof(int32_t) * 2); static_assert(sizeof(CVector2i) == sizeof(int32_t) * 2);

View File

@ -29,19 +29,19 @@ public:
constexpr CVector3d(double x, double y, double z) : mSimd(x, y, z) {} constexpr CVector3d(double x, double y, double z) : mSimd(x, y, z) {}
CVector3f asCVector3f() const { return mSimd; } [[nodiscard]] CVector3f asCVector3f() const { return mSimd; }
double magSquared() const { return mSimd.dot3(mSimd); } [[nodiscard]] double magSquared() const { return mSimd.dot3(mSimd); }
double magnitude() const { return sqrt(magSquared()); } [[nodiscard]] double magnitude() const { return sqrt(magSquared()); }
CVector3d cross(const CVector3d& rhs) const { [[nodiscard]] CVector3d cross(const CVector3d& rhs) const {
return {y() * rhs.z() - z() * rhs.y(), z() * rhs.x() - x() * rhs.z(), x() * rhs.y() - y() * rhs.x()}; return {y() * rhs.z() - z() * rhs.y(), z() * rhs.x() - x() * rhs.z(), x() * rhs.y() - y() * rhs.x()};
} }
double dot(const CVector3d& rhs) const { return mSimd.dot3(rhs.mSimd); } [[nodiscard]] double dot(const CVector3d& rhs) const { return mSimd.dot3(rhs.mSimd); }
CVector3d asNormalized() const { [[nodiscard]] CVector3d asNormalized() const {
double mag = magnitude(); double mag = magnitude();
mag = 1.0 / mag; mag = 1.0 / mag;
return mSimd * zeus::simd<double>(mag); return mSimd * zeus::simd<double>(mag);
@ -51,42 +51,50 @@ public:
void zeroOut() { mSimd = zeus::simd<double>(0.0); } void zeroOut() { mSimd = zeus::simd<double>(0.0); }
CVector3d operator+(const CVector3d& rhs) const { return mSimd + rhs.mSimd; } [[nodiscard]] CVector3d operator+(const CVector3d& rhs) const { return mSimd + rhs.mSimd; }
CVector3d operator-(const CVector3d& rhs) const { return mSimd - rhs.mSimd; } [[nodiscard]] CVector3d operator-(const CVector3d& rhs) const { return mSimd - rhs.mSimd; }
CVector3d operator*(const CVector3d& rhs) const { return mSimd * rhs.mSimd; } [[nodiscard]] CVector3d operator*(const CVector3d& rhs) const { return mSimd * rhs.mSimd; }
CVector3d operator/(const CVector3d& rhs) const { return mSimd / rhs.mSimd; } [[nodiscard]] CVector3d operator/(const CVector3d& rhs) const { return mSimd / rhs.mSimd; }
zeus::simd<double>::reference operator[](size_t idx) { [[nodiscard]] simd<double>::reference operator[](size_t idx) {
assert(idx < 3); assert(idx < 3);
return mSimd[idx]; return mSimd[idx];
} }
double operator[](size_t idx) const { [[nodiscard]] double operator[](size_t idx) const {
assert(idx < 3); assert(idx < 3);
return mSimd[idx]; return mSimd[idx];
} }
double x() const { return mSimd[0]; } [[nodiscard]] double x() const { return mSimd[0]; }
double y() const { return mSimd[1]; } [[nodiscard]] double y() const { return mSimd[1]; }
double z() const { return mSimd[2]; } [[nodiscard]] double z() const { return mSimd[2]; }
simd<double>::reference x() { return mSimd[0]; } [[nodiscard]] simd<double>::reference x() { return mSimd[0]; }
simd<double>::reference y() { return mSimd[1]; } [[nodiscard]] simd<double>::reference y() { return mSimd[1]; }
simd<double>::reference z() { return mSimd[2]; } [[nodiscard]] simd<double>::reference z() { return mSimd[2]; }
}; };
inline CVector3f::CVector3f(const CVector3d& vec) : mSimd(vec.mSimd) {} inline CVector3f::CVector3f(const CVector3d& vec) : mSimd(vec.mSimd) {}
constexpr CVector3d skZero3d(0.0); constexpr CVector3d skZero3d(0.0);
inline CVector3d operator+(double lhs, const CVector3d& rhs) { return zeus::simd<double>(lhs) + rhs.mSimd; } [[nodiscard]] inline CVector3d operator+(double lhs, const CVector3d& rhs) {
return zeus::simd<double>(lhs) + rhs.mSimd;
}
inline CVector3d operator-(double lhs, const CVector3d& rhs) { return zeus::simd<double>(lhs) - rhs.mSimd; } [[nodiscard]] inline CVector3d operator-(double lhs, const CVector3d& rhs) {
return zeus::simd<double>(lhs) - rhs.mSimd;
}
inline CVector3d operator*(double lhs, const CVector3d& rhs) { return zeus::simd<double>(lhs) * rhs.mSimd; } [[nodiscard]] inline CVector3d operator*(double lhs, const CVector3d& rhs) {
return zeus::simd<double>(lhs) * rhs.mSimd;
}
inline CVector3d operator/(double lhs, const CVector3d& rhs) { return zeus::simd<double>(lhs) / rhs.mSimd; } [[nodiscard]] inline CVector3d operator/(double lhs, const CVector3d& rhs) {
return zeus::simd<double>(lhs) / rhs.mSimd;
}
} // namespace zeus } // namespace zeus

View File

@ -41,7 +41,7 @@ public:
mSimd.copy_from(f); mSimd.copy_from(f);
} }
static CVector3f ReadBig(athena::io::IStreamReader& input) { [[nodiscard]] static CVector3f ReadBig(athena::io::IStreamReader& input) {
CVector3f ret; CVector3f ret;
ret.readBig(input); ret.readBig(input);
return ret; return ret;
@ -65,32 +65,32 @@ public:
mSimd[3] = 0.f; mSimd[3] = 0.f;
} }
CVector2f toVec2f() const { return CVector2f(mSimd); } [[nodiscard]] CVector2f toVec2f() const { return CVector2f(mSimd); }
bool operator==(const CVector3f& rhs) const { [[nodiscard]] bool operator==(const CVector3f& rhs) const {
return mSimd[0] == rhs.mSimd[0] && mSimd[1] == rhs.mSimd[1] && mSimd[2] == rhs.mSimd[2]; return mSimd[0] == rhs.mSimd[0] && mSimd[1] == rhs.mSimd[1] && mSimd[2] == rhs.mSimd[2];
} }
bool operator!=(const CVector3f& rhs) const { return !(*this == rhs); } [[nodiscard]] bool operator!=(const CVector3f& rhs) const { return !(*this == rhs); }
CVector3f operator+(const CVector3f& rhs) const { return mSimd + rhs.mSimd; } [[nodiscard]] CVector3f operator+(const CVector3f& rhs) const { return mSimd + rhs.mSimd; }
CVector3f operator-(const CVector3f& rhs) const { return mSimd - rhs.mSimd; } [[nodiscard]] CVector3f operator-(const CVector3f& rhs) const { return mSimd - rhs.mSimd; }
CVector3f operator-() const { return -mSimd; } [[nodiscard]] CVector3f operator-() const { return -mSimd; }
CVector3f operator*(const CVector3f& rhs) const { return mSimd * rhs.mSimd; } [[nodiscard]] CVector3f operator*(const CVector3f& rhs) const { return mSimd * rhs.mSimd; }
CVector3f operator/(const CVector3f& rhs) const { return mSimd / rhs.mSimd; } [[nodiscard]] CVector3f operator/(const CVector3f& rhs) const { return mSimd / rhs.mSimd; }
CVector3f operator+(float val) const { return mSimd + zeus::simd<float>(val); } [[nodiscard]] CVector3f operator+(float val) const { return mSimd + zeus::simd<float>(val); }
CVector3f operator-(float val) const { return mSimd - zeus::simd<float>(val); } [[nodiscard]] CVector3f operator-(float val) const { return mSimd - zeus::simd<float>(val); }
CVector3f operator*(float val) const { return mSimd * zeus::simd<float>(val); } [[nodiscard]] CVector3f operator*(float val) const { return mSimd * zeus::simd<float>(val); }
CVector3f operator/(float val) const { [[nodiscard]] CVector3f operator/(float val) const {
float ooval = 1.f / val; const float ooval = 1.f / val;
return mSimd * zeus::simd<float>(ooval); return mSimd * zeus::simd<float>(ooval);
} }
@ -119,48 +119,50 @@ public:
*this *= CVector3f(mag); *this *= CVector3f(mag);
} }
CVector3f normalized() const { [[nodiscard]] CVector3f normalized() const {
float mag = 1.f / magnitude(); float mag = 1.f / magnitude();
return *this * mag; return *this * mag;
} }
CVector3f cross(const CVector3f& rhs) const { [[nodiscard]] CVector3f cross(const CVector3f& rhs) const {
return CVector3f(y() * rhs.z() - z() * rhs.y(), z() * rhs.x() - x() * rhs.z(), x() * rhs.y() - y() * rhs.x()); return CVector3f(y() * rhs.z() - z() * rhs.y(), z() * rhs.x() - x() * rhs.z(), x() * rhs.y() - y() * rhs.x());
} }
float dot(const CVector3f& rhs) const { return mSimd.dot3(rhs.mSimd); } [[nodiscard]] float dot(const CVector3f& rhs) const { return mSimd.dot3(rhs.mSimd); }
float magSquared() const { return mSimd.dot3(mSimd); } [[nodiscard]] float magSquared() const { return mSimd.dot3(mSimd); }
float magnitude() const { return std::sqrt(magSquared()); } [[nodiscard]] float magnitude() const { return std::sqrt(magSquared()); }
bool isNotInf() const { return !(std::isinf(x()) || std::isinf(y()) || std::isinf(z())); } [[nodiscard]] bool isNotInf() const { return !(std::isinf(x()) || std::isinf(y()) || std::isinf(z())); }
bool isMagnitudeSafe() const { return isNotInf() && magSquared() >= 9.9999994e-29; } [[nodiscard]] bool isMagnitudeSafe() const { return isNotInf() && magSquared() >= 9.9999994e-29; }
void zeroOut() { mSimd = zeus::simd<float>(0.f); } void zeroOut() { mSimd = zeus::simd<float>(0.f); }
void splat(float xyz) { mSimd = zeus::simd<float>(xyz); } void splat(float xyz) { mSimd = zeus::simd<float>(xyz); }
static float getAngleDiff(const CVector3f& a, const CVector3f& b); [[nodiscard]] static float getAngleDiff(const CVector3f& a, const CVector3f& b);
static CVector3f lerp(const CVector3f& a, const CVector3f& b, float t) { [[nodiscard]] static CVector3f lerp(const CVector3f& a, const CVector3f& b, float t) {
return zeus::simd<float>(1.f - t) * a.mSimd + b.mSimd * zeus::simd<float>(t); return zeus::simd<float>(1.f - t) * a.mSimd + b.mSimd * zeus::simd<float>(t);
} }
static CVector3f nlerp(const CVector3f& a, const CVector3f& b, float t) { return lerp(a, b, t).normalized(); } [[nodiscard]] static CVector3f nlerp(const CVector3f& a, const CVector3f& b, float t) {
return lerp(a, b, t).normalized();
}
static CVector3f slerp(const CVector3f& a, const CVector3f& b, CRelAngle clampAngle); [[nodiscard]] static CVector3f slerp(const CVector3f& a, const CVector3f& b, CRelAngle clampAngle);
bool isNormalized() const { return std::fabs(1.f - magSquared()) <= FLT_EPSILON; } [[nodiscard]] bool isNormalized() const { return std::fabs(1.f - magSquared()) <= FLT_EPSILON; }
bool canBeNormalized() const { [[nodiscard]] bool canBeNormalized() const {
if (std::isinf(x()) || std::isinf(y()) || std::isinf(z())) if (std::isinf(x()) || std::isinf(y()) || std::isinf(z()))
return false; return false;
return !(std::fabs(x()) < FLT_EPSILON && std::fabs(y()) < FLT_EPSILON && std::fabs(z()) < FLT_EPSILON); return !(std::fabs(x()) < FLT_EPSILON && std::fabs(y()) < FLT_EPSILON && std::fabs(z()) < FLT_EPSILON);
} }
bool isZero() const { return magSquared() <= FLT_EPSILON; } [[nodiscard]] bool isZero() const { return magSquared() <= FLT_EPSILON; }
void scaleToLength(float newLength) { void scaleToLength(float newLength) {
float length = magSquared(); float length = magSquared();
@ -174,38 +176,38 @@ public:
*this *= CVector3f(scalar); *this *= CVector3f(scalar);
} }
CVector3f scaledToLength(float newLength) const { [[nodiscard]] CVector3f scaledToLength(float newLength) const {
CVector3f v = *this; CVector3f v = *this;
v.scaleToLength(newLength); v.scaleToLength(newLength);
return v; return v;
} }
bool isEqu(const CVector3f& other, float epsilon = FLT_EPSILON) const { [[nodiscard]] bool isEqu(const CVector3f& other, float epsilon = FLT_EPSILON) const {
const CVector3f diffVec = other - *this; const CVector3f diffVec = other - *this;
return (diffVec.x() <= epsilon && diffVec.y() <= epsilon && diffVec.z() <= epsilon); return (diffVec.x() <= epsilon && diffVec.y() <= epsilon && diffVec.z() <= epsilon);
} }
zeus::simd<float>::reference operator[](size_t idx) { [[nodiscard]] simd<float>::reference operator[](size_t idx) {
assert(idx < 3); assert(idx < 3);
return mSimd[idx]; return mSimd[idx];
} }
float operator[](size_t idx) const { [[nodiscard]] float operator[](size_t idx) const {
assert(idx < 3); assert(idx < 3);
return mSimd[idx]; return mSimd[idx];
} }
float x() const { return mSimd[0]; } [[nodiscard]] float x() const { return mSimd[0]; }
float y() const { return mSimd[1]; } [[nodiscard]] float y() const { return mSimd[1]; }
float z() const { return mSimd[2]; } [[nodiscard]] float z() const { return mSimd[2]; }
simd<float>::reference x() { return mSimd[0]; } [[nodiscard]] simd<float>::reference x() { return mSimd[0]; }
simd<float>::reference y() { return mSimd[1]; } [[nodiscard]] simd<float>::reference y() { return mSimd[1]; }
simd<float>::reference z() { return mSimd[2]; } [[nodiscard]] simd<float>::reference z() { return mSimd[2]; }
static inline CVector3f radToDeg(const CVector3f& rad); [[nodiscard]] static inline CVector3f radToDeg(const CVector3f& rad);
static inline CVector3f degToRad(const CVector3f& deg); [[nodiscard]] static inline CVector3f degToRad(const CVector3f& deg);
}; };
constexpr CVector3f skOne3f(1.f); constexpr CVector3f skOne3f(1.f);
constexpr CVector3f skNegOne3f(-1.f); constexpr CVector3f skNegOne3f(-1.f);
@ -219,13 +221,13 @@ constexpr CVector3f skDown(0.f, 0.f, -1.f);
constexpr CVector3f skRadToDegVec(180.f / M_PIF); constexpr CVector3f skRadToDegVec(180.f / M_PIF);
constexpr CVector3f skDegToRadVec(M_PIF / 180.f); constexpr CVector3f skDegToRadVec(M_PIF / 180.f);
inline CVector3f operator+(float lhs, const CVector3f& rhs) { return zeus::simd<float>(lhs) + rhs.mSimd; } [[nodiscard]] inline CVector3f operator+(float lhs, const CVector3f& rhs) { return zeus::simd<float>(lhs) + rhs.mSimd; }
inline CVector3f operator-(float lhs, const CVector3f& rhs) { return zeus::simd<float>(lhs) - rhs.mSimd; } [[nodiscard]] inline CVector3f operator-(float lhs, const CVector3f& rhs) { return zeus::simd<float>(lhs) - rhs.mSimd; }
inline CVector3f operator*(float lhs, const CVector3f& rhs) { return zeus::simd<float>(lhs) * rhs.mSimd; } [[nodiscard]] inline CVector3f operator*(float lhs, const CVector3f& rhs) { return zeus::simd<float>(lhs) * rhs.mSimd; }
inline CVector3f operator/(float lhs, const CVector3f& rhs) { return zeus::simd<float>(lhs) / rhs.mSimd; } [[nodiscard]] inline CVector3f operator/(float lhs, const CVector3f& rhs) { return zeus::simd<float>(lhs) / rhs.mSimd; }
inline CVector3f CVector3f::radToDeg(const CVector3f& rad) { return rad * skRadToDegVec; } inline CVector3f CVector3f::radToDeg(const CVector3f& rad) { return rad * skRadToDegVec; }

View File

@ -52,59 +52,59 @@ public:
CVector4f(const CVector3f& other, float wIn = 1.f) : mSimd(other.mSimd) { mSimd[3] = wIn; } CVector4f(const CVector3f& other, float wIn = 1.f) : mSimd(other.mSimd) { mSimd[3] = wIn; }
static CVector4f ToClip(const zeus::CVector3f& v, float w) { return CVector4f(v * w, w); } [[nodiscard]] static CVector4f ToClip(const zeus::CVector3f& v, float w) { return CVector4f(v * w, w); }
CVector3f toVec3f() const { return CVector3f(mSimd); } [[nodiscard]] CVector3f toVec3f() const { return CVector3f(mSimd); }
constexpr CVector4f& operator=(const CColor& other); constexpr CVector4f& operator=(const CColor& other);
bool operator==(const CVector4f& rhs) const { [[nodiscard]] bool operator==(const CVector4f& rhs) const {
auto eq_mask = mSimd == rhs.mSimd; auto eq_mask = mSimd == rhs.mSimd;
return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3]; return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3];
} }
bool operator!=(const CVector4f& rhs) const { [[nodiscard]] bool operator!=(const CVector4f& rhs) const {
auto eq_mask = mSimd != rhs.mSimd; auto eq_mask = mSimd != rhs.mSimd;
return eq_mask[0] || eq_mask[1] || eq_mask[2] || eq_mask[3]; return eq_mask[0] || eq_mask[1] || eq_mask[2] || eq_mask[3];
} }
bool operator<(const CVector4f& rhs) const { [[nodiscard]] bool operator<(const CVector4f& rhs) const {
auto eq_mask = mSimd < rhs.mSimd; auto eq_mask = mSimd < rhs.mSimd;
return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3]; return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3];
} }
bool operator<=(const CVector4f& rhs) const { [[nodiscard]] bool operator<=(const CVector4f& rhs) const {
auto eq_mask = mSimd <= rhs.mSimd; auto eq_mask = mSimd <= rhs.mSimd;
return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3]; return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3];
} }
bool operator>(const CVector4f& rhs) const { [[nodiscard]] bool operator>(const CVector4f& rhs) const {
auto eq_mask = mSimd > rhs.mSimd; auto eq_mask = mSimd > rhs.mSimd;
return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3]; return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3];
} }
bool operator>=(const CVector4f& rhs) const { [[nodiscard]] bool operator>=(const CVector4f& rhs) const {
auto eq_mask = mSimd >= rhs.mSimd; auto eq_mask = mSimd >= rhs.mSimd;
return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3]; return eq_mask[0] && eq_mask[1] && eq_mask[2] && eq_mask[3];
} }
CVector4f operator+(const CVector4f& rhs) const { return mSimd + rhs.mSimd; } [[nodiscard]] CVector4f operator+(const CVector4f& rhs) const { return mSimd + rhs.mSimd; }
CVector4f operator-(const CVector4f& rhs) const { return mSimd - rhs.mSimd; } [[nodiscard]] CVector4f operator-(const CVector4f& rhs) const { return mSimd - rhs.mSimd; }
CVector4f operator-() const { return -mSimd; } [[nodiscard]] CVector4f operator-() const { return -mSimd; }
CVector4f operator*(const CVector4f& rhs) const { return mSimd * rhs.mSimd; } [[nodiscard]] CVector4f operator*(const CVector4f& rhs) const { return mSimd * rhs.mSimd; }
CVector4f operator/(const CVector4f& rhs) const { return mSimd / rhs.mSimd; } [[nodiscard]] CVector4f operator/(const CVector4f& rhs) const { return mSimd / rhs.mSimd; }
CVector4f operator+(float val) const { return mSimd + zeus::simd<float>(val); } [[nodiscard]] CVector4f operator+(float val) const { return mSimd + zeus::simd<float>(val); }
CVector4f operator-(float val) const { return mSimd - zeus::simd<float>(val); } [[nodiscard]] CVector4f operator-(float val) const { return mSimd - zeus::simd<float>(val); }
CVector4f operator*(float val) const { return mSimd * zeus::simd<float>(val); } [[nodiscard]] CVector4f operator*(float val) const { return mSimd * zeus::simd<float>(val); }
CVector4f operator/(float val) const { [[nodiscard]] CVector4f operator/(float val) const {
float ooval = 1.f / val; float ooval = 1.f / val;
return mSimd * zeus::simd<float>(ooval); return mSimd * zeus::simd<float>(ooval);
} }
@ -135,72 +135,74 @@ public:
*this *= CVector4f(mag); *this *= CVector4f(mag);
} }
CVector4f normalized() const { [[nodiscard]] CVector4f normalized() const {
float mag = magnitude(); float mag = magnitude();
mag = 1.f / mag; mag = 1.f / mag;
return *this * mag; return *this * mag;
} }
float dot(const CVector4f& rhs) const { return mSimd.dot4(rhs.mSimd); } [[nodiscard]] float dot(const CVector4f& rhs) const { return mSimd.dot4(rhs.mSimd); }
float magSquared() const { return mSimd.dot4(mSimd); } [[nodiscard]] float magSquared() const { return mSimd.dot4(mSimd); }
float magnitude() const { return std::sqrt(magSquared()); } [[nodiscard]] float magnitude() const { return std::sqrt(magSquared()); }
void zeroOut() { mSimd = zeus::simd<float>(0.f); } void zeroOut() { mSimd = zeus::simd<float>(0.f); }
void splat(float xyzw) { mSimd = zeus::simd<float>(xyzw); } void splat(float xyzw) { mSimd = zeus::simd<float>(xyzw); }
static CVector4f lerp(const CVector4f& a, const CVector4f& b, float t) { [[nodiscard]] static CVector4f lerp(const CVector4f& a, const CVector4f& b, float t) {
return zeus::simd<float>(1.f - t) * a.mSimd + b.mSimd * zeus::simd<float>(t); return zeus::simd<float>(1.f - t) * a.mSimd + b.mSimd * zeus::simd<float>(t);
} }
static CVector4f nlerp(const CVector4f& a, const CVector4f& b, float t) { return lerp(a, b, t).normalized(); } [[nodiscard]] static CVector4f nlerp(const CVector4f& a, const CVector4f& b, float t) {
return lerp(a, b, t).normalized();
}
bool isNormalized() const { return std::fabs(1.f - magSquared()) < 0.01f; } [[nodiscard]] bool isNormalized() const { return std::fabs(1.f - magSquared()) < 0.01f; }
bool canBeNormalized() const { [[nodiscard]] bool canBeNormalized() const {
if (std::isinf(x()) || std::isinf(y()) || std::isinf(z()) || std::isinf(w())) if (std::isinf(x()) || std::isinf(y()) || std::isinf(z()) || std::isinf(w()))
return false; return false;
return std::fabs(x()) >= FLT_EPSILON || std::fabs(y()) >= FLT_EPSILON || std::fabs(z()) >= FLT_EPSILON || return std::fabs(x()) >= FLT_EPSILON || std::fabs(y()) >= FLT_EPSILON || std::fabs(z()) >= FLT_EPSILON ||
std::fabs(w()) >= FLT_EPSILON; std::fabs(w()) >= FLT_EPSILON;
} }
bool isEqu(const CVector4f& other, float epsilon = FLT_EPSILON) const { [[nodiscard]] bool isEqu(const CVector4f& other, float epsilon = FLT_EPSILON) const {
const CVector4f diffVec = other - *this; const CVector4f diffVec = other - *this;
return (diffVec.x() <= epsilon && diffVec.y() <= epsilon && diffVec.z() <= epsilon && diffVec.w() <= epsilon); return (diffVec.x() <= epsilon && diffVec.y() <= epsilon && diffVec.z() <= epsilon && diffVec.w() <= epsilon);
} }
zeus::simd<float>::reference operator[](size_t idx) { [[nodiscard]] simd<float>::reference operator[](size_t idx) {
assert(idx < 4); assert(idx < 4);
return mSimd[idx]; return mSimd[idx];
} }
float operator[](size_t idx) const { [[nodiscard]] float operator[](size_t idx) const {
assert(idx < 4); assert(idx < 4);
return mSimd[idx]; return mSimd[idx];
} }
float x() const { return mSimd[0]; } [[nodiscard]] float x() const { return mSimd[0]; }
float y() const { return mSimd[1]; } [[nodiscard]] float y() const { return mSimd[1]; }
float z() const { return mSimd[2]; } [[nodiscard]] float z() const { return mSimd[2]; }
float w() const { return mSimd[3]; } [[nodiscard]] float w() const { return mSimd[3]; }
simd<float>::reference x() { return mSimd[0]; } [[nodiscard]] simd<float>::reference x() { return mSimd[0]; }
simd<float>::reference y() { return mSimd[1]; } [[nodiscard]] simd<float>::reference y() { return mSimd[1]; }
simd<float>::reference z() { return mSimd[2]; } [[nodiscard]] simd<float>::reference z() { return mSimd[2]; }
simd<float>::reference w() { return mSimd[3]; } [[nodiscard]] simd<float>::reference w() { return mSimd[3]; }
}; };
constexpr CVector4f skOne4f(1.f); constexpr CVector4f skOne4f(1.f);
constexpr CVector4f skNegOne4f(-1.f); constexpr CVector4f skNegOne4f(-1.f);
constexpr CVector4f skZero4f(0.f); constexpr CVector4f skZero4f(0.f);
inline CVector4f operator+(float lhs, const CVector4f& rhs) { return zeus::simd<float>(lhs) + rhs.mSimd; } [[nodiscard]] inline CVector4f operator+(float lhs, const CVector4f& rhs) { return zeus::simd<float>(lhs) + rhs.mSimd; }
inline CVector4f operator-(float lhs, const CVector4f& rhs) { return zeus::simd<float>(lhs) - rhs.mSimd; } [[nodiscard]] inline CVector4f operator-(float lhs, const CVector4f& rhs) { return zeus::simd<float>(lhs) - rhs.mSimd; }
inline CVector4f operator*(float lhs, const CVector4f& rhs) { return zeus::simd<float>(lhs) * rhs.mSimd; } [[nodiscard]] inline CVector4f operator*(float lhs, const CVector4f& rhs) { return zeus::simd<float>(lhs) * rhs.mSimd; }
inline CVector4f operator/(float lhs, const CVector4f& rhs) { return zeus::simd<float>(lhs) / rhs.mSimd; } [[nodiscard]] inline CVector4f operator/(float lhs, const CVector4f& rhs) { return zeus::simd<float>(lhs) / rhs.mSimd; }
} // namespace zeus } // namespace zeus

View File

@ -68,7 +68,7 @@ void detectCPU();
const CPUInfo& cpuFeatures(); const CPUInfo& cpuFeatures();
std::pair<bool, const CPUInfo&> validateCPU(); [[nodiscard]] std::pair<bool, const CPUInfo&> validateCPU();
void getCpuInfo(int eax, int regs[4]); void getCpuInfo(int eax, int regs[4]);
@ -81,62 +81,64 @@ class CVector2f;
class CTransform; class CTransform;
template <typename T> template <typename T>
constexpr T min(const T& a, const T& b) { [[nodiscard]] constexpr T min(const T& a, const T& b) {
return a < b ? a : b; return a < b ? a : b;
} }
template <typename T> template <typename T>
constexpr T max(const T& a, const T& b) { [[nodiscard]] constexpr T max(const T& a, const T& b) {
return a > b ? a : b; return a > b ? a : b;
} }
template <> template <>
CVector3f min(const CVector3f& a, const CVector3f& b); [[nodiscard]] CVector3f min(const CVector3f& a, const CVector3f& b);
template <> template <>
CVector3f max(const CVector3f& a, const CVector3f& b); [[nodiscard]] CVector3f max(const CVector3f& a, const CVector3f& b);
template <typename T> template <typename T>
constexpr T clamp(const T& a, const T& val, const T& b) { [[nodiscard]] constexpr T clamp(const T& a, const T& val, const T& b) {
return max<T>(a, min<T>(b, val)); return max<T>(a, min<T>(b, val));
} }
inline constexpr float radToDeg(float rad) { return rad * (180.f / M_PIF); } [[nodiscard]] constexpr float radToDeg(float rad) { return rad * (180.f / M_PIF); }
constexpr float degToRad(float deg) { return deg * (M_PIF / 180.f); } [[nodiscard]] constexpr float degToRad(float deg) { return deg * (M_PIF / 180.f); }
constexpr double radToDeg(double rad) { return rad * (180.0 / M_PI); } [[nodiscard]] constexpr double radToDeg(double rad) { return rad * (180.0 / M_PI); }
constexpr double degToRad(double deg) { return deg * (M_PI / 180.0); } [[nodiscard]] constexpr double degToRad(double deg) { return deg * (M_PI / 180.0); }
CVector3f baryToWorld(const CVector3f& p0, const CVector3f& p1, const CVector3f& p2, const CVector3f& bary); [[nodiscard]] CVector3f baryToWorld(const CVector3f& p0, const CVector3f& p1, const CVector3f& p2,
const CVector3f& bary);
CVector3f getBezierPoint(const CVector3f& a, const CVector3f& b, const CVector3f& c, const CVector3f& d, float t); [[nodiscard]] CVector3f getBezierPoint(const CVector3f& a, const CVector3f& b, const CVector3f& c, const CVector3f& d,
float t);
float getCatmullRomSplinePoint(float a, float b, float c, float d, float t); [[nodiscard]] float getCatmullRomSplinePoint(float a, float b, float c, float d, float t);
CVector3f getCatmullRomSplinePoint(const CVector3f& a, const CVector3f& b, const CVector3f& c, const CVector3f& d, [[nodiscard]] CVector3f getCatmullRomSplinePoint(const CVector3f& a, const CVector3f& b, const CVector3f& c,
float t); const CVector3f& d, float t);
CVector3f getRoundCatmullRomSplinePoint(const CVector3f& a, const CVector3f& b, const CVector3f& c, const CVector3f& d, [[nodiscard]] CVector3f getRoundCatmullRomSplinePoint(const CVector3f& a, const CVector3f& b, const CVector3f& c,
float t); const CVector3f& d, float t);
// Since round(double) doesn't exist in some <cmath> implementations // Since round(double) doesn't exist in some <cmath> implementations
// we'll define our own // we'll define our own
inline double round(double val) { return (val < 0.0 ? std::ceil(val - 0.5) : std::ceil(val + 0.5)); } [[nodiscard]] inline double round(double val) { return (val < 0.0 ? std::ceil(val - 0.5) : std::ceil(val + 0.5)); }
inline double powD(float a, float b) { return std::exp(b * std::log(a)); } [[nodiscard]] inline double powD(float a, float b) { return std::exp(b * std::log(a)); }
inline double invSqrtD(double val) { return 1.0 / std::sqrt(val); } [[nodiscard]] inline double invSqrtD(double val) { return 1.0 / std::sqrt(val); }
inline float invSqrtF(float val) { return float(1.0 / std::sqrt(val)); } [[nodiscard]] inline float invSqrtF(float val) { return float(1.0 / std::sqrt(val)); }
int floorPowerOfTwo(int x); [[nodiscard]] int floorPowerOfTwo(int x);
int ceilingPowerOfTwo(int x); [[nodiscard]] int ceilingPowerOfTwo(int x);
template <typename U> template <typename U>
typename std::enable_if<!std::is_enum<U>::value && std::is_integral<U>::value, int>::type PopCount(U x) { [[nodiscard]] typename std::enable_if<!std::is_enum<U>::value && std::is_integral<U>::value, int>::type PopCount(U x) {
#if __GNUC__ >= 4 #if __GNUC__ >= 4
return __builtin_popcountll(x); return __builtin_popcountll(x);
#else #else
@ -153,19 +155,19 @@ typename std::enable_if<!std::is_enum<U>::value && std::is_integral<U>::value, i
} }
template <typename E> template <typename E>
typename std::enable_if<std::is_enum<E>::value, int>::type PopCount(E e) { [[nodiscard]] typename std::enable_if<std::is_enum<E>::value, int>::type PopCount(E e) {
return PopCount(static_cast<typename std::underlying_type<E>::type>(e)); return PopCount(static_cast<typename std::underlying_type<E>::type>(e));
} }
bool close_enough(const CVector3f& a, const CVector3f& b, float epsilon = FLT_EPSILON); [[nodiscard]] bool close_enough(const CVector3f& a, const CVector3f& b, float epsilon = FLT_EPSILON);
bool close_enough(const CVector2f& a, const CVector2f& b, float epsilon = FLT_EPSILON); [[nodiscard]] bool close_enough(const CVector2f& a, const CVector2f& b, float epsilon = FLT_EPSILON);
inline bool close_enough(float a, float b, double 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;
} }
inline bool close_enough(double a, double b, double epsilon = FLT_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 } // namespace zeus