Merge pull request #3 from AxioDL/retro-reimp

More re-implementations
This commit is contained in:
Phillip 2015-10-07 17:25:00 -07:00
commit c1adc6ef96
36 changed files with 627 additions and 188 deletions

View File

@ -1,3 +1,6 @@
cmake_minimum_required(VERSION 3.0)
project(zeus)
if (NOT DEFINED ATHENA_INCLUDE_DIR)
set(ATHENA_INCLUDE_DIR ../Athena/include)
endif()
@ -22,23 +25,30 @@ add_library(Math
src/CMatrix4f.cpp
src/CAABox.cpp
include/CVector3f.hpp
include/Math.hpp
include/CQuaternion.hpp
include/CMatrix3f.hpp
include/CProjection.hpp
include/CAxisAngle.hpp
include/CRelAngle.hpp
include/CPlane.hpp
include/CTransform.hpp
include/CColor.hpp
include/Global.hpp
include/MathLib.hpp
include/TVectorUnion.hpp
include/CVector2f.hpp
include/CVector3f.hpp
include/CVector3d.hpp
include/CVector4f.hpp
include/CRectangle.hpp
include/CMatrix4f.hpp
include/TVectorUnion.hpp
include/CVector4f.hpp
include/CFrustum.hpp
include/CAABox.hpp
include/COBBox.hpp)
include/COBBox.hpp
include/CLine.hpp
include/CSphere.hpp
include/CUnitVector.hpp)
add_subdirectory(test)

View File

