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);
}
static CAABox ReadBoundingBoxBig(athena::io::IStreamReader& in) {
[[nodiscard]] static CAABox ReadBoundingBoxBig(athena::io::IStreamReader& in) {
CAABox ret;
ret.readBoundingBoxBig(in);
return ret;
@ -55,28 +55,28 @@ public:
#endif
bool intersects(const CAABox& other) const {
bool x1 = (max[0] >= other.min[0]);
bool x2 = (min[0] <= other.max[0]);
bool y1 = (max[1] >= other.min[1]);
bool y2 = (min[1] <= other.max[1]);
bool z1 = (max[2] >= other.min[2]);
bool z2 = (min[2] <= other.max[2]);
[[nodiscard]] bool intersects(const CAABox& other) const {
const bool x1 = max[0] >= other.min[0];
const bool x2 = min[0] <= other.max[0];
const bool y1 = max[1] >= other.min[1];
const bool y2 = min[1] <= other.max[1];
const bool z1 = max[2] >= other.min[2];
const bool z2 = min[2] <= other.max[2];
return x1 && x2 && y1 && y2 && z1 && z2;
}
bool intersects(const CSphere& other) const;
float intersectionRadius(const CSphere& other) const;
CAABox booleanIntersection(const CAABox& other) const;
[[nodiscard]] bool intersects(const CSphere& other) const;
[[nodiscard]] float intersectionRadius(const CSphere& other) const;
[[nodiscard]] CAABox booleanIntersection(const CAABox& other) const;
bool inside(const CAABox& other) 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];
bool z = min[2] >= other.min[2] && max[2] <= other.max[2];
[[nodiscard]] bool inside(const CAABox& other) const {
const bool x = min[0] >= other.min[0] && max[0] <= other.max[0];
const bool y = min[1] >= other.min[1] && max[1] <= other.max[1];
const bool z = min[2] >= other.min[2] && max[2] <= other.max[2];
return x && y && z;
}
bool insidePlane(const CPlane& plane) const {
[[nodiscard]] bool insidePlane(const CPlane& plane) const {
CVector3f vmax;
/* X axis */
if (plane.x() >= 0.f)
@ -96,16 +96,16 @@ public:
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 {
auto delta = max - min;
[[nodiscard]] float volume() const {
const auto delta = max - min;
return delta.x() * delta.y() * delta.z();
}
CLineSeg getEdge(EBoxEdgeId id) const {
[[nodiscard]] CLineSeg getEdge(EBoxEdgeId id) const {
switch (id) {
case EBoxEdgeId::Z0:
default:
@ -139,9 +139,9 @@ public:
zeus::CPlane x0_plane;
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;
CVector3f point = xfrm * getPoint(0);
box.accumulateBounds(point);
@ -182,22 +182,22 @@ public:
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() &&
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()),
(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()),
(other.z() >= 0.f ? max.z() : min.z())};
}
float distanceBetween(const CAABox& other) {
[[nodiscard]] float distanceBetween(const CAABox& other) const {
int intersects = 0;
if (max.x() >= other.min.x() && min.x() <= other.max.x())
intersects |= 0x1;
@ -254,12 +254,12 @@ public:
}
}
CVector3f getPoint(const int point) const {
[[nodiscard]] CVector3f getPoint(const int point) const {
const CVector3f* vecs = &min;
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;
ret.x() = clamp(min.x(), float(ret.x()), max.x());
ret.y() = clamp(min.y(), float(ret.y()), max.y());
@ -267,7 +267,7 @@ public:
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 {
float midX = (max.x() - min.x()) * .5f + min.x();
@ -299,9 +299,9 @@ public:
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);
if (idx < 3)
return min[idx];
@ -312,11 +312,11 @@ public:
constexpr CAABox skInvertedBox;
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);
}
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);
}
} // namespace zeus

View File

@ -9,7 +9,8 @@ struct CAxisAngle : CVector3f {
constexpr CAxisAngle(float x, float y, float z) : CVector3f(x, y, z) {}
CAxisAngle(const CUnitVector3f& axis, float angle) : CVector3f(angle * axis) {}
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

View File

@ -76,7 +76,7 @@ public:
#if ZE_ATHENA_TYPES
static CColor ReadRGBABig(athena::io::IStreamReader& reader) {
[[nodiscard]] static CColor ReadRGBABig(athena::io::IStreamReader& reader) {
CColor ret;
ret.readRGBABig(reader);
return ret;
@ -126,27 +126,27 @@ public:
#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());
}
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) {
mSimd += rhs.mSimd;
@ -202,28 +202,28 @@ public:
*this *= mag;
}
CColor normalized() const {
[[nodiscard]] CColor normalized() const {
float mag = magnitude();
mag = 1.f / 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);
}
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);
return mSimd[idx];
}
float operator[](const size_t& idx) const {
[[nodiscard]] float operator[](const size_t& idx) const {
assert(idx < 4);
return mSimd[idx];
}
@ -233,7 +233,7 @@ public:
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) {
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;
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]
@ -293,15 +293,15 @@ public:
return *this;
}
float r() const { return mSimd[0]; }
float g() const { return mSimd[1]; }
float b() const { return mSimd[2]; }
float a() const { return mSimd[3]; }
[[nodiscard]] float r() const { return mSimd[0]; }
[[nodiscard]] float g() const { return mSimd[1]; }
[[nodiscard]] float b() const { return mSimd[2]; }
[[nodiscard]] float a() const { return mSimd[3]; }
simd<float>::reference r() { return mSimd[0]; }
simd<float>::reference g() { return mSimd[1]; }
simd<float>::reference b() { return mSimd[2]; }
simd<float>::reference a() { return mSimd[3]; }
[[nodiscard]] simd<float>::reference r() { return mSimd[0]; }
[[nodiscard]] simd<float>::reference g() { return mSimd[1]; }
[[nodiscard]] simd<float>::reference b() { return mSimd[2]; }
[[nodiscard]] simd<float>::reference a() { return mSimd[3]; }
};
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 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 std {

View File

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

View File

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

View File

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

View File

@ -51,29 +51,29 @@ public:
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>() +
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());
return m[i];
}
const CVector4f& operator[](size_t i) const {
[[nodiscard]] const CVector4f& operator[](size_t i) const {
assert(i < m.size());
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;
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;
wOut = xfVec.w();
return xfVec.toVec3f() / xfVec.w();
@ -83,7 +83,7 @@ public:
};
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;
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>() +

View File

@ -18,7 +18,7 @@ public:
extents.readBig(in);
}
static COBBox ReadBig(athena::io::IStreamReader& in) {
[[nodiscard]] static COBBox ReadBig(athena::io::IStreamReader& in) {
COBBox out;
out.readBig(in);
return out;
@ -35,17 +35,19 @@ public:
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) {
CVector3f center = box.center();
[[nodiscard]] static COBBox FromAABox(const CAABox& box, const CTransform& xf) {
const CVector3f center = box.center();
const CVector3f extents = box.max - center;
const CTransform newXf = xf * CTransform::Translate(center);
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

View File

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

View File

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

View File

@ -71,19 +71,19 @@ public:
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) {
mSimd += q.mSimd;
@ -107,19 +107,19 @@ public:
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(); }
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};
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
@ -127,7 +127,7 @@ public:
* @param angle The magnitude of the rotation in radians
* @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));
}
@ -137,93 +137,96 @@ public:
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;
q *= rotation.inverse();
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 {
CQuaternion r(0.f, v);
[[nodiscard]] CVector3f transform(const CVector3f& v) const {
const CQuaternion r(0.f, v);
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,
const zeus::CRelAngle& angle);
[[nodiscard]] static CQuaternion clampedRotateTo(const zeus::CUnitVector3f& v0, const zeus::CUnitVector3f& v1,
const zeus::CRelAngle& angle);
float roll() const {
[[nodiscard]] float roll() const {
simd_floats f(mSimd);
return std::asin(-2.f * (f[1] * f[3] - f[0] * f[2]));
}
float pitch() const {
[[nodiscard]] float pitch() const {
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]);
}
float yaw() const {
[[nodiscard]] float yaw() const {
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]);
}
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();
y() = i.y();
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);
return mSimd[idx];
}
float operator[](size_t idx) const {
[[nodiscard]] float operator[](size_t idx) const {
assert(idx < 4);
return mSimd[idx];
}
float w() const { return mSimd[0]; }
float x() const { return mSimd[1]; }
float y() const { return mSimd[2]; }
float z() const { return mSimd[3]; }
[[nodiscard]] float w() const { return mSimd[0]; }
[[nodiscard]] float x() const { return mSimd[1]; }
[[nodiscard]] float y() const { return mSimd[2]; }
[[nodiscard]] float z() const { return mSimd[3]; }
simd<float>::reference w() { return mSimd[0]; }
simd<float>::reference x() { return mSimd[1]; }
simd<float>::reference y() { return mSimd[2]; }
simd<float>::reference z() { return mSimd[3]; }
[[nodiscard]] simd<float>::reference w() { return mSimd[0]; }
[[nodiscard]] simd<float>::reference x() { return mSimd[1]; }
[[nodiscard]] simd<float>::reference y() { return mSimd[2]; }
[[nodiscard]] simd<float>::reference z() { return mSimd[3]; }
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.
@ -243,52 +246,52 @@ public:
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));
}
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() {
float magDiv = 1.f / magnitude();
mSimd *= magDiv;
}
CNUQuaternion normalized() const {
[[nodiscard]] CNUQuaternion normalized() const {
float magDiv = 1.f / magnitude();
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) {
mSimd += q.mSimd;
return *this;
}
zeus::simd<float>::reference operator[](size_t idx) {
[[nodiscard]] simd<float>::reference operator[](size_t idx) {
assert(idx < 4);
return mSimd[idx];
}
float operator[](size_t idx) const {
[[nodiscard]] float operator[](size_t idx) const {
assert(idx < 4);
return mSimd[idx];
}
float w() const { return mSimd[0]; }
float x() const { return mSimd[1]; }
float y() const { return mSimd[2]; }
float z() const { return mSimd[3]; }
[[nodiscard]] float w() const { return mSimd[0]; }
[[nodiscard]] float x() const { return mSimd[1]; }
[[nodiscard]] float y() const { return mSimd[2]; }
[[nodiscard]] float z() const { return mSimd[3]; }
simd<float>::reference w() { return mSimd[0]; }
simd<float>::reference x() { return mSimd[1]; }
simd<float>::reference y() { return mSimd[2]; }
simd<float>::reference z() { return mSimd[3]; }
[[nodiscard]] simd<float>::reference w() { return mSimd[0]; }
[[nodiscard]] simd<float>::reference x() { return mSimd[1]; }
[[nodiscard]] simd<float>::reference y() { return mSimd[2]; }
[[nodiscard]] simd<float>::reference z() { return mSimd[3]; }
simd<float> mSimd;
};
@ -298,11 +301,11 @@ inline CQuaternion CQuaternion::fromNUQuaternion(const CNUQuaternion& q) {
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

View File

@ -9,7 +9,7 @@ public:
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())
return false;
if (point.y() < position.y() || point.y() > position.y() + size.y())
@ -18,7 +18,7 @@ public:
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() ||
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;
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);
if (ret < 0.f)
ret += 2.f * M_PIF;
@ -32,13 +32,13 @@ public:
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;
ret.angle = degToRad(angle);
return ret;
@ -46,9 +46,9 @@ public:
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 {
angle += other.angle;
@ -92,6 +92,6 @@ public:
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

View File

@ -7,10 +7,10 @@ class CSphere {
public:
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 {
float dist = (position - other.position).magnitude();
[[nodiscard]] bool intersects(const CSphere& other) const {
const float dist = (position - other.position).magnitude();
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)
: 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));
}
CTransform inverse() const {
[[nodiscard]] CTransform inverse() const {
CMatrix3f inv = basis.inverted();
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) {
origin += other;
@ -66,25 +70,25 @@ public:
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) {
float sinT = std::sin(theta);
float cosT = std::cos(theta);
[[nodiscard]] static CTransform RotateX(float theta) {
const float sinT = std::sin(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},
simd<float>{0.f, -sinT, cosT, 0.f}));
}
static CTransform RotateY(float theta) {
float sinT = std::sin(theta);
float cosT = std::cos(theta);
[[nodiscard]] static CTransform RotateY(float theta) {
const float sinT = std::sin(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},
simd<float>{sinT, 0.f, cosT, 0.f}));
}
static CTransform RotateZ(float theta) {
float sinT = std::sin(theta);
float cosT = std::cos(theta);
[[nodiscard]] static CTransform RotateZ(float theta) {
const float sinT = std::sin(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},
simd<float>{0.f, 0.f, 1.f, 0.f}));
}
@ -134,7 +138,7 @@ public:
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));
}
@ -143,26 +147,26 @@ public:
*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},
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(
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},
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);
}
CTransform getRotation() const {
[[nodiscard]] CTransform getRotation() const {
CTransform ret = *this;
ret.origin.zeroOut();
return ret;
@ -177,11 +181,11 @@ public:
* buildMatrix3f is here for compliance with Retro's Math API
* @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);
ret[0][3] = 0.0f;
ret[1][3] = 0.0f;
@ -190,11 +194,11 @@ public:
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() {
basis[0].normalize();
@ -213,7 +217,7 @@ public:
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;
if (uVec.y() < uVec.x() || uVec.z() < uVec.y() || uVec.z() < uVec.x())
i = 2;
@ -230,13 +234,15 @@ public:
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

View File

@ -33,7 +33,7 @@ public:
mSimd[3] = 0.0f;
}
static CVector2f ReadBig(athena::io::IStreamReader& input) {
[[nodiscard]] static CVector2f ReadBig(athena::io::IStreamReader& input) {
CVector2f ret;
ret.readBig(input);
return ret;
@ -52,35 +52,47 @@ public:
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;
return mSimd * simd<float>(ooval);
}
@ -132,76 +144,78 @@ public:
*this *= CVector2f(mag);
}
CVector2f normalized() const {
[[nodiscard]] CVector2f normalized() const {
float mag = magnitude();
mag = 1.f / 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 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);
}
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()))
return false;
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;
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);
return mSimd[idx];
}
float operator[](size_t idx) const {
[[nodiscard]] float operator[](size_t idx) const {
assert(idx < 2);
return mSimd[idx];
}
float x() const { return mSimd[0]; }
float y() const { return mSimd[1]; }
[[nodiscard]] float x() const { return mSimd[0]; }
[[nodiscard]] float y() const { return mSimd[1]; }
simd<float>::reference x() { return mSimd[0]; }
simd<float>::reference y() { return mSimd[1]; }
[[nodiscard]] simd<float>::reference x() { return mSimd[0]; }
[[nodiscard]] simd<float>::reference y() { return mSimd[1]; }
};
constexpr CVector2f skOne2f(1.f);
constexpr CVector2f skNegOne2f(-1.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

View File

@ -16,17 +16,27 @@ public:
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); }
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); }
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);
}
[[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; }
constexpr bool operator!=(const CVector2i& other) const noexcept { return !operator==(other); }
[[nodiscard]] constexpr bool operator==(const CVector2i& other) const noexcept {
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);

View File

@ -29,19 +29,19 @@ public:
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()};
}
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();
mag = 1.0 / mag;
return mSimd * zeus::simd<double>(mag);
@ -51,42 +51,50 @@ public:
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);
return mSimd[idx];
}
double operator[](size_t idx) const {
[[nodiscard]] double operator[](size_t idx) const {
assert(idx < 3);
return mSimd[idx];
}
double x() const { return mSimd[0]; }
double y() const { return mSimd[1]; }
double z() const { return mSimd[2]; }
[[nodiscard]] double x() const { return mSimd[0]; }
[[nodiscard]] double y() const { return mSimd[1]; }
[[nodiscard]] double z() const { return mSimd[2]; }
simd<double>::reference x() { return mSimd[0]; }
simd<double>::reference y() { return mSimd[1]; }
simd<double>::reference z() { return mSimd[2]; }
[[nodiscard]] simd<double>::reference x() { return mSimd[0]; }
[[nodiscard]] simd<double>::reference y() { return mSimd[1]; }
[[nodiscard]] simd<double>::reference z() { return mSimd[2]; }
};
inline CVector3f::CVector3f(const CVector3d& vec) : mSimd(vec.mSimd) {}
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

