mirror of
https://github.com/AxioDL/zeus.git
synced 2025-06-30 02:13:37 +00:00
WIP math reimplementations
This commit is contained in:
parent
57cfbc93b9
commit
5e2b997266
@ -7,7 +7,7 @@ endif()
|
|||||||
include_directories(include ${ATHENA_INCLUDE_DIR})
|
include_directories(include ${ATHENA_INCLUDE_DIR})
|
||||||
|
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
|
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(Math
|
add_library(Math
|
||||||
|
@ -42,23 +42,18 @@ public:
|
|||||||
#if __SSE__
|
#if __SSE__
|
||||||
TDblVectorUnion splat {x, y, z, 0.0};
|
TDblVectorUnion splat {x, y, z, 0.0};
|
||||||
mVec128[0] = splat.mVec128[0];
|
mVec128[0] = splat.mVec128[0];
|
||||||
mVec128[0] = splat.mVec128[1];
|
mVec128[1] = splat.mVec128[1];
|
||||||
#else
|
#else
|
||||||
v[0] = x; v[1] = y; v[2] = z; v[3] = 0.0;
|
v[0] = x; v[1] = y; v[2] = z; v[3] = 0.0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector3d(float x, float y, float z)
|
|
||||||
: CVector3d(double(x), double(y), double(z))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CVector3f asCVector3f()
|
CVector3f asCVector3f()
|
||||||
{
|
{
|
||||||
CVector3f ret;
|
CVector3f ret;
|
||||||
ret.x = Math::round(x);
|
ret.x = float(x);
|
||||||
ret.y = Math::round(y);
|
ret.y = float(y);
|
||||||
ret.z = Math::round(z);
|
ret.z = float(z);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#if _M_IX86_FP >= 1 || _M_X64
|
#if _M_IX86_FP >= 1 || _M_X64
|
||||||
# define __SSE__ 1
|
# define __SSE__ 1
|
||||||
#endif
|
#endif
|
||||||
|
#include <x86intrin.h>
|
||||||
|
|
||||||
#if __SSE__
|
#if __SSE__
|
||||||
# include <immintrin.h>
|
# include <immintrin.h>
|
||||||
@ -47,6 +48,9 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
inline int rotr(int x, int n) { return ((x >> n) | (x << (32 - n))); }
|
||||||
|
inline int rotl(int x, int n) { return ((x << n) | (x >> (32 - n))); }
|
||||||
|
|
||||||
|
|
||||||
#endif //ZEUS_GLOBAL_HPP
|
#endif //ZEUS_GLOBAL_HPP
|
||||||
|
|
||||||
|
@ -22,14 +22,61 @@ namespace Math
|
|||||||
|
|
||||||
// Since round(double) doesn't exist in some <cmath> implementations
|
// Since round(double) doesn't exist in some <cmath> implementations
|
||||||
// we'll define our own
|
// we'll define our own
|
||||||
inline float round(double val) { return (val < 0.0 ? floor(val - 0.5) : floor(val + 0.5)); }
|
inline float round(double val) { return (val < 0.0 ? ceil(val - 0.5) : floor(val + 0.5)); }
|
||||||
|
|
||||||
extern const CVector3f kUpVec;
|
extern const CVector3f kUpVec;
|
||||||
CTransform lookAt(const CVector3f& pos, const CVector3f& lookPos, const CVector3f& up=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)
|
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; }
|
{ 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);
|
CVector3f getBezierPoint(const CVector3f& a, const CVector3f& b, const CVector3f& c, const CVector3f& d, float t);
|
||||||
|
float getCatmullRomSplinePoint(float p0, float p1,
|
||||||
|
float p2, float p3, float t);
|
||||||
|
CVector3f getCatmullRomSplinePoint(const CVector3f& p0, const CVector3f& p1,
|
||||||
|
const CVector3f& p2, const CVector3f& p3, float t);
|
||||||
|
|
||||||
|
inline float slowCosineR(float val) { return float(cos(val)); }
|
||||||
|
inline float slowSineR(float val) { return float(sin(val)); }
|
||||||
|
inline float arcSineR(float val) { return float(asin(val)); }
|
||||||
|
inline float arcTangentR(float val) { return float(atan(val)); }
|
||||||
|
inline float fastArcCosR(float val)
|
||||||
|
{
|
||||||
|
double f2 = fabs(val);
|
||||||
|
if (f2 <= 0.925000011920929)
|
||||||
|
return float(acos(val));
|
||||||
|
|
||||||
|
float f4 = val * val;
|
||||||
|
float f5 = 1.5707964f;
|
||||||
|
float f0 = -0.99822718f;
|
||||||
|
float f3 = -0.20586604f;
|
||||||
|
f5 = (val * f5) + f0;
|
||||||
|
f2 = 0.11425424f;
|
||||||
|
float f1 = val * f4;
|
||||||
|
f0 = -0.29697824f;
|
||||||
|
f5 = (f1 * f5) + f3;
|
||||||
|
f1 = (f1 * f4);
|
||||||
|
f5 = (f1 * f5) + f2;
|
||||||
|
f1 = (f1 * f4);
|
||||||
|
f5 = (f1 * f5) + f0;
|
||||||
|
return f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int floorPowerOfTwo(int x)
|
||||||
|
{
|
||||||
|
if (x == 0)
|
||||||
|
return 0;
|
||||||
|
/*
|
||||||
|
* we want to ensure that we always get the previous power,
|
||||||
|
* but if we have values like 256, we'll always get the same value,
|
||||||
|
* x-1 ensures that we always get the previous power.
|
||||||
|
*/
|
||||||
|
x = (x - 1) | (x >> 1);
|
||||||
|
x = x | (x >> 2);
|
||||||
|
x = x | (x >> 4);
|
||||||
|
x = x | (x >> 8);
|
||||||
|
x = x | (x >> 16);
|
||||||
|
return x - (x >> 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
27
src/Math.cpp
27
src/Math.cpp
@ -1,4 +1,5 @@
|
|||||||
#include "Math.hpp"
|
#include "Math.hpp"
|
||||||
|
#include <x86intrin.h>
|
||||||
|
|
||||||
namespace Zeus
|
namespace Zeus
|
||||||
{
|
{
|
||||||
@ -24,19 +25,25 @@ CTransform lookAt(const CVector3f& pos, const CVector3f& lookPos, const CVector3
|
|||||||
return CTransform(rmBasis.transposed(), CVector3f(-pos.dot(vRight), -pos.dot(vUp), -pos.dot(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)
|
CVector3f getBezierPoint(const CVector3f& p0, const CVector3f& p1, const CVector3f& p2, const CVector3f& p3, float t)
|
||||||
{
|
{
|
||||||
//TODO: This isn't quite right, figure out what's really going on and reimplement
|
float w = (1.0 - t);
|
||||||
#if 0
|
CVector3f ret;
|
||||||
float inv = 1.0 - f1;
|
ret.x = ((((((p0.x * (p1.x * t)) + w) * (((p1.x * (p2.x * t)) + w) * t)) + w) * (((((p1.x * (p2.x * t)) + w) * (((p2.x * (p3.x * t)) + w) * t)) + w) * t)) + w);
|
||||||
CVector3f r3;
|
ret.y = ((((((p0.y * (p1.y * t)) + w) * (((p1.y * (p2.y * t)) + w) * t)) + w) * (((((p1.y * (p2.y * t)) + w) * (((p2.y * (p3.y * t)) + w) * t)) + w) * t)) + w);
|
||||||
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);
|
ret.z = ((((((p0.z * (p1.z * t)) + w) * (((p1.z * (p2.z * t)) + w) * t)) + w) * (((((p1.z * (p2.z * t)) + w) * (((p2.z * (p3.z * t)) + w) * t)) + w) * t)) + w);
|
||||||
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);
|
return ret;
|
||||||
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;
|
float getCatmullRomSplinePoint(float p0, float p1, float p2, float p3, float t)
|
||||||
#endif
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
CVector3f getCatmullRomSplinePoint(const CVector3f& p0, const CVector3f& p1, const CVector3f& p2, const CVector3f& p3, float t)
|
||||||
|
{
|
||||||
return CVector3f::skZero;
|
return CVector3f::skZero;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
#include <MathLib.hpp>
|
#include <MathLib.hpp>
|
||||||
|
|
||||||
// This is only for testing, do NOT do this normally
|
// This is only for testing, do NOT do this normally
|
||||||
@ -15,13 +16,14 @@ int main()
|
|||||||
assert(!vec.normalized().canBeNormalized());
|
assert(!vec.normalized().canBeNormalized());
|
||||||
float blarg = 5.f;
|
float blarg = 5.f;
|
||||||
CVector3f t{100, 100, 200};
|
CVector3f t{100, 100, 200};
|
||||||
Math::clamp(blarg, 0.f, 1.f);
|
blarg = Math::clamp(0.f, blarg, 1.f);
|
||||||
CAABox test{{-100, -100, -100}, {100, 100, 100}};
|
CAABox test{{-100, -100, -100}, {100, 100, 100}};
|
||||||
CAABox test2{{-100, -100, -100}, {100, 100, 100}};
|
CAABox test2{{-100, -100, -100}, {100, 100, 100}};
|
||||||
CAABox test3{{-50, -50, -50}, {50, 50, 50}};
|
CAABox test3{{-50, -50, -50}, {50, 50, 50}};
|
||||||
CAABox test4{{-50, -50, -105}, {50, 50, 105}};
|
CAABox test4{{-50, -50, -105}, {50, 50, 105}};
|
||||||
CVector3f point(-90, 67, -105);
|
CVector3f point(-90, 67, -105);
|
||||||
CVector3f closestPoint = test.closestPointAlongVector(point);
|
CVector3f closestPoint = test.closestPointAlongVector(point);
|
||||||
|
CVector3d doubleVec(100, -100, -200);
|
||||||
|
|
||||||
assert(t.isEqu(t));
|
assert(t.isEqu(t));
|
||||||
assert(test.inside(test));
|
assert(test.inside(test));
|
||||||
@ -29,7 +31,8 @@ int main()
|
|||||||
assert(test3.inside(test));
|
assert(test3.inside(test));
|
||||||
assert(!test4.inside(test));
|
assert(!test4.inside(test));
|
||||||
|
|
||||||
std::cout << Math::round(1.5) << std::endl;
|
std::cout << std::setprecision(16) << (double)Math::fastArcCosR(1.802073) << std::endl;
|
||||||
|
std::cout << Math::floorPowerOfTwo(256) << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user