@ -3,25 +3,33 @@
#include "CVector3f.hpp"
#include "CTransform.hpp"
#include "CPlane.hpp"
#include "Math.hpp"
#include <Athena/IStreamReader.hpp>
inline float fsel(float a, float b, float c)
namespace Zeus
{
return (a >= -0.0f) ? b : c;
}
class ZE_ALIGN(16) CAABox
{
public:
ZE_DECLARE_ALIGNED_ALLOCATOR();
enum EBoxEdgeID
{
};
enum EBoxFaceID
{
};
static const CAABox skInvertedBox;
CVector3f m_min;
CVector3f m_max;
// set default AABox to insane inverse min/max to allow for accumulation
inline CAABox()
: m_min(10000000000000000.f), m_max(-10000000000000000.f)
: m_min(1e16f), m_max(-1e16f)
{}
CAABox(const CVector3f& min, const CVector3f& max)
@ -30,12 +38,14 @@ public:
{
}
CAABox(float minX,const float minY,const float& minZ,
float maxX,const float& maxY,const float& maxZ)
CAABox(float minX, float minY, float minZ,
float maxX, float maxY, float maxZ)
: m_min(minX, minY, minZ),
m_max(maxX, maxY, maxZ)
{
}
CAABox(Athena::io::IStreamReader& in) {readBoundingBox(in);}
inline void readBoundingBox(Athena::io::IStreamReader& in)
{
@ -46,26 +56,83 @@ public:
m_max[1] = in.readFloat();
m_max[2] = in.readFloat();
}
CAABox(Athena::io::IStreamReader& in) {readBoundingBox(in);}
inline bool intersects(const CAABox& other) const
{
if (m_max[0] < other.m_min[0]) return false;
if (m_min[0] > other.m_max[0]) return false;
if (m_max[1] < other.m_min[1]) return false;
if (m_min[1] > other.m_max[1]) return false;
if (m_max[2] < other.m_min[2]) return false;
if (m_min[2] > other.m_max[2]) return false;
bool x1 = (m_max[0] < other.m_min[0]);
bool x2 = (m_min[0] > other.m_max[0]);
bool y1 = (m_max[1] < other.m_min[1]);
bool y2 = (m_min[1] > other.m_max[1]);
bool z1 = (m_max[2] < other.m_min[2]);
bool z2 = (m_min[2] > other.m_max[2]);
return x1 && x2 && y1 && y2 && z1 && z2;
}
inline bool inside(const CAABox& other) const
{
bool x = m_min[0] >= other.m_min[0] && m_max[0] <= other.m_max[0];
bool y = m_min[1] >= other.m_min[1] && m_max[1] <= other.m_max[1];
bool z = m_min[2] >= other.m_min[2] && m_max[2] <= other.m_max[2];
return x && y && z;
}
inline bool insidePlane(const CPlane& plane) const
{
CVector3f vmin, vmax;
/* X axis */
if (plane.a >= 0) {
vmin[0] = m_min[0];
vmax[0] = m_max[0];
} else {
vmin[0] = m_max[0];
vmax[0] = m_min[0];
}
/* Y axis */
if (plane.b >= 0) {
vmin[1] = m_min[1];
vmax[1] = m_max[1];
} else {
vmin[1] = m_max[1];
vmax[1] = m_min[1];
}
/* Z axis */
if (plane.c >= 0) {
vmin[2] = m_min[2];
vmax[2] = m_max[2];
} else {
vmin[2] = m_max[2];
vmax[2] = m_min[2];
}
float dadot = plane.vec.dot(vmax);
if (dadot + plane.d < 0)
return false;
return true;
}
CVector3f center() const
CVector3f center() const {return (m_min + m_max) * 0.5f;}
CVector3f volume() const {return (m_max - m_min) * 0.5f;}
inline CAABox getTransformedAABox(const CTransform& xfrm)
{
return (m_min + m_max) * 0.5f;
}
CVector3f extents() const
{
return (m_max - m_min) * 0.5f;
CAABox box;
CVector3f point = xfrm * getPoint(0);
box.accumulateBounds(point);
point = xfrm * getPoint(1);
box.accumulateBounds(point);
point = xfrm * getPoint(2);
box.accumulateBounds(point);
point = xfrm * getPoint(3);
box.accumulateBounds(point);
point = xfrm * getPoint(4);
box.accumulateBounds(point);
point = xfrm * getPoint(5);
box.accumulateBounds(point);
point = xfrm * getPoint(6);
box.accumulateBounds(point);
point = xfrm * getPoint(7);
box.accumulateBounds(point);
return box;
}
inline void accumulateBounds(const CVector3f& point)
@ -76,22 +143,12 @@ public:
m_min.y = point.y;
if (m_min.z > point.z)
m_min.z = point.z;
if (m_max.x < point.x)
m_max.x = point.x;
if (m_max.y < point.y)
m_max.y = point.y;
if (m_max.z < point.z)
m_max.z = point.z;
/*
for (unsigned i = 0; i < 3; i++)
{
if (m_min[i] > point[i])
m_min[i] = point[i];
if (m_max[i] < point[i])
m_max[i] = point[i];
}*/
}
inline bool pointInside(const CVector3f& other) const
@ -103,14 +160,43 @@ public:
inline CVector3f closestPointAlongVector(const CVector3f& other)
{
return {fsel(other.x, m_min.x, m_max.x),
(other.y >= -0.f) ? m_min.y : m_max.y,
(other.z >= -0.f) ? m_min.z : m_max.z};
CVector3f center = this->center();
return {(other.x < center.x ? m_min.x : m_max.x),
(other.y < center.y ? m_min.y : m_max.y),
(other.z < center.z ? m_min.z : m_max.z)};
}
inline CVector3f furthestPointAlongVector(const CVector3f& other)
{
CVector3f center = this->center();
return {(other.x < center.x ? m_max.x : m_min.x),
(other.y < center.y ? m_max.y : m_min.y),
(other.z < center.z ? m_max.z : m_min.z)};
}
inline CVector3f getPoint(const int point)
{
int zOff = point & 4;
int yOff = (point * 2) & 4;
int xOff = (point * 4) & 4;
float z = ((float*)(&m_min.x) + zOff)[2];
float y = ((float*)(&m_min.x) + yOff)[1];
float x = ((float*)(&m_min.x) + xOff)[0];
return CVector3f(x, y, z);
}
inline CVector3f clampToBox(const CVector3f& vec)
{
CVector3f ret = vec;
Math::clamp(m_min.x, ret.x, m_max.x);
Math::clamp(m_min.y, ret.y, m_max.y);
Math::clamp(m_min.z, ret.z, m_max.z);
return ret;
}
inline void splitX(CAABox& posX, CAABox& negX) const
{
float midX = (m_max.x - m_min.x) / 2.0 + m_min.x;
float midX = (m_max.x - m_min.x) * .5 + m_min.x;
posX.m_max = m_max;
posX.m_min = m_min;
posX.m_min.x = midX;
@ -121,7 +207,7 @@ public:
inline void splitY(CAABox& posY, CAABox& negY) const
{
float midY = (m_max.y - m_min.y) / 2.0 + m_min.y;
float midY = (m_max.y - m_min.y) * .5 + m_min.y;
posY.m_max = m_max;
posY.m_min = m_min;
posY.m_min.y = midY;
@ -132,7 +218,7 @@ public:
inline void splitZ(CAABox& posZ, CAABox& negZ) const
{
float midZ = (m_max.z - m_min.z) / 2.0 + m_min.z;
float midZ = (m_max.z - m_min.z) * .5 + m_min.z;
posZ.m_max = m_max;
posZ.m_min = m_min;
posZ.m_min.z = midZ;
@ -140,22 +226,12 @@ public:
negZ.m_max.z = midZ;
negZ.m_min = m_min;
}
inline bool invalid() {return (m_max.x < m_min.x || m_max.y < m_min.y || m_max.z < m_min.z);}
};
inline bool operator ==(const CAABox& left, const CAABox& right)
{
return (left.m_min == right.m_min && left.m_max == right.m_max);
}
inline bool operator !=(const CAABox& left, const CAABox& right)
{
return (left.m_min != right.m_min || left.m_max != right.m_max);
}
inline CAABox operator*(const CTransform& left, const CAABox& right)
{
return {left * (right.m_min - right.m_max), left * (right.m_max - right.m_min)};
inline bool operator ==(const CAABox& left, const CAABox& right) {return (left.m_min == right.m_min && left.m_max == right.m_max);}
inline bool operator !=(const CAABox& left, const CAABox& right) {return (left.m_min != right.m_min || left.m_max != right.m_max);}
}
#endif // CAABOX_HPP

View File

@ -4,6 +4,8 @@
#include "Global.hpp"
#include "CVector3f.hpp"
namespace Zeus
{
struct ZE_ALIGN(16) CAxisAngle
{
ZE_DECLARE_ALIGNED_ALLOCATOR();
@ -20,5 +22,6 @@ struct ZE_ALIGN(16) CAxisAngle
CVector3f axis;
float angle;
};
}
#endif // CAXISANGLE_H

View File

@ -11,7 +11,9 @@
#define COLOR(rgba) rgba
#endif
typedef union _RGBA32
namespace Zeus
{
typedef union
{
struct
{
@ -170,19 +172,19 @@ public:
}
inline void normalize()
{
float mag = length();
float mag = magnitude();
assert(mag != 0.0);
mag = 1.0 / mag;
*this *= mag;
}
inline CColor normalized()
{
float mag = length();
float mag = magnitude();
assert(mag != 0.0);
mag = 1.0 / mag;
return *this * mag;
}
inline float lengthSquared() const
inline float magSquared() const
{
#if __SSE4_1__
TVectorUnion result;
@ -196,9 +198,9 @@ public:
return r * r + g * g + b * b + a * a;
#endif
}
inline float length() const
inline float magnitude() const
{
return sqrtf(lengthSquared());
return sqrtf(magSquared());
}
static inline CColor lerp(const CColor& a, const CColor& b, float t)
{
@ -288,4 +290,6 @@ static inline CColor operator/(float lhs, const CColor& rhs)
#endif
}
}
#endif // CCOLOR_HPP

View File

@ -4,6 +4,8 @@
#include "CPlane.hpp"
#include "CAABox.hpp"
namespace Zeus
{
class CFrustum
{
CPlane m_planes[6];
@ -123,5 +125,5 @@ public:
}
};
}
#endif // CFRUSTUM_HPP

0
include/CLine.hpp Normal file
View File

View File

@ -6,7 +6,8 @@
#include <assert.h>
/* Column-major matrix class */
namespace Zeus
{
class CQuaternion;
class ZE_ALIGN(16) CMatrix3f
{
@ -106,4 +107,6 @@ public:
CMatrix3f operator*(const CMatrix3f& lhs, const CMatrix3f& rhs);
}
#endif // CMATRIX3F_HPP

View File

@ -4,6 +4,8 @@
#include "CVector4f.hpp"
#include "CVector3f.hpp"
namespace Zeus
{
class ZE_ALIGN(16) CMatrix4f
{
public:
@ -178,6 +180,7 @@ static inline CMatrix4f operator*(const CMatrix4f& lhs, const CMatrix4f& rhs)
#endif
return ret;
}
}
#endif // CMATRIX4F

View File

@ -5,9 +5,12 @@
#include "CVector3f.hpp"
#include "CAABox.hpp"
class COBBox
namespace Zeus
{
class ZE_ALIGN(16) COBBox
{
public:
ZE_DECLARE_ALIGNED_ALLOCATOR();
CTransform m_transform;
CVector3f m_extents;
@ -15,7 +18,10 @@ public:
{}
COBBox(const CAABox& aabb)
{ createFromAABox(aabb); }
: m_extents(aabb.volume())
{
m_transform.m_origin = aabb.center();
}
CAABox calculateAABox(const CTransform& transform = CTransform())
{
@ -32,28 +38,27 @@ public:
{-1.0, 1.0, -1.0},
{-1.0, 1.0, 1.0}
};
CVector3f p = m_extents * basis[0];
for (int i = 0; i < 8; i++)
{
CVector3f p = (m_extents * basis[i]);
ret.accumulateBounds(trans * p);
}
ret.accumulateBounds(trans * p);
p = m_extents * basis[1];
ret.accumulateBounds(trans * p);
p = m_extents * basis[2];
ret.accumulateBounds(trans * p);
p = m_extents * basis[3];
ret.accumulateBounds(trans * p);
p = m_extents * basis[4];
ret.accumulateBounds(trans * p);
p = m_extents * basis[5];
ret.accumulateBounds(trans * p);
p = m_extents * basis[6];
ret.accumulateBounds(trans * p);
p = m_extents * basis[7];
ret.accumulateBounds(trans * p);
return ret;
}
void createFromAABox(const CAABox& box)
{
m_extents = box.extents();
m_transform.m_origin = box.center();
}
static inline COBBox fromAABox(const CAABox& box)
{
COBBox ret;
ret.createFromAABox(box);
return box;
}
};
}
#endif

View File

@ -3,7 +3,10 @@
#include "Global.hpp"
#include "CVector3f.hpp"
#include "Math.hpp"
namespace Zeus
{
class ZE_ALIGN(16) CPlane
{
public:
@ -11,6 +14,14 @@ public:
inline CPlane() {}
CPlane(float a, float b, float c, float d) : a(a), b(b), c(c), d(d) {}
CPlane(const CVector3f& a, const CVector3f& b, const CVector3f& c)
{
CVector3f ab = b - a;
CVector3f ac = c - a;
vec = ab.cross(ac).normalized();
d = -a.dot(vec);
}
CPlane(const CVector3f& point, float displacement)
{
#if __SSE__
@ -20,11 +31,18 @@ public:
#endif
d = displacement;
}
float clipLineSegment(const CVector3f& a, const CVector3f& b)
{
float mag = ((b.z - a.z) * (((b.x - a.x) * ((b.y - a.y) * vec.y)) + vec.x)) + vec.z;
float dis = (-(vec.y - d)) / mag;
return Math::clamp(0.0f, dis, 1.0f);
}
inline void normalize()
{
float nd = d;
float mag = vec.length();
float mag = vec.magnitude();
assert(mag != 0.0f);
mag = 1.0 / mag;
vec *= mag;
@ -44,5 +62,6 @@ public:
#endif
};
};
}
#endif // CPLANE_HPP

View File

@ -7,7 +7,8 @@
#define _USE_MATH_DEFINES 1
#include <math.h>
namespace Zeus
{
enum EProjType
{
PROJ_NONE = 0,
@ -110,5 +111,6 @@ protected:
CMatrix4f m_mtx;
};
}
#endif // CMATRIX3F_HPP

View File

@ -8,6 +8,8 @@
#include <math.h>
#include <Athena/IStreamReader.hpp>
namespace Zeus
{
class ZE_ALIGN(16) CQuaternion
{
public:
@ -46,8 +48,8 @@ public:
const CQuaternion& operator*=(const CQuaternion& q);
const CQuaternion& operator*=(float scale);
const CQuaternion& operator/=(float scale);
float length() const;
float lengthSquared() const;
float magnitude() const;
float magSquared() const;
void normalize();
CQuaternion normalized() const;
void invert();
@ -106,4 +108,5 @@ public:
CQuaternion operator+(float lhs, const CQuaternion& rhs);
CQuaternion operator-(float lhs, const CQuaternion& rhs);
CQuaternion operator*(float lhs, const CQuaternion& rhs);
}
#endif // CQUATERNION_HPP

View File

@ -2,6 +2,8 @@
#define CRECTANGLE_HPP
#include "CVector2f.hpp"
namespace Zeus
{
class CRectangle
{
public:
@ -28,5 +30,6 @@ public:
CVector2f position;
CVector2f size;
};
}
#endif // CRECTANGLE_HPP

33
include/CRelAngle.hpp Normal file
View File

@ -0,0 +1,33 @@
#ifndef CRELANGLE_HPP
#define CRELANGLE_HPP
#include "CVector3f.hpp"
#include "Math.hpp"
namespace Zeus
{
/**
* @brief The CRelAngle class represents relative angles in radians
*/
class ZE_ALIGN(16) CRelAngle : public CVector3f
{
public:
/**
* @brief CRelAngle
* @param angles In degrees
*/
CRelAngle(const CVector3f& angles)
{
x = Math::degToRad(angles.x);
y = Math::degToRad(angles.y);
z = Math::degToRad(angles.z);
}
CRelAngle(float x, float y, float z)
: CRelAngle(CVector3f{x, y, z})
{
}
};
}
#endif // CRELANGLE_HPP

28
include/CSphere.hpp Normal file
View File

@ -0,0 +1,28 @@
#ifndef CSPHERE_HPP
#define CSPHERE_HPP
#include "CVector3f.hpp"
namespace Zeus
{
class ZE_ALIGN(16) CSphere
{
public:
ZE_DECLARE_ALIGNED_ALLOCATOR();
CSphere(const CVector3f& position, float radius) { vec = position; r = radius; }
inline CVector3f getSurfaceNormal(const CVector3f& coord) { return (vec - coord).normalized(); }
union
{
struct { float x, y, z, r; };
float s[4];
CVector3f vec;
#if __SSE__
__m128 mVec128;
#endif
};
};
}
#endif

View File

@ -5,7 +5,10 @@
#include "CMatrix3f.hpp"
#include "CMatrix4f.hpp"
#include "CVector3f.hpp"
#include "CQuaternion.hpp"
namespace Zeus
{
class ZE_ALIGN(16) CTransform
{
public:
@ -29,9 +32,41 @@ public:
m_basis = CMatrix3f::skIdentityMatrix3f;
m_origin = position;
}
inline CVector3f operator*(const CVector3f& other) const
{return m_origin + m_basis * other;}
inline void translate(float x, float y, float z) { translate({x, y, z}); }
inline void rotate(const CVector3f& euler) { *this = *this * CMatrix3f(CQuaternion(euler)); }
inline void scaleBy(float factor)
{ CTransform xfrm(CMatrix3f(CVector3f(factor, factor, factor))); *this = *this * xfrm; }
inline void scale(const CVector3f& factor)
{
m_basis = CMatrix3f(true);
m_basis[0][0] = factor.x;
m_basis[1][1] = factor.y;
m_basis[2][2] = factor.z;
m_origin.zeroOut();
}
inline void scale(float x, float y, float z) { scale({x, y, z}); }
inline void scale(float factor) { scale({factor, factor, factor}); }
inline void multiplyIgnoreTranslation(const CTransform& xfrm) { m_basis = m_basis*xfrm.m_basis; }
inline CTransform getRotation() { CTransform ret = *this; ret.m_origin.zeroOut(); return ret; }
void setRotation(const CMatrix3f& mat) { m_basis = mat; }
void setRotation(const CTransform& xfrm) { setRotation(xfrm.m_basis); }
/**
* @brief buildMatrix3f Returns the stored matrix
* buildMatrix3f is here for compliance with Retro's Math API
* @return The Matrix (Neo, you are the one)
*/
inline CMatrix3f buildMatrix3f() { return m_basis; }
inline CVector3f operator*(const CVector3f& other) const {return m_origin + m_basis * other;}
inline void toMatrix4f(CMatrix4f& mat) const
{
@ -48,6 +83,24 @@ public:
#endif
}
static inline CTransform fromColumns(const CVector3f& m0, const CVector3f& m1, const CVector3f& m2, const CVector3f& m3)
{
CTransform ret;
ret.m_basis[0][0] = m0[0];
ret.m_basis[0][1] = m1[0];
ret.m_basis[0][2] = m2[0];
ret.m_origin[0] = m3[0];
ret.m_basis[1][0] = m0[1];
ret.m_basis[1][1] = m1[1];
ret.m_basis[1][2] = m2[1];
ret.m_origin[1] = m3[1];
ret.m_basis[2][0] = m0[2];
ret.m_basis[2][1] = m1[2];
ret.m_basis[2][2] = m2[2];
ret.m_origin[2] = m3[2];
return ret;
}
CMatrix3f m_basis;
CVector3f m_origin;
};
@ -57,6 +110,8 @@ static inline CTransform CTransformFromScaleVector(const CVector3f& scale)
return CTransform(CMatrix3f(scale));
}
CTransform CTransformFromEditorEuler(const CVector3f& eulerVec);
CTransform CTransformFromEditorEulers(const CVector3f& eulerVec, const CVector3f& origin);
CTransform CTransformFromAxisAngle(const CVector3f& axis, float angle);
}
#endif // CTRANSFORM_HPP