View File

@ -41,7 +41,7 @@ public:
mSimd.copy_from(f);
}
static CVector3f ReadBig(athena::io::IStreamReader& input) {
[[nodiscard]] static CVector3f ReadBig(athena::io::IStreamReader& input) {
CVector3f ret;
ret.readBig(input);
return ret;
@ -65,32 +65,32 @@ public:
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];
}
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 {
float ooval = 1.f / val;
[[nodiscard]] CVector3f operator/(float val) const {
const float ooval = 1.f / val;
return mSimd * zeus::simd<float>(ooval);
}
@ -119,48 +119,50 @@ public:
*this *= CVector3f(mag);
}
CVector3f normalized() const {
[[nodiscard]] CVector3f normalized() const {
float mag = 1.f / magnitude();
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());
}
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 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);
}
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()))
return false;
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) {
float length = magSquared();
@ -174,38 +176,38 @@ public:
*this *= CVector3f(scalar);
}
CVector3f scaledToLength(float newLength) const {
[[nodiscard]] CVector3f scaledToLength(float newLength) const {
CVector3f v = *this;
v.scaleToLength(newLength);
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;
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);
return mSimd[idx];
}
float operator[](size_t idx) const {
[[nodiscard]] float operator[](size_t idx) const {
assert(idx < 3);
return mSimd[idx];
}
float x() const { return mSimd[0]; }
float y() const { return mSimd[1]; }
float z() const { return mSimd[2]; }
[[nodiscard]] float x() const { return mSimd[0]; }
[[nodiscard]] float y() const { return mSimd[1]; }
[[nodiscard]] float z() const { return mSimd[2]; }
simd<float>::reference x() { return mSimd[0]; }
simd<float>::reference y() { return mSimd[1]; }
simd<float>::reference z() { return mSimd[2]; }
[[nodiscard]] simd<float>::reference x() { return mSimd[0]; }
[[nodiscard]] simd<float>::reference y() { return mSimd[1]; }
[[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 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 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; }

View File

@ -52,59 +52,59 @@ public:
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);
bool operator==(const CVector4f& rhs) const {
[[nodiscard]] bool operator==(const CVector4f& rhs) const {
auto eq_mask = mSimd == rhs.mSimd;
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;
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;
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;
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;
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;
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;
return mSimd * zeus::simd<float>(ooval);
}
@ -135,72 +135,74 @@ public:
*this *= CVector4f(mag);
}
CVector4f normalized() const {
[[nodiscard]] CVector4f normalized() const {
float mag = magnitude();
mag = 1.f / 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 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);
}
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()))
return false;
return std::fabs(x()) >= FLT_EPSILON || std::fabs(y()) >= FLT_EPSILON || std::fabs(z()) >= 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;
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);
return mSimd[idx];
}
float operator[](size_t idx) const {
[[nodiscard]] float operator[](size_t idx) const {
assert(idx < 4);
return mSimd[idx];
}
float x() const { return mSimd[0]; }
float y() const { return mSimd[1]; }
float z() const { return mSimd[2]; }
float w() const { return mSimd[3]; }
[[nodiscard]] float x() const { return mSimd[0]; }
[[nodiscard]] float y() const { return mSimd[1]; }
[[nodiscard]] float z() const { return mSimd[2]; }
[[nodiscard]] float w() const { return mSimd[3]; }
simd<float>::reference x() { return mSimd[0]; }
simd<float>::reference y() { return mSimd[1]; }
simd<float>::reference z() { return mSimd[2]; }
simd<float>::reference w() { return mSimd[3]; }
[[nodiscard]] simd<float>::reference x() { return mSimd[0]; }
[[nodiscard]] simd<float>::reference y() { return mSimd[1]; }
[[nodiscard]] simd<float>::reference z() { return mSimd[2]; }
[[nodiscard]] simd<float>::reference w() { return mSimd[3]; }
};
constexpr CVector4f skOne4f(1.f);
constexpr CVector4f skNegOne4f(-1.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

View File

@ -68,7 +68,7 @@ void detectCPU();
const CPUInfo& cpuFeatures();
std::pair<bool, const CPUInfo&> validateCPU();
[[nodiscard]] std::pair<bool, const CPUInfo&> validateCPU();
void getCpuInfo(int eax, int regs[4]);
@ -81,62 +81,64 @@ class CVector2f;
class CTransform;
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;
}
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;
}
template <>
CVector3f min(const CVector3f& a, const CVector3f& b);
[[nodiscard]] CVector3f min(const CVector3f& a, const CVector3f& b);
template <>
CVector3f max(const CVector3f& a, const CVector3f& b);
[[nodiscard]] CVector3f max(const CVector3f& a, const CVector3f& b);
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));
}
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,
float t);
[[nodiscard]] CVector3f getCatmullRomSplinePoint(const CVector3f& a, const CVector3f& b, const CVector3f& c,
const CVector3f& d, float t);
CVector3f getRoundCatmullRomSplinePoint(const CVector3f& a, const CVector3f& b, const CVector3f& c, const CVector3f& d,
float t);
[[nodiscard]] CVector3f getRoundCatmullRomSplinePoint(const CVector3f& a, const CVector3f& b, const CVector3f& c,
const CVector3f& d, float t);
// Since round(double) doesn't exist in some <cmath> implementations
// 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>
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
return __builtin_popcountll(x);
#else
@ -153,19 +155,19 @@ typename std::enable_if<!std::is_enum<U>::value && std::is_integral<U>::value, i
}
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));
}
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;
}
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;
}
} // namespace zeus