21
include/CUnitVector.hpp Normal file
View File

@ -0,0 +1,21 @@
#ifndef CUNITVECTOR_HPP
#define CUNITVECTOR_HPP
#include "CVector3f.hpp"
namespace Zeus
{
class ZE_ALIGN(16) CUnitVector3f : public CVector3f
{
public:
ZE_DECLARE_ALIGNED_ALLOCATOR();
CUnitVector3f(const CVector3f& vec)
: CVector3f(vec)
{
if (canBeNormalized())
normalize();
}
};
}
#endif

View File

@ -8,7 +8,8 @@
#include <math.h>
#include <assert.h>
namespace Zeus
{
class ZE_ALIGN(16) CVector2f
{
public:
@ -197,18 +198,27 @@ class ZE_ALIGN(16) CVector2f
}
inline void normalize()
{
float mag = length();
assert(mag != 0.0);
mag = 1.0 / mag;
*this *= mag;
float mag = magnitude();
if (mag > 1e-6f)
{
mag = 1.0 / mag;
*this *= mag;
}
else
zeroOut();
}
inline CVector2f normalized() const
{
float mag = length();
assert(mag != 0.0);
mag = 1.0 / mag;
return *this * mag;
float mag = magnitude();
if (mag > 1e-6f)
{
mag = 1.0 / mag;
return *this * mag;
}
return {0, 0};
}
inline float cross(const CVector2f& rhs) const
{
return (x * rhs.y) - (y * rhs.x);
@ -227,7 +237,7 @@ class ZE_ALIGN(16) CVector2f
return (x * rhs.x) + (y * rhs.y);
#endif
}
inline float lengthSquared() const
inline float magSquared() const
{
#if __SSE4_1__
TVectorUnion result;
@ -241,9 +251,9 @@ class ZE_ALIGN(16) CVector2f
return x*x + y*y;
#endif
}
inline float length() const
inline float magnitude() const
{
return sqrtf(lengthSquared());
return sqrtf(magSquared());
}
inline void zeroOut()
@ -277,9 +287,14 @@ class ZE_ALIGN(16) CVector2f
}
static CVector2f slerp(const CVector2f& a, const CVector2f& b, float t);
inline bool isNormalized(float thresh = 0.0001f) const
inline bool isNormalized(float thresh = 1e-5f) const
{
return (length() > thresh);
return (fabs(1.0f - magSquared()) <= thresh);
}
inline bool canBeNormalized()
{
return !isNormalized();
}
inline float& operator[](size_t idx) {return (&x)[idx];}
@ -343,5 +358,6 @@ static inline CVector2f operator/(float lhs, const CVector2f& rhs)
return CVector2f(lhs / rhs.x, lhs / rhs.y);
#endif
}
}
#endif // CVECTOR2F_HPP

View File

@ -8,6 +8,8 @@
#include <math.h>
#include <assert.h>
namespace Zeus
{
class ZE_ALIGN(16) CVector3f
{
public:
@ -162,23 +164,29 @@ public:
}
inline void normalize()
{
float mag = length();
assert(mag != 0.0);
mag = 1.0 / mag;
*this *= mag;
float mag = magnitude();
if (mag > 1e-6f)
{
mag = 1.0 / mag;
*this *= mag;
}
else
zeroOut();
}
inline CVector3f normalized() const
{
float mag = length();
assert(mag != 0.0);
mag = 1.0 / mag;
return *this * mag;
float mag = magnitude();
if (mag > 1e-6f)
{
mag = 1.0 / mag;
return *this * mag;
}
return {0, 0, 0};
}
inline 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);
}
inline float dot(const CVector3f& rhs) const
{ return CVector3f(y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x); }
inline float dot(const CVector3f& rhs) const
{
#if __SSE4_1__
TVectorUnion result;
@ -192,7 +200,7 @@ public:
return (x * rhs.x) + (y * rhs.y) + (z * rhs.z);
#endif
}
inline float lengthSquared() const
inline float magSquared() const
{
#if __SSE4_1__
TVectorUnion result;
@ -206,10 +214,8 @@ public:
return x*x + y*y + z*z;
#endif
}
inline float length() const
{
return sqrtf(lengthSquared());
}
inline float magnitude() const
{ return sqrtf(magSquared()); }
inline void zeroOut()
{
@ -233,18 +239,46 @@ public:
static float getAngleDiff(const CVector3f& a, const CVector3f& b);
static inline CVector3f lerp(const CVector3f& a, const CVector3f& b, float t)
{
return (a + (b - a) * t);
}
{ return (a + (b - a) * t); }
static inline CVector3f nlerp(const CVector3f& a, const CVector3f& b, float t)
{
return lerp(a, b, t).normalized();
}
{ return lerp(a, b, t).normalized(); }
static CVector3f slerp(const CVector3f& a, const CVector3f& b, float t);
//static CVector3f slerp(const CVector3f& a, const CVector3f& b, const CRelAngle& angle);
inline bool isNormalized(float thresh = 0.0001f) const
inline bool isNormalized(float thresh = 1e-5f) const
{ return (fabs(1.0f - magSquared()) <= thresh); }
inline bool canBeNormalized()
{ return !isNormalized(); }
inline bool isZero() const
{ return magSquared() <= 1e-7; }
inline void scaleToLength(float newLength)
{
return (length() > thresh);
float length = magSquared();
if (length < 1e-6f)
{
x = newLength, y = 0.f, z = 0.f;
return;
}
length = sqrt(length);
float scalar = newLength / length;
*this *= scalar;
}
inline CVector3f scaledToLength(float newLength) const
{
CVector3f v = *this;
v.scaleToLength(newLength);
return v;
}
inline bool isEqu(const CVector3f& other, float epsilon=1e-7f)
{
CVector3f diffVec = other - *this;
return (diffVec.x <= epsilon && diffVec.y <= epsilon && diffVec.z <= epsilon);
}
inline float& operator[](size_t idx) {return (&x)[idx];}
@ -253,10 +287,7 @@ public:
union
{
struct
{
float x, y, z;
};
struct { float x, y, z; };
float v[4];
#if __SSE__
__m128 mVec128;
@ -308,5 +339,6 @@ static inline CVector3f operator/(float lhs, const CVector3f& rhs)
return CVector3f(lhs / rhs.x, lhs / rhs.y, lhs / rhs.z);
#endif
}
}
#endif // CVECTOR3F_HPP

View File

@ -9,6 +9,8 @@
#include <float.h>
#include <assert.h>
namespace Zeus
{
class ZE_ALIGN(16) CVector4f
{
public:
@ -221,17 +223,24 @@ class ZE_ALIGN(16) CVector4f
}
inline void normalize()
{
float mag = length();
assert(mag != 0.0);
mag = 1.0 / mag;
*this *= mag;
float mag = magnitude();
if (mag > 1e-6f)
{
mag = 1.0 / mag;
*this *= mag;
}
else
zeroOut();
}
inline CVector4f normalized() const
{
float mag = length();
assert(mag != 0.0);
mag = 1.0 / mag;
return *this * mag;
float mag = magnitude();
if (mag > 1e-6f)
{
mag = 1.0 / mag;
return *this * mag;
}
return {0, 0, 0, 0};
}
inline float dot(const CVector4f& rhs) const
@ -248,7 +257,7 @@ class ZE_ALIGN(16) CVector4f
return (x * rhs.x) + (y * rhs.y) + (z * rhs.z) + (w * rhs.w);
#endif
}
inline float lengthSquared() const
inline float magSquared() const
{
#if __SSE4_1__
TVectorUnion result;
@ -262,9 +271,9 @@ class ZE_ALIGN(16) CVector4f
return x*x + y*y + z*z + w*w;
#endif
}
inline float length() const
inline float magnitude() const
{
return sqrtf(lengthSquared());
return sqrtf(magSquared());
}
inline void zeroOut()
@ -295,9 +304,14 @@ class ZE_ALIGN(16) CVector4f
return lerp(a, b, t).normalized();
}
inline bool isNormalized(float thresh = 0.0001f) const
inline bool isNormalized(float thresh = 1e-5f) const
{
return (length() > thresh);
return (fabs(1.0f - magSquared()) <= thresh);
}
inline bool canBeNormalized()
{
return !isNormalized();
}
inline float& operator[](size_t idx) {return (&x)[idx];}
@ -361,5 +375,6 @@ static inline CVector4f operator/(float lhs, const CVector4f& rhs)
return CVector4f(lhs / rhs.x, lhs / rhs.y, lhs / rhs.z, lhs / rhs.w);
#endif
}
}
#endif // CVECTOR4F_HPP

View File

@ -11,7 +11,7 @@
# define ZE_ALIGN(x) __declspec(align(x))
# else
# include <mm_malloc.h>
# define ZE_ALIGN(x) __attribute__((aligned(x)))
# define ZE_ALIGN(x) alignas(16)
# endif
# define ZE_SHUFFLE(x,y,z,w) ((w)<<6 | (z)<<4 | (y)<<2 | (x))
# define zeAlloc(sz, align) _mm_malloc(sz, align)
@ -29,9 +29,10 @@
inline void* operator new[](size_t sizeInBytes) { return zeAlloc(sizeInBytes,16); } \
inline void operator delete[](void* ptr) { zeFree(ptr); } \
inline void* operator new[](size_t, void* ptr) { return ptr; } \
inline void operator delete[](void*, void*) { }
inline void operator delete[](void*, void*) { } \
void __unused__()
#else
# define ZE_DECLARE_ALIGNED_ALLOCATOR()
# define ZE_DECLARE_ALIGNED_ALLOCATOR() void __unused__()
#endif
#if __SSE__

View File

@ -6,31 +6,31 @@
#include "CVector3f.hpp"
#include "CTransform.hpp"
/* Macros for min/max. */
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif /* MIN */
#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif /* MAX */
namespace Zeus
{
namespace Math
{
template<typename T>
inline T clamp(T min, T val, T max) {return MAX(min, MIN(max, val));}
inline T clamp(T min, T val, T max) {return std::max(min, std::min(max, val));}
inline float radToDeg(float rad) {return rad * 180.f / M_PI;}
inline float degToRad(float deg) {return deg * M_PI / 180;}
extern const CVector3f kRadToDegVec;
extern const CVector3f kDegToRadVec;
inline CVector3f radToDeg(CVector3f rad) {return rad * kRadToDegVec;}
inline CVector3f degToRad(CVector3f deg) {return deg * kDegToRadVec;}
// Since round(double) doesn't exist in some <cmath> implementations
// we'll define our own
inline float round(double val) { return (val < 0.0 ? floor(val - 0.5) : floor(val + 0.5)); }
extern const CVector3f kUpVec;
CTransform lookAt(const CVector3f& pos, const CVector3f& lookPos, const CVector3f& up=kUpVec);
inline CVector3f baryToWorld(const CVector3f& p0, const CVector3f& p1, const CVector3f& p2, const CVector3f& bary)
{ return bary.x * p0 + bary.y * p1 + bary.z * p2; }
inline CVector3f getBezierPoint(const CVector3f& a, const CVector3f& b, const CVector3f& c, const CVector3f& d, float t);
}
}
#endif // MATH_HPP

View File

@ -2,6 +2,7 @@
#define __MATHLIB_HPP
#include "CAxisAngle.hpp"
#include "CRelAngle.hpp"
#include "CMatrix3f.hpp"
#include "CMatrix4f.hpp"
#include "CProjection.hpp"
@ -9,11 +10,15 @@
#include "CQuaternion.hpp"
#include "CVector2f.hpp"
#include "CVector3f.hpp"
#include "CVector3d.hpp"
#include "CVector4f.hpp"
#include "CUnitVector.hpp"
#include "CRectangle.hpp"
#include "CPlane.hpp"
#include "CLine.hpp"
#include "CAABox.hpp"
#include "COBBox.hpp"
#include "CSphere.hpp"
#include "CFrustum.hpp"
#include "CColor.hpp"
#include "Global.hpp"

View File

@ -1,6 +1,8 @@
#ifndef TVECTORUNION
#define TVECTORUNION
namespace Zeus
{
typedef union
{
float v[4];
@ -9,5 +11,14 @@ typedef union
#endif
} TVectorUnion;
typedef union
{
double v[4];
#if __SSE__
__m128d mVec128[2];
#endif
} TDblVectorUnion;
}
#endif // TVECTORUNION

View File

@ -1,2 +1,2 @@
#include "CAABox.hpp"
const CAABox CAABox::skInvertedBox = CAABox();
const Zeus::CAABox Zeus::CAABox::skInvertedBox = CAABox();

View File

@ -1,11 +1,11 @@
#include "CColor.hpp"
const CColor CColor::skRed (COLOR(0xFF0000FF));
const CColor CColor::skBlack (COLOR(0x000000FF));
const CColor CColor::skBlue (COLOR(0x0000FFFF));
const CColor CColor::skGreen (COLOR(0x00FF00FF));
const CColor CColor::skGrey (COLOR(0x808080FF));
const CColor CColor::skOrange(COLOR(0xFF7000FF));
const CColor CColor::skPurple(COLOR(0xA000FFFF));
const CColor CColor::skYellow(COLOR(0xFFFF00FF));
const CColor CColor::skWhite (COLOR(0xFFFFFFFF));
const Zeus::CColor Zeus::CColor::skRed (COLOR(0xFF0000FF));
const Zeus::CColor Zeus::CColor::skBlack (COLOR(0x000000FF));
const Zeus::CColor Zeus::CColor::skBlue (COLOR(0x0000FFFF));
const Zeus::CColor Zeus::CColor::skGreen (COLOR(0x00FF00FF));
const Zeus::CColor Zeus::CColor::skGrey (COLOR(0x808080FF));
const Zeus::CColor Zeus::CColor::skOrange(COLOR(0xFF7000FF));
const Zeus::CColor Zeus::CColor::skPurple(COLOR(0xA000FFFF));
const Zeus::CColor Zeus::CColor::skYellow(COLOR(0xFFFF00FF));
const Zeus::CColor Zeus::CColor::skWhite (COLOR(0xFFFFFFFF));

View File

@ -2,6 +2,8 @@
#include "CQuaternion.hpp"
#include "Global.hpp"
namespace Zeus
{
const CMatrix3f CMatrix3f::skIdentityMatrix3f = CMatrix3f();
CMatrix3f::CMatrix3f(const CQuaternion& quat)
@ -136,4 +138,4 @@ CMatrix3f CMatrix3f::inverted() const
-(m[0][0]*m[1][2] - m[0][2]*m[1][0]) * det,
(m[0][0]*m[1][1] - m[0][1]*m[1][0]) * det);
}
}

View File

@ -1,3 +1,3 @@
#include "CMatrix4f.hpp"
const CMatrix4f CMatrix4f::skIdentityMatrix4f = CMatrix4f();
const Zeus::CMatrix4f Zeus::CMatrix4f::skIdentityMatrix4f = CMatrix4f();

View File

@ -2,6 +2,8 @@
#include <math.h>
#include <stdio.h>
namespace Zeus
{
void CProjection::_updateCachedMatrix()
{
if (m_projType == PROJ_ORTHO)
@ -65,4 +67,5 @@ void CProjection::_updateCachedMatrix()
abort();
}
}
}

View File

@ -1,6 +1,8 @@
#include "CQuaternion.hpp"
#include <math.h>
namespace Zeus
{
void CQuaternion::fromVector3f(const CVector3f& vec)
{
float cosX = cosf(0.5 * vec.x);
@ -102,24 +104,24 @@ const CQuaternion& CQuaternion::operator/=(float scale)
return *this;
}
float CQuaternion::length() const
float CQuaternion::magnitude() const
{
return sqrt(lengthSquared());
return sqrt(magSquared());
}
float CQuaternion::lengthSquared() const
float CQuaternion::magSquared() const
{
return (r*r + (v.dot(v)));
}
void CQuaternion::normalize()
{
*this /= length();
*this /= magnitude();
}
CQuaternion CQuaternion::normalized() const
{
return *this/length();
return *this/magnitude();
}
void CQuaternion::invert()
@ -170,7 +172,7 @@ CQuaternion CQuaternion::log() const
CQuaternion CQuaternion::exp() const
{
float a = (v.length());
float a = (v.magnitude());
float sina = sinf(a);
float cosa = cos(a);
CQuaternion ret;
@ -249,3 +251,4 @@ CQuaternion operator*(float lhs, const CQuaternion& rhs)
{
return CQuaternion(lhs * rhs.r, lhs * rhs.v);
}
}

View File

@ -1,5 +1,7 @@
#include "CTransform.hpp"
namespace Zeus
{
CTransform CTransformFromEditorEuler(const CVector3f& eulerVec)
{
CTransform result;
@ -57,3 +59,11 @@ CTransform CTransformFromAxisAngle(const CVector3f& axis, float angle)
return result;
}
CTransform CTransformFromEditorEulers(const CVector3f& eulerVec, const CVector3f& origin)
{
CTransform ret = CTransformFromEditorEuler(eulerVec);
ret.m_origin = origin;
return ret;
}
}

View File

@ -4,14 +4,16 @@
#include <assert.h>
#include "Math.hpp"
namespace Zeus
{
const CVector2f CVector2f::skOne = CVector2f(1.0);
const CVector2f CVector2f::skNegOne = CVector2f(-1.0);
const CVector2f CVector2f::skZero;
float CVector2f::getAngleDiff(const CVector2f& a, const CVector2f& b)
{
float mag1 = a.length();
float mag2 = b.length();
float mag1 = a.magnitude();
float mag2 = b.magnitude();
if (!mag1 || !mag2)
return 0;
@ -47,4 +49,4 @@ CVector2f CVector2f::slerp(const CVector2f& a, const CVector2f& b, float t)
}
return a;
}
}

View File

@ -4,14 +4,16 @@
#include <assert.h>
#include "Math.hpp"
namespace Zeus
{
const CVector3f CVector3f::skOne = CVector3f(1.0);
const CVector3f CVector3f::skNegOne = CVector3f(-1.0);
const CVector3f CVector3f::skZero;
float CVector3f::getAngleDiff(const CVector3f& a, const CVector3f& b)
{
float mag1 = a.length();
float mag2 = b.length();
float mag1 = a.magnitude();
float mag2 = b.magnitude();
if (!mag1 || !mag2)
return 0;
@ -50,3 +52,4 @@ CVector3f CVector3f::slerp(const CVector3f& a, const CVector3f& b, float t)
}
return a;
}
}

View File

@ -1,10 +1,14 @@
#include "Math.hpp"
const CVector3f Math::kUpVec(0.0, 0.0, 1.0);
const CVector3f Math::kRadToDegVec(180.0f / M_PI);
const CVector3f Math::kDegToRadVec(M_PI / 180.0f);
namespace Zeus
{
namespace Math
{
const CVector3f kUpVec(0.0, 0.0, 1.0);
const CVector3f kRadToDegVec(180.0f / M_PI);
const CVector3f kDegToRadVec(M_PI / 180.0f);
CTransform Math::lookAt(const CVector3f& pos, const CVector3f& lookPos, const CVector3f& up)
CTransform lookAt(const CVector3f& pos, const CVector3f& lookPos, const CVector3f& up)
{
CVector3f vLook,vRight,vUp;
@ -19,3 +23,20 @@ CTransform Math::lookAt(const CVector3f& pos, const CVector3f& lookPos, const CV
CMatrix3f rmBasis(vRight, vUp, vLook);
return CTransform(rmBasis.transposed(), CVector3f(-pos.dot(vRight), -pos.dot(vUp), -pos.dot(vLook)));
}
CVector3f getBezierPoint(const CVector3f& r4, const CVector3f& r5, const CVector3f& r6, const CVector3f& r7, float f1)
{
//TODO: This isn't quite right, figure out what's really going on and reimplement
#if 0
float inv = 1.0 - f1;
CVector3f r3;
r3.x = ((((((r4.x * (r5.x * f1)) + inv) * (((r5.x * (r6.x * f1)) + inv) * f1)) + inv) * (((((r5.x * (r6.x * f1)) + inv) * (((r6.x * (r7.x * f1)) + inv) * f1)) + inv) * f1)) + inv);
r3.y = ((((((r4.y * (r5.y * f1)) + inv) * (((r5.y * (r6.y * f1)) + inv) * f1)) + inv) * (((((r5.y * (r6.y * f1)) + inv) * (((r6.y * (r7.y * f1)) + inv) * f1)) + inv) * f1)) + inv);
r3.z = ((((((r4.z * (r5.z * f1)) + inv) * (((r5.z * (r6.z * f1)) + inv) * f1)) + inv) * (((((r5.z * (r6.z * f1)) + inv) * (((r6.z * (r7.z * f1)) + inv) * f1)) + inv) * f1)) + inv);
return r3;
#endif
return CVector3f::skZero;
}
}
}

10
test/CMakeLists.txt Normal file
View File

@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.0)
project(zeustest)
include_directories(../include)
add_executable(zeustest
main.cpp)
target_link_libraries(zeustest
Math)

35
test/main.cpp Normal file
View File

@ -0,0 +1,35 @@
#include <iostream>
#include <MathLib.hpp>
// This is only for testing, do NOT do this normally
using namespace Zeus;
int main()
{
assert(!CAABox({100, 100, 100}, {100, 100, 100}).invalid());
assert(CAABox().invalid());
CVector3f vec{320, 632162.f, 800.f};
assert(vec.canBeNormalized());
assert(!vec.isZero());
assert(CVector3f().isZero());
assert(!vec.normalized().canBeNormalized());
float blarg = 5.f;
CVector3f t{100, 100, 200};
Math::clamp(blarg, 0.f, 1.f);
CAABox test{{-100, -100, -100}, {100, 100, 100}};
CAABox test2{{-100, -100, -100}, {100, 100, 100}};
CAABox test3{{-50, -50, -50}, {50, 50, 50}};
CAABox test4{{-50, -50, -105}, {50, 50, 105}};
CVector3f point(-90, 67, -105);
CVector3f closestPoint = test.closestPointAlongVector(point);
assert(t.isEqu(t));
assert(test.inside(test));
assert(test2.inside(test));
assert(test3.inside(test));
assert(!test4.inside(test));
std::cout << Math::round(1.5) << std::endl;
return 0;
}