aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Client/Project/VisualStudio/Phy2D/Phy2D.vcxproj19
-rw-r--r--Client/Project/VisualStudio/Phy2D/Phy2D.vcxproj.filters60
-rw-r--r--Client/Project/VisualStudio/Phy2Dlite/Phy2Dlite.vcxproj3
-rw-r--r--Client/Project/VisualStudio/Phy2Dlite/Phy2Dlite.vcxproj.filters15
-rw-r--r--Client/Source/Phy2D/Common/Math.h191
-rw-r--r--Client/Source/Phy2D/Common/Settings.h82
-rw-r--r--Client/Source/Phy2D/Common/Type.h (renamed from Client/Source/Phy2D/Shapes/p2CircleShape.cpp)0
-rw-r--r--Client/Source/Phy2D/Dynamic/Arbiter.cpp189
-rw-r--r--Client/Source/Phy2D/Dynamic/Arbiter.h91
-rw-r--r--Client/Source/Phy2D/Dynamic/Body.cpp47
-rw-r--r--Client/Source/Phy2D/Dynamic/Body.h34
-rw-r--r--Client/Source/Phy2D/Dynamic/Collide.cpp326
-rw-r--r--Client/Source/Phy2D/Dynamic/Joint.cpp102
-rw-r--r--Client/Source/Phy2D/Dynamic/Joint.h34
-rw-r--r--Client/Source/Phy2D/Dynamic/World.cpp129
-rw-r--r--Client/Source/Phy2D/Dynamic/World.h36
-rw-r--r--Client/Source/Phy2D/Phy2D.h4
-rw-r--r--Client/Source/Phy2D/Shapes/p2CircleShape.h8
-rw-r--r--Client/Source/Phy2D/Shapes/p2PolygonShape.cpp0
-rw-r--r--Client/Source/Phy2D/Shapes/p2PolygonShape.h0
-rw-r--r--Client/Source/Phy2D/Shapes/p2Shape.h7
-rw-r--r--Client/Source/Phy2D/Tests/test.h2
-rw-r--r--Client/Source/Phy2D/Tests/test_math.cpp9
-rw-r--r--Client/Source/Phy2D/Tests/test_p2d.cpp625
-rw-r--r--Client/Source/Phy2DLite/Constants.h24
-rw-r--r--Client/Source/Phy2DLite/Settings.h23
-rw-r--r--Client/Source/Phy2DLite/World.cpp2
-rw-r--r--Client/ThirdParty/fix32/fix32.cpp0
-rw-r--r--Client/ThirdParty/fix32/fix32.h7
-rw-r--r--Client/ThirdParty/fix32/fix32.hpp161
-rw-r--r--Client/ThirdParty/math-sll/LICENSE23
-rw-r--r--Client/ThirdParty/math-sll/Makefile69
-rw-r--r--Client/ThirdParty/math-sll/README51
-rw-r--r--Client/ThirdParty/math-sll/math-sll.c957
-rw-r--r--Client/ThirdParty/math-sll/math-sll.h770
35 files changed, 2192 insertions, 1908 deletions
diff --git a/Client/Project/VisualStudio/Phy2D/Phy2D.vcxproj b/Client/Project/VisualStudio/Phy2D/Phy2D.vcxproj
index 54f9787..84b0365 100644
--- a/Client/Project/VisualStudio/Phy2D/Phy2D.vcxproj
+++ b/Client/Project/VisualStudio/Phy2D/Phy2D.vcxproj
@@ -137,13 +137,6 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\Source\Phy2D\Common\Math.cpp" />
- <ClCompile Include="..\..\..\Source\Phy2D\Dynamic\Arbiter.cpp" />
- <ClCompile Include="..\..\..\Source\Phy2D\Dynamic\Body.cpp" />
- <ClCompile Include="..\..\..\Source\Phy2D\Dynamic\Collide.cpp" />
- <ClCompile Include="..\..\..\Source\Phy2D\Dynamic\Joint.cpp" />
- <ClCompile Include="..\..\..\Source\Phy2D\Dynamic\World.cpp" />
- <ClCompile Include="..\..\..\Source\Phy2D\Shapes\p2CircleShape.cpp" />
- <ClCompile Include="..\..\..\Source\Phy2D\Shapes\p2PolygonShape.cpp" />
<ClCompile Include="..\..\..\Source\Phy2D\Tests\test_p2d.cpp" />
<ClCompile Include="..\..\..\Source\Phy2D\Tests\test_math.cpp" />
<ClCompile Include="..\..\..\ThirdParty\fix32\fix32.cpp" />
@@ -163,21 +156,16 @@
<ClCompile Include="..\..\..\ThirdParty\libfixmath\libfixmath\fix16_trig.c" />
<ClCompile Include="..\..\..\ThirdParty\libfixmath\libfixmath\fract32.c" />
<ClCompile Include="..\..\..\ThirdParty\libfixmath\libfixmath\uint32.c" />
+ <ClCompile Include="..\..\..\ThirdParty\math-sll\math-sll.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Source\Phy2D\Common\Math.h" />
<ClInclude Include="..\..\..\Source\Phy2D\Common\Settings.h" />
- <ClInclude Include="..\..\..\Source\Phy2D\Dynamic\Arbiter.h" />
- <ClInclude Include="..\..\..\Source\Phy2D\Dynamic\Body.h" />
- <ClInclude Include="..\..\..\Source\Phy2D\Dynamic\Joint.h" />
- <ClInclude Include="..\..\..\Source\Phy2D\Dynamic\World.h" />
+ <ClInclude Include="..\..\..\Source\Phy2D\Common\Type.h" />
<ClInclude Include="..\..\..\Source\Phy2D\Phy2D.h" />
<ClInclude Include="..\..\..\Source\Phy2D\Rendering\Visualize.h" />
- <ClInclude Include="..\..\..\Source\Phy2D\Shapes\p2CircleShape.h" />
- <ClInclude Include="..\..\..\Source\Phy2D\Shapes\p2PolygonShape.h" />
- <ClInclude Include="..\..\..\Source\Phy2D\Shapes\p2Shape.h" />
<ClInclude Include="..\..\..\Source\Phy2D\Tests\test.h" />
- <ClInclude Include="..\..\..\ThirdParty\fix32\fix32.h" />
+ <ClInclude Include="..\..\..\ThirdParty\fix32\fix32.hpp" />
<ClInclude Include="..\..\..\ThirdParty\glad\glad.h" />
<ClInclude Include="..\..\..\ThirdParty\glad\khrplatform.h" />
<ClInclude Include="..\..\..\ThirdParty\imgui\backends\imgui_impl_opengl2.h" />
@@ -195,6 +183,7 @@
<ClInclude Include="..\..\..\ThirdParty\libfixmath\libfixmath\fract32.h" />
<ClInclude Include="..\..\..\ThirdParty\libfixmath\libfixmath\int64.h" />
<ClInclude Include="..\..\..\ThirdParty\libfixmath\libfixmath\uint32.h" />
+ <ClInclude Include="..\..\..\ThirdParty\math-sll\math-sll.h" />
</ItemGroup>
<ItemGroup>
<Text Include="..\..\..\Source\Phy2D\README.txt" />
diff --git a/Client/Project/VisualStudio/Phy2D/Phy2D.vcxproj.filters b/Client/Project/VisualStudio/Phy2D/Phy2D.vcxproj.filters
index 5a36dba..cf32e27 100644
--- a/Client/Project/VisualStudio/Phy2D/Phy2D.vcxproj.filters
+++ b/Client/Project/VisualStudio/Phy2D/Phy2D.vcxproj.filters
@@ -31,17 +31,11 @@
<Filter Include="Dynamic">
<UniqueIdentifier>{596062aa-a263-4c8c-acf2-1267b28a0f97}</UniqueIdentifier>
</Filter>
+ <Filter Include="libs\sll">
+ <UniqueIdentifier>{fc4d6710-2d01-480a-892c-79a461ad0ec4}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="..\..\..\Source\Phy2D\Shapes\p2CircleShape.cpp">
- <Filter>Shapes</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\Phy2D\Shapes\p2PolygonShape.cpp">
- <Filter>Shapes</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\Phy2D\Dynamic\Body.cpp">
- <Filter>Dynamic</Filter>
- </ClCompile>
<ClCompile Include="..\..\..\Source\Phy2D\Common\Math.cpp">
<Filter>Common</Filter>
</ClCompile>
@@ -51,18 +45,6 @@
<ClCompile Include="..\..\..\Source\Phy2D\Tests\test_p2d.cpp">
<Filter>Test</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\Source\Phy2D\Dynamic\Joint.cpp">
- <Filter>Dynamic</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\Phy2D\Dynamic\World.cpp">
- <Filter>Dynamic</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\Phy2D\Dynamic\Arbiter.cpp">
- <Filter>Dynamic</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\Phy2D\Dynamic\Collide.cpp">
- <Filter>Dynamic</Filter>
- </ClCompile>
<ClCompile Include="..\..\..\ThirdParty\glad\glad.c">
<Filter>libs\glad</Filter>
</ClCompile>
@@ -114,24 +96,15 @@
<ClCompile Include="..\..\..\ThirdParty\libfixmath\libfixmath\uint32.c">
<Filter>libs\libfixmath</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\ThirdParty\math-sll\math-sll.c">
+ <Filter>libs\sll</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
- <ClInclude Include="..\..\..\Source\Phy2D\Shapes\p2CircleShape.h">
- <Filter>Shapes</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\Phy2D\Shapes\p2PolygonShape.h">
- <Filter>Shapes</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\Phy2D\Shapes\p2Shape.h">
- <Filter>Shapes</Filter>
- </ClInclude>
<ClInclude Include="..\..\..\Source\Phy2D\Phy2D.h" />
<ClInclude Include="..\..\..\Source\Phy2D\Rendering\Visualize.h">
<Filter>Rendering</Filter>
</ClInclude>
- <ClInclude Include="..\..\..\Source\Phy2D\Dynamic\Body.h">
- <Filter>Dynamic</Filter>
- </ClInclude>
<ClInclude Include="..\..\..\Source\Phy2D\Common\Settings.h">
<Filter>Common</Filter>
</ClInclude>
@@ -141,24 +114,12 @@
<ClInclude Include="..\..\..\Source\Phy2D\Tests\test.h">
<Filter>Test</Filter>
</ClInclude>
- <ClInclude Include="..\..\..\Source\Phy2D\Dynamic\Joint.h">
- <Filter>Dynamic</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\Phy2D\Dynamic\World.h">
- <Filter>Dynamic</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\Phy2D\Dynamic\Arbiter.h">
- <Filter>Dynamic</Filter>
- </ClInclude>
<ClInclude Include="..\..\..\ThirdParty\glad\glad.h">
<Filter>libs\glad</Filter>
</ClInclude>
<ClInclude Include="..\..\..\ThirdParty\glad\khrplatform.h">
<Filter>libs\glad</Filter>
</ClInclude>
- <ClInclude Include="..\..\..\ThirdParty\fix32\fix32.h">
- <Filter>libs\fix32</Filter>
- </ClInclude>
<ClInclude Include="..\..\..\ThirdParty\imgui\imstb_truetype.h">
<Filter>libs\imgui</Filter>
</ClInclude>
@@ -204,6 +165,15 @@
<ClInclude Include="..\..\..\ThirdParty\libfixmath\libfixmath\uint32.h">
<Filter>libs\libfixmath</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\Source\Phy2D\Common\Type.h">
+ <Filter>Common</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ThirdParty\math-sll\math-sll.h">
+ <Filter>libs\sll</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ThirdParty\fix32\fix32.hpp">
+ <Filter>libs\fix32</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\..\Source\Phy2D\README.txt" />
diff --git a/Client/Project/VisualStudio/Phy2Dlite/Phy2Dlite.vcxproj b/Client/Project/VisualStudio/Phy2Dlite/Phy2Dlite.vcxproj
index 61da1c4..3f7e430 100644
--- a/Client/Project/VisualStudio/Phy2Dlite/Phy2Dlite.vcxproj
+++ b/Client/Project/VisualStudio/Phy2Dlite/Phy2Dlite.vcxproj
@@ -160,6 +160,7 @@
<ClCompile Include="..\..\..\ThirdParty\libfixmath\libfixmath\fix16_trig.c" />
<ClCompile Include="..\..\..\ThirdParty\libfixmath\libfixmath\fract32.c" />
<ClCompile Include="..\..\..\ThirdParty\libfixmath\libfixmath\uint32.c" />
+ <ClCompile Include="..\..\..\ThirdParty\math-sll\math-sll.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Source\Phy2DLite\Arbiter.h" />
@@ -171,6 +172,7 @@
<ClInclude Include="..\..\..\Source\Phy2DLite\Settings.h" />
<ClInclude Include="..\..\..\Source\Phy2DLite\Tests\test.h" />
<ClInclude Include="..\..\..\Source\Phy2DLite\World.h" />
+ <ClInclude Include="..\..\..\ThirdParty\fix32\fix32.hpp" />
<ClInclude Include="..\..\..\ThirdParty\fpm\include\fpm\fixed.hpp" />
<ClInclude Include="..\..\..\ThirdParty\fpm\include\fpm\ios.hpp" />
<ClInclude Include="..\..\..\ThirdParty\fpm\include\fpm\math.hpp" />
@@ -191,6 +193,7 @@
<ClInclude Include="..\..\..\ThirdParty\libfixmath\libfixmath\fract32.h" />
<ClInclude Include="..\..\..\ThirdParty\libfixmath\libfixmath\int64.h" />
<ClInclude Include="..\..\..\ThirdParty\libfixmath\libfixmath\uint32.h" />
+ <ClInclude Include="..\..\..\ThirdParty\math-sll\math-sll.h" />
</ItemGroup>
<ItemGroup>
<Text Include="..\..\..\Source\Phy2DLite\README.txt" />
diff --git a/Client/Project/VisualStudio/Phy2Dlite/Phy2Dlite.vcxproj.filters b/Client/Project/VisualStudio/Phy2Dlite/Phy2Dlite.vcxproj.filters
index 104e093..3b49c68 100644
--- a/Client/Project/VisualStudio/Phy2Dlite/Phy2Dlite.vcxproj.filters
+++ b/Client/Project/VisualStudio/Phy2Dlite/Phy2Dlite.vcxproj.filters
@@ -60,6 +60,9 @@
<ClCompile Include="..\..\..\Source\Phy2DLite\Tests\test.cpp">
<Filter>Tests</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\ThirdParty\math-sll\math-sll.c">
+ <Filter>Libs\sll</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Source\Phy2DLite\Arbiter.h" />
@@ -133,6 +136,12 @@
<Filter>Libs\fpm</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\Phy2DLite\Constants.h" />
+ <ClInclude Include="..\..\..\ThirdParty\math-sll\math-sll.h">
+ <Filter>Libs\sll</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ThirdParty\fix32\fix32.hpp">
+ <Filter>Libs\fix32</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Tests">
@@ -153,6 +162,12 @@
<Filter Include="Libs\fpm">
<UniqueIdentifier>{4670ccf3-2964-42b4-bb00-6b48eae171ad}</UniqueIdentifier>
</Filter>
+ <Filter Include="Libs\sll">
+ <UniqueIdentifier>{1b250cf1-a3ca-4e90-9bc9-bc10df919ccf}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Libs\fix32">
+ <UniqueIdentifier>{e9dd5549-728e-408f-b740-15e38984d253}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\..\ThirdParty\libfixmath\libfixmath\code_style.txt">
diff --git a/Client/Source/Phy2D/Common/Math.h b/Client/Source/Phy2D/Common/Math.h
index 9c0ff8f..e69de29 100644
--- a/Client/Source/Phy2D/Common/Math.h
+++ b/Client/Source/Phy2D/Common/Math.h
@@ -1,191 +0,0 @@
-#pragma once
-
-#include <math.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <string>
-
-#include "Settings.h"
-
-namespace Phy2D
-{
-
- struct Vec2
- {
- Vec2() {}
- Vec2(number x, number y) : x(x), y(y) {}
-
- void Set(number x_, number y_) { x = x_; y = y_; }
-
- Vec2 operator -() { return Vec2(-x, -y); }
-
- void operator += (const Vec2& v)
- {
- x += v.x; y += v.y;
- }
-
- void operator -= (const Vec2& v)
- {
- x -= v.x; y -= v.y;
- }
-
- void operator *= (number a)
- {
- x *= a; y *= a;
- }
-
- number Length() const
- {
- return SQRT(x * x + y * y);
- }
-
- std::string ToString()
- {
- return std::to_string((float)x) + "," + std::to_string((float)y);
- }
-
- number x, y;
- };
-
- struct Mat22
- {
- Mat22() {}
- Mat22(number angle)
- {
- number c = COS(angle), s = SIN(angle);
- col1.x = c; col2.x = -s;
- col1.y = s; col2.y = c;
- }
-
- Mat22(const Vec2& col1, const Vec2& col2) : col1(col1), col2(col2) {}
-
- Mat22 Transpose() const
- {
- return Mat22(Vec2(col1.x, col2.x), Vec2(col1.y, col2.y));
- }
-
- Mat22 Invert() const
- {
- number a = col1.x, b = col2.x, c = col1.y, d = col2.y;
- Mat22 B;
- number det = a * d - b * c;
- assert(det != 0.0f);
- det = (number)1.0f / det;
- B.col1.x = det * d; B.col2.x = -det * b;
- B.col1.y = -det * c; B.col2.y = det * a;
- return B;
- }
-
- Vec2 col1, col2;
- };
-
- inline number Dot(const Vec2& a, const Vec2& b)
- {
- return a.x * b.x + a.y * b.y;
- }
-
- inline number Cross(const Vec2& a, const Vec2& b)
- {
- return a.x * b.y - a.y * b.x;
- }
-
- inline Vec2 Cross(const Vec2& a, number s)
- {
- return Vec2(s * a.y, -s * a.x);
- }
-
- inline Vec2 Cross(number s, const Vec2& a)
- {
- return Vec2(-s * a.y, s * a.x);
- }
-
- inline Vec2 operator * (const Mat22& A, const Vec2& v)
- {
- return Vec2(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y);
- }
-
- inline Vec2 operator + (const Vec2& a, const Vec2& b)
- {
- return Vec2(a.x + b.x, a.y + b.y);
- }
-
- inline Vec2 operator - (const Vec2& a, const Vec2& b)
- {
- return Vec2(a.x - b.x, a.y - b.y);
- }
-
- inline Vec2 operator * (number s, const Vec2& v)
- {
- return Vec2(s * v.x, s * v.y);
- }
-
- inline Mat22 operator + (const Mat22& A, const Mat22& B)
- {
- return Mat22(A.col1 + B.col1, A.col2 + B.col2);
- }
-
- inline Mat22 operator * (const Mat22& A, const Mat22& B)
- {
- return Mat22(A * B.col1, A * B.col2);
- }
-
- inline number Abs(number a)
- {
- return a > 0.0f ? a : -a;
- }
-
- inline Vec2 Abs(const Vec2& a)
- {
- return Vec2(fabsf(a.x), fabsf(a.y));
- }
-
- inline Mat22 Abs(const Mat22& A)
- {
- return Mat22(Abs(A.col1), Abs(A.col2));
- }
-
- inline number Sign(number x)
- {
- return (float) x < 0.0f ? -1.0f : 1.0f;
- }
-
- inline number Min(number a, number b)
- {
- return a < b ? a : b;
- }
-
- inline number Max(number a, number b)
- {
- return a > b ? a : b;
- }
-
- inline number Clamp(number a, number low, number high)
- {
- return Max(low, Min(a, high));
- }
-
- template<typename T> inline void Swap(T& a, T& b)
- {
- T tmp = a;
- a = b;
- b = tmp;
- }
-
- //// Random number in range [-1,1]
- //inline number Random()
- //{
- // number r = (number)rand();
- // r /= RAND_MAX;
- // r = (number)2.0f * r - 1.0f;
- // return r;
- //}
-
- //inline number Random(number lo, number hi)
- //{
- // number r = (number)rand();
- // r /= RAND_MAX;
- // r = (hi - lo) * r + lo;
- // return r;
- //}
-
-}
diff --git a/Client/Source/Phy2D/Common/Settings.h b/Client/Source/Phy2D/Common/Settings.h
index 5c24b57..318a76c 100644
--- a/Client/Source/Phy2D/Common/Settings.h
+++ b/Client/Source/Phy2D/Common/Settings.h
@@ -1,27 +1,97 @@
#pragma once
+#define NUMBER_FLOAT 1
+#define NUMBER_LIBFIX 2
+#define NUMBER_FPM 3
+
+#define NUMBER_ALIAS NUMBER_FPM
+
+#if NUMBER_ALIAS == NUMBER_LIBFIX
#include "libfixmath/libfixmath/fixmath.h"
+#elif NUMBER_ALIAS == NUMBER_FPM
+#include "fpm/include/fpm/fixed.hpp"
+#include "fpm/include/fpm/math.hpp"
+#endif
namespace Phy2D
{
-#define NUMBER_FLOAT false
+#if NUMBER_ALIAS == NUMBER_FLOAT
-#if NUMBER_FLOAT
-typedef float number;
+ typedef float fixed;
#define NUMBER_MAX (FLT_MAX)
#define NUMBER_MIN (FLT_MIN)
#define SQRT(a) (sqrt((a)))
#define SIN(a) (sin((a)))
#define COS(a) (cos((a)))
-#else
-// 同时一定要开启内联函数扩展,否则执行效率会非常低
-typedef Fix16 number;
+#define PI (3.1415925f)
+
+#elif NUMBER_ALIAS == NUMBER_LIBFIX
+
+ // 同时一定要开启内联函数扩展,否则执行效率会非常低
+ typedef Fix16 fixed;
#define NUMBER_MAX (fix16_maximum)
#define NUMBER_MIN (fix16_minimum)
#define SQRT(a) ((a).sqrt())
#define SIN(a) ((a).sin())
#define COS(a) ((a).cos())
+#define PI (fix16_pi)
+
+#elif NUMBER_ALIAS == NUMBER_FPM
+
+ template <typename T>
+ struct Limits {};
+
+ template <>
+ struct Limits<fpm::fixed_16_16>
+ {
+ static constexpr bool is_signed() noexcept { return true; }
+ static constexpr int digits() noexcept { return 31; }
+ static constexpr int max_digits10() noexcept { return 5 + 5; }
+ static constexpr int min_exponent() noexcept { return -15; }
+ static constexpr int max_exponent() noexcept { return 15; }
+ static constexpr int min_exponent10() noexcept { return -4; }
+ static constexpr int max_exponent10() noexcept { return 4; }
+ static constexpr fpm::fixed_16_16 min() noexcept { return fpm::fixed_16_16::from_raw_value(-2147483647 - 1); }
+ static constexpr fpm::fixed_16_16 max() noexcept { return fpm::fixed_16_16::from_raw_value(2147483647); }
+ };
+
+ template <>
+ struct Limits<fpm::fixed_24_8>
+ {
+ static constexpr bool is_signed() noexcept { return true; }
+ static constexpr int digits() noexcept { return 31; }
+ static constexpr int max_digits10() noexcept { return 7 + 3; }
+ static constexpr int min_exponent() noexcept { return -7; }
+ static constexpr int max_exponent() noexcept { return 23; }
+ static constexpr int min_exponent10() noexcept { return -2; }
+ static constexpr int max_exponent10() noexcept { return 6; }
+ static constexpr fpm::fixed_24_8 min() noexcept { return fpm::fixed_24_8::from_raw_value(-2147483647 - 1); }
+ static constexpr fpm::fixed_24_8 max() noexcept { return fpm::fixed_24_8::from_raw_value(2147483647); }
+ };
+
+ template <>
+ struct Limits<fpm::fixed_8_24>
+ {
+ static constexpr bool is_signed() noexcept { return true; }
+ static constexpr int digits() noexcept { return 31; }
+ static constexpr int max_digits10() noexcept { return 3 + 8; }
+ static constexpr int min_exponent() noexcept { return -23; }
+ static constexpr int max_exponent() noexcept { return 7; }
+ static constexpr int min_exponent10() noexcept { return -7; }
+ static constexpr int max_exponent10() noexcept { return 2; }
+ static constexpr fpm::fixed_8_24 min() noexcept { return fpm::fixed_8_24::from_raw_value(-2147483647 - 1); }
+ static constexpr fpm::fixed_8_24 max() noexcept { return fpm::fixed_8_24::from_raw_value(2147483647); }
+ };
+
+ typedef fpm::fixed_16_16 fixed;
+#define NUMBER_MAX (Limits<fixed>::max())
+#define NUMBER_MIN (Limits<fixed>::min())
+#define SQRT(a) (fpm::sqrt((a)))
+#define SIN(a) (fpm::sin((a)))
+#define COS(a) (fpm::cos((a)))
+#define PI (fixed::pi())
+
#endif
} \ No newline at end of file
diff --git a/Client/Source/Phy2D/Shapes/p2CircleShape.cpp b/Client/Source/Phy2D/Common/Type.h
index e69de29..e69de29 100644
--- a/Client/Source/Phy2D/Shapes/p2CircleShape.cpp
+++ b/Client/Source/Phy2D/Common/Type.h
diff --git a/Client/Source/Phy2D/Dynamic/Arbiter.cpp b/Client/Source/Phy2D/Dynamic/Arbiter.cpp
deleted file mode 100644
index 4163154..0000000
--- a/Client/Source/Phy2D/Dynamic/Arbiter.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-#include "Arbiter.h"
-#include "World.h"
-#include "Body.h"
-#include "Joint.h"
-
-using namespace Phy2D;
-
-Arbiter::Arbiter(Body* b1, Body* b2)
-{
- if (b1 < b2)
- {
- body1 = b1;
- body2 = b2;
- }
- else
- {
- body1 = b2;
- body2 = b1;
- }
-
- numContacts = Collide(contacts, body1, body2);
-
- friction = SQRT(body1->friction * body2->friction);
-}
-
-void Arbiter::Update(Contact* newContacts, int numNewContacts)
-{
- Contact mergedContacts[2];
-
- for (int i = 0; i < numNewContacts; ++i)
- {
- Contact* cNew = newContacts + i;
- int k = -1;
- for (int j = 0; j < numContacts; ++j)
- {
- Contact* cOld = contacts + j;
- if (cNew->feature.value == cOld->feature.value)
- {
- k = j;
- break;
- }
- }
-
- if (k > -1)
- {
- Contact* c = mergedContacts + i;
- Contact* cOld = contacts + k;
- *c = *cNew;
- if (World::warmStarting)
- {
- c->Pn = cOld->Pn;
- c->Pt = cOld->Pt;
- c->Pnb = cOld->Pnb;
- }
- else
- {
- c->Pn = 0.0f;
- c->Pt = 0.0f;
- c->Pnb = 0.0f;
- }
- }
- else
- {
- mergedContacts[i] = newContacts[i];
- }
- }
-
- for (int i = 0; i < numNewContacts; ++i)
- contacts[i] = mergedContacts[i];
-
- numContacts = numNewContacts;
-}
-
-
-void Arbiter::PreStep(number inv_dt)
-{
- const number k_allowedPenetration = 0.01f;
- number k_biasFactor = World::positionCorrection ? 0.2f : 0.0f;
-
- for (int i = 0; i < numContacts; ++i)
- {
- Contact* c = contacts + i;
-
- Vec2 r1 = c->position - body1->position;
- Vec2 r2 = c->position - body2->position;
-
- // Precompute normal mass, tangent mass, and bias.
- number rn1 = Dot(r1, c->normal);
- number rn2 = Dot(r2, c->normal);
- number kNormal = body1->invMass + body2->invMass;
- kNormal += body1->invI * (Dot(r1, r1) - rn1 * rn1) + body2->invI * (Dot(r2, r2) - rn2 * rn2);
- c->massNormal = (number) 1.0f / kNormal;
-
- Vec2 tangent = Cross(c->normal, 1.0f);
- number rt1 = Dot(r1, tangent);
- number rt2 = Dot(r2, tangent);
- number kTangent = body1->invMass + body2->invMass;
- kTangent += body1->invI * (Dot(r1, r1) - rt1 * rt1) + body2->invI * (Dot(r2, r2) - rt2 * rt2);
- c->massTangent = (number) 1.0f / kTangent;
-
- c->bias = -k_biasFactor * inv_dt * Min(0.0f, c->separation + k_allowedPenetration);
-
- if (World::accumulateImpulses)
- {
- // Apply normal + friction impulse
- Vec2 P = c->Pn * c->normal + c->Pt * tangent;
-
- body1->velocity -= body1->invMass * P;
- body1->angularVelocity -= body1->invI * Cross(r1, P);
-
- body2->velocity += body2->invMass * P;
- body2->angularVelocity += body2->invI * Cross(r2, P);
- }
- }
-}
-
-void Arbiter::ApplyImpulse()
-{
- Body* b1 = body1;
- Body* b2 = body2;
-
- for (int i = 0; i < numContacts; ++i)
- {
- Contact* c = contacts + i;
- c->r1 = c->position - b1->position;
- c->r2 = c->position - b2->position;
-
- // Relative velocity at contact
- Vec2 dv = b2->velocity + Cross(b2->angularVelocity, c->r2) - b1->velocity - Cross(b1->angularVelocity, c->r1);
-
- // Compute normal impulse
- number vn = Dot(dv, c->normal);
-
- number dPn = c->massNormal * (-vn + c->bias);
-
- if (World::accumulateImpulses)
- {
- // Clamp the accumulated impulse
- number Pn0 = c->Pn;
- c->Pn = Max(Pn0 + dPn, 0.0f);
- dPn = c->Pn - Pn0;
- }
- else
- {
- dPn = Max(dPn, 0.0f);
- }
-
- // Apply contact impulse
- Vec2 Pn = dPn * c->normal;
-
- b1->velocity -= b1->invMass * Pn;
- b1->angularVelocity -= b1->invI * Cross(c->r1, Pn);
-
- b2->velocity += b2->invMass * Pn;
- b2->angularVelocity += b2->invI * Cross(c->r2, Pn);
-
- // Relative velocity at contact
- dv = b2->velocity + Cross(b2->angularVelocity, c->r2) - b1->velocity - Cross(b1->angularVelocity, c->r1);
-
- Vec2 tangent = Cross(c->normal, 1.0f);
- number vt = Dot(dv, tangent);
- number dPt = c->massTangent * (-vt);
-
- if (World::accumulateImpulses)
- {
- // Compute friction impulse
- number maxPt = friction * c->Pn;
-
- // Clamp friction
- number oldTangentImpulse = c->Pt;
- c->Pt = Clamp(oldTangentImpulse + dPt, -maxPt, maxPt);
- dPt = c->Pt - oldTangentImpulse;
- }
- else
- {
- number maxPt = friction * dPn;
- dPt = Clamp(dPt, -maxPt, maxPt);
- }
-
- // Apply contact impulse
- Vec2 Pt = dPt * tangent;
-
- b1->velocity -= b1->invMass * Pt;
- b1->angularVelocity -= b1->invI * Cross(c->r1, Pt);
-
- b2->velocity += b2->invMass * Pt;
- b2->angularVelocity += b2->invI * Cross(c->r2, Pt);
- }
-}
diff --git a/Client/Source/Phy2D/Dynamic/Arbiter.h b/Client/Source/Phy2D/Dynamic/Arbiter.h
deleted file mode 100644
index 64bed72..0000000
--- a/Client/Source/Phy2D/Dynamic/Arbiter.h
+++ /dev/null
@@ -1,91 +0,0 @@
-#pragma once
-
-#include "../Common/Math.h"
-
-namespace Phy2D
-{
-
- struct Body;
-
- union FeaturePair
- {
- struct Edges
- {
- char inEdge1;
- char outEdge1;
- char inEdge2;
- char outEdge2;
- } e;
- int value;
- };
-
- struct Contact
- {
- Contact() : Pn(0.0f), Pt(0.0f), Pnb(0.0f) {}
-
- Vec2 position;
- Vec2 normal;
- Vec2 r1, r2;
- number separation;
- number Pn; // accumulated normal impulse
- number Pt; // accumulated tangent impulse
- number Pnb; // accumulated normal impulse for position bias
- number massNormal, massTangent;
- number bias;
- FeaturePair feature;
- };
-
- struct ArbiterKey
- {
- ArbiterKey(Body* b1, Body* b2)
- {
- if (b1 < b2)
- {
- body1 = b1; body2 = b2;
- }
- else
- {
- body1 = b2; body2 = b1;
- }
- }
-
- Body* body1;
- Body* body2;
- };
-
- struct Arbiter
- {
- enum { MAX_POINTS = 2 };
-
- Arbiter(Body* b1, Body* b2);
-
- void Update(Contact* contacts, int numContacts);
-
- void PreStep(number inv_dt);
- void ApplyImpulse();
-
- Contact contacts[MAX_POINTS];
- int numContacts;
-
- Body* body1;
- Body* body2;
-
- // Combined friction
- number friction;
- };
-
- // This is used by std::set
- inline bool operator < (const ArbiterKey& a1, const ArbiterKey& a2)
- {
- if (a1.body1 < a2.body1)
- return true;
-
- if (a1.body1 == a2.body1 && a1.body2 < a2.body2)
- return true;
-
- return false;
- }
-
- int Collide(Contact* contacts, Body* body1, Body* body2);
-
-} \ No newline at end of file
diff --git a/Client/Source/Phy2D/Dynamic/Body.cpp b/Client/Source/Phy2D/Dynamic/Body.cpp
deleted file mode 100644
index 1d896fd..0000000
--- a/Client/Source/Phy2D/Dynamic/Body.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "Body.h"
-
-using namespace Phy2D;
-
-Body::Body()
-{
- position.Set(0.0f, 0.0f);
- rotation = 0.0f;
- velocity.Set(0.0f, 0.0f);
- angularVelocity = 0.0f;
- force.Set(0.0f, 0.0f);
- torque = 0.0f;
- friction = 0.2f;
-
- width.Set(1.0f, 1.0f);
- mass = NUMBER_MAX;
- invMass = 0.0f;
- I = NUMBER_MAX;
- invI = 0.0f;
-}
-
-void Body::Set(const Vec2& w, number m)
-{
- position.Set(0.0f, 0.0f);
- rotation = 0.0f;
- velocity.Set(0.0f, 0.0f);
- angularVelocity = 0.0f;
- force.Set(0.0f, 0.0f);
- torque = 0.0f;
- friction = 0.2f;
-
- width = w;
- mass = m;
-
- if (mass < NUMBER_MAX)
- {
- invMass = (number)1.0f / mass;
- I = mass * (width.x * width.x + width.y * width.y) / 12.0f;
- invI = (number)1.0f / I;
- }
- else
- {
- invMass = 0.0f;
- I = NUMBER_MAX;
- invI = 0.0f;
- }
-}
diff --git a/Client/Source/Phy2D/Dynamic/Body.h b/Client/Source/Phy2D/Dynamic/Body.h
deleted file mode 100644
index 8c2ac72..0000000
--- a/Client/Source/Phy2D/Dynamic/Body.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#pragma once
-
-#include "../Common/Math.h"
-
-namespace Phy2D
-{
-
- struct Body
- {
- Body();
- void Set(const Vec2& w, number m);
-
- void AddForce(const Vec2& f)
- {
- force += f;
- }
-
- Vec2 position;
- number rotation;
-
- Vec2 velocity;
- number angularVelocity;
-
- Vec2 force;
- number torque;
-
- Vec2 width;
-
- number friction;
- number mass, invMass;
- number I, invI;
- };
-
-} \ No newline at end of file
diff --git a/Client/Source/Phy2D/Dynamic/Collide.cpp b/Client/Source/Phy2D/Dynamic/Collide.cpp
deleted file mode 100644
index 6849c0e..0000000
--- a/Client/Source/Phy2D/Dynamic/Collide.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-#include "Arbiter.h"
-#include "Body.h"
-#include "World.h"
-#include "Joint.h"
-
-using namespace Phy2D;
-
-// Box vertex and edge numbering:
-//
-// ^ y
-// |
-// e1
-// v2 ------ v1
-// | |
-// e2 | | e4 --> x
-// | |
-// v3 ------ v4
-// e3
-
-enum Axis
-{
- FACE_A_X,
- FACE_A_Y,
- FACE_B_X,
- FACE_B_Y
-};
-
-enum EdgeNumbers
-{
- NO_EDGE = 0,
- EDGE1,
- EDGE2,
- EDGE3,
- EDGE4
-};
-
-struct ClipVertex
-{
- ClipVertex() { fp.value = 0; }
- Vec2 v;
- FeaturePair fp;
-};
-
-void Flip(FeaturePair& fp)
-{
- Swap(fp.e.inEdge1, fp.e.inEdge2);
- Swap(fp.e.outEdge1, fp.e.outEdge2);
-}
-
-int ClipSegmentToLine(ClipVertex vOut[2], ClipVertex vIn[2],
- const Vec2& normal, number offset, char clipEdge)
-{
- // Start with no output points
- int numOut = 0;
-
- // Calculate the distance of end points to the line
- number distance0 = Dot(normal, vIn[0].v) - offset;
- number distance1 = Dot(normal, vIn[1].v) - offset;
-
- // If the points are behind the plane
- if (distance0 <= 0.0f) vOut[numOut++] = vIn[0];
- if (distance1 <= 0.0f) vOut[numOut++] = vIn[1];
-
- // If the points are on different sides of the plane
- if (distance0 * distance1 < 0.0f)
- {
- // Find intersection point of edge and plane
- number interp = distance0 / (distance0 - distance1);
- vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v);
- if (distance0 > 0.0f)
- {
- vOut[numOut].fp = vIn[0].fp;
- vOut[numOut].fp.e.inEdge1 = clipEdge;
- vOut[numOut].fp.e.inEdge2 = NO_EDGE;
- }
- else
- {
- vOut[numOut].fp = vIn[1].fp;
- vOut[numOut].fp.e.outEdge1 = clipEdge;
- vOut[numOut].fp.e.outEdge2 = NO_EDGE;
- }
- ++numOut;
- }
-
- return numOut;
-}
-
-static void ComputeIncidentEdge(ClipVertex c[2], const Vec2& h, const Vec2& pos,
- const Mat22& Rot, const Vec2& normal)
-{
- // The normal is from the reference box. Convert it
- // to the incident boxe's frame and flip sign.
- Mat22 RotT = Rot.Transpose();
- Vec2 n = -(RotT * normal);
- Vec2 nAbs = Abs(n);
-
- if (nAbs.x > nAbs.y)
- {
- if (Sign(n.x) > 0.0f)
- {
- c[0].v.Set(h.x, -h.y);
- c[0].fp.e.inEdge2 = EDGE3;
- c[0].fp.e.outEdge2 = EDGE4;
-
- c[1].v.Set(h.x, h.y);
- c[1].fp.e.inEdge2 = EDGE4;
- c[1].fp.e.outEdge2 = EDGE1;
- }
- else
- {
- c[0].v.Set(-h.x, h.y);
- c[0].fp.e.inEdge2 = EDGE1;
- c[0].fp.e.outEdge2 = EDGE2;
-
- c[1].v.Set(-h.x, -h.y);
- c[1].fp.e.inEdge2 = EDGE2;
- c[1].fp.e.outEdge2 = EDGE3;
- }
- }
- else
- {
- if (Sign(n.y) > 0.0f)
- {
- c[0].v.Set(h.x, h.y);
- c[0].fp.e.inEdge2 = EDGE4;
- c[0].fp.e.outEdge2 = EDGE1;
-
- c[1].v.Set(-h.x, h.y);
- c[1].fp.e.inEdge2 = EDGE1;
- c[1].fp.e.outEdge2 = EDGE2;
- }
- else
- {
- c[0].v.Set(-h.x, -h.y);
- c[0].fp.e.inEdge2 = EDGE2;
- c[0].fp.e.outEdge2 = EDGE3;
-
- c[1].v.Set(h.x, -h.y);
- c[1].fp.e.inEdge2 = EDGE3;
- c[1].fp.e.outEdge2 = EDGE4;
- }
- }
-
- c[0].v = pos + Rot * c[0].v;
- c[1].v = pos + Rot * c[1].v;
-}
-
-namespace Phy2D
-{
-
- // The normal points from A to B
- int Collide(Contact* contacts, Body* bodyA, Body* bodyB)
- {
- // Setup
- Vec2 hA = 0.5f * bodyA->width;
- Vec2 hB = 0.5f * bodyB->width;
-
- Vec2 posA = bodyA->position;
- Vec2 posB = bodyB->position;
-
- Mat22 RotA(bodyA->rotation), RotB(bodyB->rotation);
-
- Mat22 RotAT = RotA.Transpose();
- Mat22 RotBT = RotB.Transpose();
-
- Vec2 dp = posB - posA;
- Vec2 dA = RotAT * dp;
- Vec2 dB = RotBT * dp;
-
- Mat22 C = RotAT * RotB;
- Mat22 absC = Abs(C);
- Mat22 absCT = absC.Transpose();
-
- // Box A faces
- Vec2 faceA = Abs(dA) - hA - absC * hB;
- if (faceA.x > 0.0f || faceA.y > 0.0f)
- return 0;
-
- // Box B faces
- Vec2 faceB = Abs(dB) - absCT * hA - hB;
- if (faceB.x > 0.0f || faceB.y > 0.0f)
- return 0;
-
- // Find best axis
- Axis axis;
- number separation;
- Vec2 normal;
-
- // Box A faces
- axis = FACE_A_X;
- separation = faceA.x;
- normal = dA.x > 0.0f ? RotA.col1 : -RotA.col1;
-
- const number relativeTol = 0.95f;
- const number absoluteTol = 0.01f;
-
- if (faceA.y > relativeTol * separation + absoluteTol * hA.y)
- {
- axis = FACE_A_Y;
- separation = faceA.y;
- normal = dA.y > 0.0f ? RotA.col2 : -RotA.col2;
- }
-
- // Box B faces
- if (faceB.x > relativeTol * separation + absoluteTol * hB.x)
- {
- axis = FACE_B_X;
- separation = faceB.x;
- normal = dB.x > 0.0f ? RotB.col1 : -RotB.col1;
- }
-
- if (faceB.y > relativeTol * separation + absoluteTol * hB.y)
- {
- axis = FACE_B_Y;
- separation = faceB.y;
- normal = dB.y > 0.0f ? RotB.col2 : -RotB.col2;
- }
-
- // Setup clipping plane data based on the separating axis
- Vec2 frontNormal, sideNormal;
- ClipVertex incidentEdge[2];
- number front, negSide, posSide;
- char negEdge, posEdge;
-
- // Compute the clipping lines and the line segment to be clipped.
- switch (axis)
- {
- case FACE_A_X:
- {
- frontNormal = normal;
- front = Dot(posA, frontNormal) + hA.x;
- sideNormal = RotA.col2;
- number side = Dot(posA, sideNormal);
- negSide = -side + hA.y;
- posSide = side + hA.y;
- negEdge = EDGE3;
- posEdge = EDGE1;
- ComputeIncidentEdge(incidentEdge, hB, posB, RotB, frontNormal);
- }
- break;
-
- case FACE_A_Y:
- {
- frontNormal = normal;
- front = Dot(posA, frontNormal) + hA.y;
- sideNormal = RotA.col1;
- number side = Dot(posA, sideNormal);
- negSide = -side + hA.x;
- posSide = side + hA.x;
- negEdge = EDGE2;
- posEdge = EDGE4;
- ComputeIncidentEdge(incidentEdge, hB, posB, RotB, frontNormal);
- }
- break;
-
- case FACE_B_X:
- {
- frontNormal = -normal;
- front = Dot(posB, frontNormal) + hB.x;
- sideNormal = RotB.col2;
- number side = Dot(posB, sideNormal);
- negSide = -side + hB.y;
- posSide = side + hB.y;
- negEdge = EDGE3;
- posEdge = EDGE1;
- ComputeIncidentEdge(incidentEdge, hA, posA, RotA, frontNormal);
- }
- break;
-
- case FACE_B_Y:
- {
- frontNormal = -normal;
- front = Dot(posB, frontNormal) + hB.y;
- sideNormal = RotB.col1;
- number side = Dot(posB, sideNormal);
- negSide = -side + hB.x;
- posSide = side + hB.x;
- negEdge = EDGE2;
- posEdge = EDGE4;
- ComputeIncidentEdge(incidentEdge, hA, posA, RotA, frontNormal);
- }
- break;
- }
-
- // clip other face with 5 box planes (1 face plane, 4 edge planes)
-
- ClipVertex clipPoints1[2];
- ClipVertex clipPoints2[2];
- int np;
-
- // Clip to box side 1
- np = ClipSegmentToLine(clipPoints1, incidentEdge, -sideNormal, negSide, negEdge);
-
- if (np < 2)
- return 0;
-
- // Clip to negative box side 1
- np = ClipSegmentToLine(clipPoints2, clipPoints1, sideNormal, posSide, posEdge);
-
- if (np < 2)
- return 0;
-
- // Now clipPoints2 contains the clipping points.
- // Due to roundoff, it is possible that clipping removes all points.
-
- int numContacts = 0;
- for (int i = 0; i < 2; ++i)
- {
- number separation = Dot(frontNormal, clipPoints2[i].v) - front;
-
- if (separation <= 0)
- {
- contacts[numContacts].separation = separation;
- contacts[numContacts].normal = normal;
- // slide contact point onto reference face (easy to cull)
- contacts[numContacts].position = clipPoints2[i].v - separation * frontNormal;
- contacts[numContacts].feature = clipPoints2[i].fp;
- if (axis == FACE_B_X || axis == FACE_B_Y)
- Flip(contacts[numContacts].feature);
- ++numContacts;
- }
- }
-
- return numContacts;
- }
-} \ No newline at end of file
diff --git a/Client/Source/Phy2D/Dynamic/Joint.cpp b/Client/Source/Phy2D/Dynamic/Joint.cpp
deleted file mode 100644
index 95f7c64..0000000
--- a/Client/Source/Phy2D/Dynamic/Joint.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-#include "Joint.h"
-#include "Body.h"
-#include "World.h"
-
-using namespace Phy2D;
-
-void Joint::Set(Body* b1, Body* b2, const Vec2& anchor)
-{
- body1 = b1;
- body2 = b2;
-
- Mat22 Rot1(body1->rotation);
- Mat22 Rot2(body2->rotation);
- Mat22 Rot1T = Rot1.Transpose();
- Mat22 Rot2T = Rot2.Transpose();
-
- localAnchor1 = Rot1T * (anchor - body1->position);
- localAnchor2 = Rot2T * (anchor - body2->position);
-
- P.Set(0.0f, 0.0f);
-
- softness = 0.0f;
- biasFactor = 0.2f;
-}
-
-void Joint::PreStep(number inv_dt)
-{
- // Pre-compute anchors, mass matrix, and bias.
- Mat22 Rot1(body1->rotation);
- Mat22 Rot2(body2->rotation);
-
- r1 = Rot1 * localAnchor1;
- r2 = Rot2 * localAnchor2;
-
- // deltaV = deltaV0 + K * impulse
- // invM = [(1/m1 + 1/m2) * eye(2) - skew(r1) * invI1 * skew(r1) - skew(r2) * invI2 * skew(r2)]
- // = [1/m1+1/m2 0 ] + invI1 * [r1.y*r1.y -r1.x*r1.y] + invI2 * [r1.y*r1.y -r1.x*r1.y]
- // [ 0 1/m1+1/m2] [-r1.x*r1.y r1.x*r1.x] [-r1.x*r1.y r1.x*r1.x]
- Mat22 K1;
- K1.col1.x = body1->invMass + body2->invMass; K1.col2.x = 0.0f;
- K1.col1.y = 0.0f; K1.col2.y = body1->invMass + body2->invMass;
-
- Mat22 K2;
- K2.col1.x = body1->invI * r1.y * r1.y; K2.col2.x = -body1->invI * r1.x * r1.y;
- K2.col1.y = -body1->invI * r1.x * r1.y; K2.col2.y = body1->invI * r1.x * r1.x;
-
- Mat22 K3;
- K3.col1.x = body2->invI * r2.y * r2.y; K3.col2.x = -body2->invI * r2.x * r2.y;
- K3.col1.y = -body2->invI * r2.x * r2.y; K3.col2.y = body2->invI * r2.x * r2.x;
-
- Mat22 K = K1 + K2 + K3;
- K.col1.x += softness;
- K.col2.y += softness;
-
- M = K.Invert();
-
- Vec2 p1 = body1->position + r1;
- Vec2 p2 = body2->position + r2;
- Vec2 dp = p2 - p1;
-
- if (World::positionCorrection)
- {
- bias = -biasFactor * inv_dt * dp;
- }
- else
- {
- bias.Set(0.0f, 0.0f);
- }
-
- if (World::warmStarting)
- {
- // Apply accumulated impulse.
- body1->velocity -= body1->invMass * P;
- body1->angularVelocity -= body1->invI * Cross(r1, P);
-
- body2->velocity += body2->invMass * P;
- body2->angularVelocity += body2->invI * Cross(r2, P);
- }
- else
- {
- P.Set(0.0f, 0.0f);
- }
-}
-
-void Joint::ApplyImpulse()
-{
- Vec2 dv = body2->velocity + Cross(body2->angularVelocity, r2) - body1->velocity - Cross(body1->angularVelocity, r1);
-
- Vec2 impulse;
-
- impulse = M * (bias - dv - softness * P);
-
- body1->velocity -= body1->invMass * impulse;
- body1->angularVelocity -= body1->invI * Cross(r1, impulse);
-
- body2->velocity += body2->invMass * impulse;
- body2->angularVelocity += body2->invI * Cross(r2, impulse);
-
- P += impulse;
-}
-
-
diff --git a/Client/Source/Phy2D/Dynamic/Joint.h b/Client/Source/Phy2D/Dynamic/Joint.h
deleted file mode 100644
index ee08b40..0000000
--- a/Client/Source/Phy2D/Dynamic/Joint.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#pragma once
-
-#include "../Common/Math.h"
-
-namespace Phy2D
-{
-
- struct Body;
-
- struct Joint
- {
- Joint() :
- body1(0), body2(0),
- P(0.0f, 0.0f),
- biasFactor(0.2f), softness(0.0f)
- {}
-
- void Set(Body* body1, Body* body2, const Vec2& anchor);
-
- void PreStep(number inv_dt);
- void ApplyImpulse();
-
- Mat22 M;
- Vec2 localAnchor1, localAnchor2;
- Vec2 r1, r2;
- Vec2 bias;
- Vec2 P; // accumulated impulse
- Body* body1;
- Body* body2;
- number biasFactor;
- number softness;
- };
-
-}
diff --git a/Client/Source/Phy2D/Dynamic/World.cpp b/Client/Source/Phy2D/Dynamic/World.cpp
deleted file mode 100644
index 4f48b69..0000000
--- a/Client/Source/Phy2D/Dynamic/World.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-#include "World.h"
-#include "Body.h"
-#include "Joint.h"
-#include "Arbiter.h"
-
-using namespace Phy2D;
-
-
-using std::vector;
-using std::map;
-using std::pair;
-
-typedef map<ArbiterKey, Arbiter>::iterator ArbIter;
-typedef pair<ArbiterKey, Arbiter> ArbPair;
-
-bool World::accumulateImpulses = true;
-bool World::warmStarting = true;
-bool World::positionCorrection = true;
-
-void World::Add(Body* body)
-{
- bodies.push_back(body);
-}
-
-void World::Add(Joint* joint)
-{
- joints.push_back(joint);
-}
-
-void World::Clear()
-{
- bodies.clear();
- joints.clear();
- arbiters.clear();
-}
-
-void World::BroadPhase()
-{
- // O(n^2) broad-phase
- for (int i = 0; i < (int)bodies.size(); ++i)
- {
- Body* bi = bodies[i];
-
- for (int j = i + 1; j < (int)bodies.size(); ++j)
- {
- Body* bj = bodies[j];
-
- if (bi->invMass == 0.0f && bj->invMass == 0.0f)
- continue;
-
- Arbiter newArb(bi, bj);
- ArbiterKey key(bi, bj);
-
- if (newArb.numContacts > 0)
- {
- ArbIter iter = arbiters.find(key);
- if (iter == arbiters.end())
- {
- arbiters.insert(ArbPair(key, newArb));
- }
- else
- {
- iter->second.Update(newArb.contacts, newArb.numContacts);
- }
- }
- else
- {
- arbiters.erase(key);
- }
- }
- }
-}
-
-void World::Step(number dt)
-{
- number inv_dt = dt > 0.0f ? (number)1.0f / dt : (number)0.0f;
-
- // Determine overlapping bodies and update contact points.
- BroadPhase();
-
- // Integrate forces.
- for (int i = 0; i < (int)bodies.size(); ++i)
- {
- Body* b = bodies[i];
-
- if (b->invMass == 0.0f)
- continue;
-
- b->velocity += dt * (gravity + b->invMass * b->force);
- b->angularVelocity += dt * b->invI * b->torque;
- }
-
- // Perform pre-steps.
- for (ArbIter arb = arbiters.begin(); arb != arbiters.end(); ++arb)
- {
- arb->second.PreStep(inv_dt);
- }
-
- for (int i = 0; i < (int)joints.size(); ++i)
- {
- joints[i]->PreStep(inv_dt);
- }
-
- // Perform iterations
- for (int i = 0; i < iterations; ++i)
- {
- for (ArbIter arb = arbiters.begin(); arb != arbiters.end(); ++arb)
- {
- arb->second.ApplyImpulse();
- }
-
- for (int j = 0; j < (int)joints.size(); ++j)
- {
- joints[j]->ApplyImpulse();
- }
- }
-
- // Integrate Velocities
- for (int i = 0; i < (int)bodies.size(); ++i)
- {
- Body* b = bodies[i];
-
- b->position += dt * b->velocity;
- b->rotation += dt * b->angularVelocity;
-
- b->force.Set(0.0f, 0.0f);
- b->torque = 0.0f;
- }
-}
diff --git a/Client/Source/Phy2D/Dynamic/World.h b/Client/Source/Phy2D/Dynamic/World.h
deleted file mode 100644
index 93c883d..0000000
--- a/Client/Source/Phy2D/Dynamic/World.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-
-#include <vector>
-#include <map>
-#include "../Common/Math.h"
-#include "Arbiter.h"
-
-namespace Phy2D
-{
-
- struct Body;
- struct Joint;
-
- struct World
- {
- World(Vec2 gravity, int iterations) : gravity(gravity), iterations(iterations) {}
-
- void Add(Body* body);
- void Add(Joint* joint);
- void Clear();
-
- void Step(number dt);
-
- void BroadPhase();
-
- std::vector<Body*> bodies;
- std::vector<Joint*> joints;
- std::map<ArbiterKey, Arbiter> arbiters;
- Vec2 gravity;
- int iterations;
- static bool accumulateImpulses;
- static bool warmStarting;
- static bool positionCorrection;
- };
-
-}
diff --git a/Client/Source/Phy2D/Phy2D.h b/Client/Source/Phy2D/Phy2D.h
index d2e97f8..0fc0011 100644
--- a/Client/Source/Phy2D/Phy2D.h
+++ b/Client/Source/Phy2D/Phy2D.h
@@ -2,7 +2,3 @@
// 定点数的物理引擎
-
-#include "Dynamic/World.h"
-#include "Dynamic/Body.h"
-#include "Dynamic/Joint.h"
diff --git a/Client/Source/Phy2D/Shapes/p2CircleShape.h b/Client/Source/Phy2D/Shapes/p2CircleShape.h
deleted file mode 100644
index a13a6ab..0000000
--- a/Client/Source/Phy2D/Shapes/p2CircleShape.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-#include "p2Shape.h"
-
-class p2CircleShape : public p2Shape
-{
-
-};
diff --git a/Client/Source/Phy2D/Shapes/p2PolygonShape.cpp b/Client/Source/Phy2D/Shapes/p2PolygonShape.cpp
deleted file mode 100644
index e69de29..0000000
--- a/Client/Source/Phy2D/Shapes/p2PolygonShape.cpp
+++ /dev/null
diff --git a/Client/Source/Phy2D/Shapes/p2PolygonShape.h b/Client/Source/Phy2D/Shapes/p2PolygonShape.h
deleted file mode 100644
index e69de29..0000000
--- a/Client/Source/Phy2D/Shapes/p2PolygonShape.h
+++ /dev/null
diff --git a/Client/Source/Phy2D/Shapes/p2Shape.h b/Client/Source/Phy2D/Shapes/p2Shape.h
deleted file mode 100644
index 4546314..0000000
--- a/Client/Source/Phy2D/Shapes/p2Shape.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-class p2Shape
-{
-
-};
-
diff --git a/Client/Source/Phy2D/Tests/test.h b/Client/Source/Phy2D/Tests/test.h
index c814e3f..f3459ea 100644
--- a/Client/Source/Phy2D/Tests/test.h
+++ b/Client/Source/Phy2D/Tests/test.h
@@ -3,4 +3,4 @@
#define TEST_MATH 1
#define TEST_P2D 2
-#define TEST TEST_P2D
+#define TEST TEST_MATH
diff --git a/Client/Source/Phy2D/Tests/test_math.cpp b/Client/Source/Phy2D/Tests/test_math.cpp
index e7642c1..f88170d 100644
--- a/Client/Source/Phy2D/Tests/test_math.cpp
+++ b/Client/Source/Phy2D/Tests/test_math.cpp
@@ -4,16 +4,17 @@
#include <iostream>
#include "../Common/Math.h"
+#include "fix32/fix32.hpp"
-using namespace Phy2D;
using namespace std;
int main(int argc, char **argv)
{
- Vec2 a = Vec2(1.f, 2.f);
- Vec2 b = a;
+ Fix32 a = 1.3;
+ Fix32 b = 2.4;
+ Fix32 c = a * b;
- cout << (a+b).ToString();
+ cout << (double)c;
getchar();
diff --git a/Client/Source/Phy2D/Tests/test_p2d.cpp b/Client/Source/Phy2D/Tests/test_p2d.cpp
index 9050ccd..e69de29 100644
--- a/Client/Source/Phy2D/Tests/test_p2d.cpp
+++ b/Client/Source/Phy2D/Tests/test_p2d.cpp
@@ -1,625 +0,0 @@
-#include "test.h"
-#if TEST == TEST_P2D
-
-#include "libfixmath/libfixmath/fixmath.h"
-#include <iostream>
-#include <time.h>
-#include <math.h>
-#include "SDL2/SDL.h"
-#include "../Rendering/Visualize.h"
-#include "imgui/imgui.h"
-#include "imgui/backends/imgui_impl_opengl2.h"
-#include "imgui/backends/imgui_impl_sdl.h"
-
-#include "../Phy2D.h"
-
-using namespace std;
-using namespace Phy2D;
-
-namespace
-{
- Body bodies[200];
- Joint joints[100];
-
- Body* bomb = NULL;
-
- float timeStep = 1.0f / 60.0f;
- int iterations = 10;
- Vec2 gravity(0.0f, -10.0f);
-
- int numBodies = 0;
- int numJoints = 0;
-
- int demoIndex = 0;
-
- int width = 1280;
- int height = 720;
- float zoom = 10.0f;
- float pan_y = 8.0f;
-
- World world(gravity, iterations);
-}
-
-static void DrawBody(Body* body)
-{
- Mat22 R(body->rotation);
- Vec2 x = body->position;
- Vec2 h = 0.5f * body->width;
-
- Vec2 v1 = x + R * Vec2(-h.x, -h.y);
- Vec2 v2 = x + R * Vec2(h.x, -h.y);
- Vec2 v3 = x + R * Vec2(h.x, h.y);
- Vec2 v4 = x + R * Vec2(-h.x, h.y);
-
- if (body == bomb)
- glColor3f(0.4f, 0.9f, 0.4f);
- else
- glColor3f(0.8f, 0.8f, 0.9f);
-
- glBegin(GL_LINE_LOOP);
- glVertex2f(v1.x, v1.y);
- glVertex2f(v2.x, v2.y);
- glVertex2f(v3.x, v3.y);
- glVertex2f(v4.x, v4.y);
- glEnd();
-}
-
-static void DrawJoint(Joint* joint)
-{
- Body* b1 = joint->body1;
- Body* b2 = joint->body2;
-
- Mat22 R1(b1->rotation);
- Mat22 R2(b2->rotation);
-
- Vec2 x1 = b1->position;
- Vec2 p1 = x1 + R1 * joint->localAnchor1;
-
- Vec2 x2 = b2->position;
- Vec2 p2 = x2 + R2 * joint->localAnchor2;
-
- glColor3f(0.5f, 0.5f, 0.8f);
- glBegin(GL_LINES);
- glVertex2f(x1.x, x1.y);
- glVertex2f(p1.x, p1.y);
- glVertex2f(x2.x, x2.y);
- glVertex2f(p2.x, p2.y);
- glEnd();
-}
-
-static void Demo1(Body* b, Joint* j)
-{
- float x, y;
-
- b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
- b->position.Set(0.0f, (number)-0.5f * b->width.y);
- world.Add(b);
- ++b; ++numBodies;
-
- b->Set(Vec2(1.0f, 1.0f), 200.0f);
- b->position.Set(0.0f, 4.0f);
- world.Add(b);
- ++b; ++numBodies;
-}
-
-// A simple pendulum
-static void Demo2(Body* b, Joint* j)
-{
- Body* b1 = b + 0;
- b1->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
- b1->friction = 0.2f;
- b1->position.Set(0.0f, (number)-0.5f * b1->width.y);
- b1->rotation = 0.0f;
- world.Add(b1);
-
- Body* b2 = b + 1;
- b2->Set(Vec2(1.0f, 1.0f), 100.0f);
- b2->friction = 0.2f;
- b2->position.Set(9.0f, 11.0f);
- b2->rotation = 0.0f;
- world.Add(b2);
-
- numBodies += 2;
-
- j->Set(b1, b2, Vec2(0.0f, 11.0f));
- world.Add(j);
-
- numJoints += 1;
-}
-
-// Varying friction coefficients
-static void Demo3(Body* b, Joint* j)
-{
- b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
- b->position.Set(0.0f, (number)-0.5f * b->width.y);
- world.Add(b);
- ++b; ++numBodies;
-
- b->Set(Vec2(13.0f, 0.25f), NUMBER_MAX);
- b->position.Set(-2.0f, 11.0f);
- b->rotation = -0.25f;
- world.Add(b);
- ++b; ++numBodies;
-
- b->Set(Vec2(0.25f, 1.0f), NUMBER_MAX);
- b->position.Set(5.25f, 9.5f);
- world.Add(b);
- ++b; ++numBodies;
-
- b->Set(Vec2(13.0f, 0.25f), NUMBER_MAX);
- b->position.Set(2.0f, 7.0f);
- b->rotation = 0.25f;
- world.Add(b);
- ++b; ++numBodies;
-
- b->Set(Vec2(0.25f, 1.0f), NUMBER_MAX);
- b->position.Set(-5.25f, 5.5f);
- world.Add(b);
- ++b; ++numBodies;
-
- b->Set(Vec2(13.0f, 0.25f), NUMBER_MAX);
- b->position.Set(-2.0f, 3.0f);
- b->rotation = -0.25f;
- world.Add(b);
- ++b; ++numBodies;
-
- float friction[5] = { 0.75f, 0.5f, 0.35f, 0.1f, 0.0f };
- for (int i = 0; i < 5; ++i)
- {
- b->Set(Vec2(0.5f, 0.5f), 25.0f);
- b->friction = friction[i];
- b->position.Set(-7.5f + 2.0f * i, 14.0f);
- world.Add(b);
- ++b; ++numBodies;
- }
-}
-
-// A vertical stack
-static void Demo4(Body* b, Joint* j)
-{
- b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
- b->friction = 0.2f;
- b->position.Set(0.0f, (number)-0.5f * b->width.y);
- b->rotation = 0.0f;
- world.Add(b);
- ++b; ++numBodies;
-
- for (int i = 0; i < 10; ++i)
- {
- b->Set(Vec2(1.0f, 1.0f), 1.0f);
- b->friction = 0.2f;
- //float x = Random(-0.1f, 0.1f);
- float x = 0;
- b->position.Set(x, 0.51f + 1.05f * i);
- world.Add(b);
- ++b; ++numBodies;
- }
-}
-
-// A pyramid
-static void Demo5(Body* b, Joint* j)
-{
- b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
- b->friction = 0.2f;
- b->position.Set(0.0f, (number)-0.5f * b->width.y);
- b->rotation = 0.0f;
- world.Add(b);
- ++b; ++numBodies;
-
- Vec2 x(-6.0f, 0.75f);
- Vec2 y;
-
- for (int i = 0; i < 12; ++i)
- {
- y = x;
-
- for (int j = i; j < 12; ++j)
- {
- b->Set(Vec2(1.0f, 1.0f), 10.0f);
- b->friction = 0.2f;
- b->position = y;
- world.Add(b);
- ++b; ++numBodies;
-
- y += Vec2(1.125f, 0.0f);
- }
-
- //x += Vec2(0.5625f, 1.125f);
- x += Vec2(0.5625f, 2.0f);
- }
-}
-
-// A teeter
-static void Demo6(Body* b, Joint* j)
-{
- Body* b1 = b + 0;
- b1->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
- b1->position.Set(0.0f, (number)-0.5f * b1->width.y);
- world.Add(b1);
-
- Body* b2 = b + 1;
- b2->Set(Vec2(12.0f, 0.25f), 100.0f);
- b2->position.Set(0.0f, 1.0f);
- world.Add(b2);
-
- Body* b3 = b + 2;
- b3->Set(Vec2(0.5f, 0.5f), 25.0f);
- b3->position.Set(-5.0f, 2.0f);
- world.Add(b3);
-
- Body* b4 = b + 3;
- b4->Set(Vec2(0.5f, 0.5f), 25.0f);
- b4->position.Set(-5.5f, 2.0f);
- world.Add(b4);
-
- Body* b5 = b + 4;
- b5->Set(Vec2(1.0f, 1.0f), 100.0f);
- b5->position.Set(5.5f, 15.0f);
- world.Add(b5);
-
- numBodies += 5;
-
- j->Set(b1, b2, Vec2(0.0f, 1.0f));
- world.Add(j);
-
- numJoints += 1;
-}
-
-// A suspension bridge
-static void Demo7(Body* b, Joint* j)
-{
- b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
- b->friction = 0.2f;
- b->position.Set(0.0f, (number)-0.5f * b->width.y);
- b->rotation = 0.0f;
- world.Add(b);
- ++b; ++numBodies;
-
- const int numPlanks = 15;
- float mass = 50.0f;
-
- for (int i = 0; i < numPlanks; ++i)
- {
- b->Set(Vec2(1.0f, 0.25f), mass);
- b->friction = 0.2f;
- b->position.Set(-8.5f + 1.25f * i, 5.0f);
- world.Add(b);
- ++b; ++numBodies;
- }
-
- // Tuning
- float frequencyHz = 2.0f;
- float dampingRatio = 0.7f;
-
- // frequency in radians
- float omega = (number)2.0f * fix16_pi * frequencyHz;
-
- // damping coefficient
- float d = 2.0f * mass * dampingRatio * omega;
-
- // spring stifness
- float k = mass * omega * omega;
-
- // magic formulas
- float softness = 1.0f / (d + timeStep * k);
- float biasFactor = timeStep * k / (d + timeStep * k);
-
- for (int i = 0; i < numPlanks; ++i)
- {
- j->Set(bodies + i, bodies + i + 1, Vec2(-9.125f + 1.25f * i, 5.0f));
- j->softness = softness;
- j->biasFactor = biasFactor;
-
- world.Add(j);
- ++j; ++numJoints;
- }
-
- j->Set(bodies + numPlanks, bodies, Vec2(-9.125f + 1.25f * numPlanks, 5.0f));
- j->softness = softness;
- j->biasFactor = biasFactor;
- world.Add(j);
- ++j; ++numJoints;
-}
-
-// Dominos
-static void Demo8(Body* b, Joint* j)
-{
- Body* b1 = b;
- b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
- b->position.Set(0.0f, (number)-0.5f * b->width.y);
- world.Add(b);
- ++b; ++numBodies;
-
- b->Set(Vec2(12.0f, 0.5f), NUMBER_MAX);
- b->position.Set(-1.5f, 10.0f);
- world.Add(b);
- ++b; ++numBodies;
-
- for (int i = 0; i < 10; ++i)
- {
- b->Set(Vec2(0.2f, 2.0f), 10.0f);
- b->position.Set(-6.0f + 1.0f * i, 11.125f);
- b->friction = 0.1f;
- world.Add(b);
- ++b; ++numBodies;
- }
-
- b->Set(Vec2(14.0f, 0.5f), NUMBER_MAX);
- b->position.Set(1.0f, 6.0f);
- b->rotation = 0.3f;
- world.Add(b);
- ++b; ++numBodies;
-
- Body* b2 = b;
- b->Set(Vec2(0.5f, 3.0f), NUMBER_MAX);
- b->position.Set(-7.0f, 4.0f);
- world.Add(b);
- ++b; ++numBodies;
-
- Body* b3 = b;
- b->Set(Vec2(12.0f, 0.25f), 20.0f);
- b->position.Set(-0.9f, 1.0f);
- world.Add(b);
- ++b; ++numBodies;
-
- j->Set(b1, b3, Vec2(-2.0f, 1.0f));
- world.Add(j);
- ++j; ++numJoints;
-
- Body* b4 = b;
- b->Set(Vec2(0.5f, 0.5f), 10.0f);
- b->position.Set(-10.0f, 15.0f);
- world.Add(b);
- ++b; ++numBodies;
-
- j->Set(b2, b4, Vec2(-7.0f, 15.0f));
- world.Add(j);
- ++j; ++numJoints;
-
- Body* b5 = b;
- b->Set(Vec2(2.0f, 2.0f), 20.0f);
- b->position.Set(6.0f, 2.5f);
- b->friction = 0.1f;
- world.Add(b);
- ++b; ++numBodies;
-
- j->Set(b1, b5, Vec2(6.0f, 2.6f));
- world.Add(j);
- ++j; ++numJoints;
-
- Body* b6 = b;
- b->Set(Vec2(2.0f, 0.2f), 10.0f);
- b->position.Set(6.0f, 3.6f);
- world.Add(b);
- ++b; ++numBodies;
-
- j->Set(b5, b6, Vec2(7.0f, 3.5f));
- world.Add(j);
- ++j; ++numJoints;
-}
-
-// A multi-pendulum
-static void Demo9(Body* b, Joint* j)
-{
- b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
- b->friction = 0.2f;
- b->position.Set(0.0f, (number)-0.5f * b->width.y);
- b->rotation = 0.0f;
- world.Add(b);
-
- Body * b1 = b;
- ++b;
- ++numBodies;
-
- float mass = 10.0f;
-
- // Tuning
- float frequencyHz = 4.0f;
- float dampingRatio = 0.7f;
-
- // frequency in radians
- float omega = (number) 2.0f * fix16_pi * frequencyHz;
-
- // damping coefficient
- float d = 2.0f * mass * dampingRatio * omega;
-
- // spring stiffness
- float k = mass * omega * omega;
-
- // magic formulas
- float softness = 1.0f / (d + timeStep * k);
- float biasFactor = timeStep * k / (d + timeStep * k);
-
- const float y = 12.0f;
-
- for (int i = 0; i < 15; ++i)
- {
- Vec2 x(0.5f + i, y);
- b->Set(Vec2(0.75f, 0.25f), mass);
- b->friction = 0.2f;
- b->position = x;
- b->rotation = 0.0f;
- world.Add(b);
-
- j->Set(b1, b, Vec2(float(i), y));
- j->softness = softness;
- j->biasFactor = biasFactor;
- world.Add(j);
-
- b1 = b;
- ++b;
- ++numBodies;
- ++j;
- ++numJoints;
- }
-}
-
-static void InitDemo()
-{
- world.Clear();
- numBodies = 0;
- numJoints = 0;
- bomb = NULL;
-
- demoIndex = 0;
- Demo5(bodies, joints);
-}
-
-int main(int argc, char **argv) {
-
- // Setup SDL
- // (Some versions of SDL before <2.0.10 appears to have performance/stalling issues on a minority of Windows systems,
- // depending on whether SDL_INIT_GAMECONTROLLER is enabled or disabled.. updating to latest version of SDL is recommended!)
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
- {
- printf("Error: %s\n", SDL_GetError());
- return -1;
- }
-
- // Setup window
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
- SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
- SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
- SDL_Window* window = SDL_CreateWindow("Phy2D", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, window_flags);
- SDL_GLContext gl_context = SDL_GL_CreateContext(window);
-
- if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) {
- std::cerr << "Failed to initialize the OpenGL context." << std::endl;
- exit(1);
- }
-
- SDL_GL_MakeCurrent(window, gl_context);
- SDL_GL_SetSwapInterval(1); // Enable vsync
-
- // Setup Dear ImGui context
- IMGUI_CHECKVERSION();
- ImGui::CreateContext();
- ImGuiIO& io = ImGui::GetIO(); (void)io;
- //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
- //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
-
- // Setup Dear ImGui style
- ImGui::StyleColorsDark();
- //ImGui::StyleColorsClassic();
-
- // Setup Platform/Renderer backends
- ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
- ImGui_ImplOpenGL2_Init();
-
- // Load Fonts
- // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
- // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
- // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
- // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
- // - Read 'docs/FONTS.md' for more instructions and details.
- // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
- //io.Fonts->AddFontDefault();
- //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
- //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
- //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
- //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f);
- //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
- //IM_ASSERT(font != NULL);
-
- // Our state
- bool show_demo_window = true;
- bool show_another_window = false;
- ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
-
- glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-
- float aspect = float(width) / float(height);
- if (width >= height)
- {
- // aspect >= 1, set the height from -1 to 1, with larger width
- glOrtho(-zoom * aspect, zoom * aspect, -zoom + pan_y, zoom + pan_y, -1.0, 1.0);
- }
- else
- {
- // aspect < 1, set the width to -1 to 1, with larger height
- glOrtho(-zoom, zoom, -zoom / aspect + pan_y, zoom / aspect + pan_y, -1.0, 1.0);
- }
-
- InitDemo();
-
- // Main loop
- bool done = false;
- while (!done)
- {
- //glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- // Poll and handle events (inputs, window resize, etc.)
- // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
- // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
- // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
- // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
- SDL_Event event;
- while (SDL_PollEvent(&event))
- {
- ImGui_ImplSDL2_ProcessEvent(&event);
- if (event.type == SDL_QUIT)
- done = true;
- if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
- done = true;
- }
-
- // Start the Dear ImGui frame
- ImGui_ImplOpenGL2_NewFrame();
- ImGui_ImplSDL2_NewFrame();
- ImGui::NewFrame();
-
- // Rendering
- ImGui::Render();
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- world.Step(timeStep);
-
- for (int i = 0; i < numBodies; ++i)
- DrawBody(bodies + i);
-
- for (int i = 0; i < numJoints; ++i)
- DrawJoint(joints + i);
-
- glPointSize(4.0f);
- glColor3f(1.0f, 0.0f, 0.0f);
- glBegin(GL_POINTS);
- std::map<ArbiterKey, Arbiter>::const_iterator iter;
- for (iter = world.arbiters.begin(); iter != world.arbiters.end(); ++iter)
- {
- const Arbiter& arbiter = iter->second;
- for (int i = 0; i < arbiter.numContacts; ++i)
- {
- Vec2 p = arbiter.contacts[i].position;
- glVertex2f(p.x, p.y);
- }
- }
- glEnd();
- glPointSize(1.0f);
-
- //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound
- ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
- SDL_GL_SwapWindow(window);
- }
-
- // Cleanup
- ImGui_ImplOpenGL2_Shutdown();
- ImGui_ImplSDL2_Shutdown();
- ImGui::DestroyContext();
-
- SDL_GL_DeleteContext(gl_context);
- SDL_DestroyWindow(window);
- SDL_Quit();
-
- return 0;
-}
-
-#endif \ No newline at end of file
diff --git a/Client/Source/Phy2DLite/Constants.h b/Client/Source/Phy2DLite/Constants.h
index f116ca8..59a8c09 100644
--- a/Client/Source/Phy2DLite/Constants.h
+++ b/Client/Source/Phy2DLite/Constants.h
@@ -5,7 +5,7 @@
namespace Phy2D
{
#if NUMBER_ALIAS == NUMBER_FPM
-#define CONSTANT(name, value) static fixed name = fixed::from_raw_value(value)
+#define CONSTANT(name, value) static constexpr fixed name = fixed::from_raw_value(value)
CONSTANT(_1, 65536);
CONSTANT(_n1, -65536);
@@ -16,5 +16,27 @@ namespace Phy2D
CONSTANT(_0_95, 62259);
CONSTANT(_12, 786432);
+#elif NUMBER_ALIAS == NUMBER_FLOAT
+
+ static const float _1 = 1;
+ static const float _n1 = -1;
+ static const float _0 = 0;
+ static const float _0_01 = 0.01;
+ static const float _0_2 = 0.2;
+ static const float _0_5 = 0.5;
+ static const float _0_95 = 0.95;
+ static const float _12 = 12;
+
+#elif NUMBER_ALIAS == NUMBER_FIX32
+
+ static const float _1 = 1;
+ static const float _n1 = -1;
+ static const float _0 = 0;
+ static const float _0_01 = 0.01;
+ static const float _0_2 = 0.2;
+ static const float _0_5 = 0.5;
+ static const float _0_95 = 0.95;
+ static const float _12 = 12;
+
#endif
} \ No newline at end of file
diff --git a/Client/Source/Phy2DLite/Settings.h b/Client/Source/Phy2DLite/Settings.h
index 9345b32..6454943 100644
--- a/Client/Source/Phy2DLite/Settings.h
+++ b/Client/Source/Phy2DLite/Settings.h
@@ -1,16 +1,19 @@
#pragma once
-#define NUMBER_FLOAT 1
-#define NUMBER_LIBFIX 2
-#define NUMBER_FPM 3
+#define NUMBER_FLOAT 1
+#define NUMBER_LIBFIX 2
+#define NUMBER_FPM 3
+#define NUMBER_FIX32 4
-#define NUMBER_ALIAS NUMBER_FPM
+#define NUMBER_ALIAS NUMBER_FIX32
#if NUMBER_ALIAS == NUMBER_LIBFIX
#include "libfixmath/libfixmath/fixmath.h"
#elif NUMBER_ALIAS == NUMBER_FPM
#include "fpm/include/fpm/fixed.hpp"
#include "fpm/include/fpm/math.hpp"
+#elif NUMBER_ALIAS == NUMBER_FIX32
+#include "fix32/fix32.hpp"
#endif
namespace Phy2D
@@ -24,10 +27,10 @@ typedef float fixed;
#define SQRT(a) (sqrt((a)))
#define SIN(a) (sin((a)))
#define COS(a) (cos((a)))
+#define PI (3.1415925f)
#elif NUMBER_ALIAS == NUMBER_LIBFIX
-// 同时一定要开启内联函数扩展,否则执行效率会非常低
typedef Fix16 fixed;
#define NUMBER_MAX (fix16_maximum)
#define NUMBER_MIN (fix16_minimum)
@@ -91,6 +94,16 @@ typedef fpm::fixed_16_16 fixed;
#define COS(a) (fpm::cos((a)))
#define PI (fixed::pi())
+#elif NUMBER_ALIAS == NUMBER_FIX32
+
+ typedef Fix32 fixed;
+#define NUMBER_MAX (CONST_MAX)
+#define NUMBER_MIN (CONST_MIN)
+#define SQRT(a) ((a).sqrt())
+#define SIN(a) ((a).sin())
+#define COS(a) ((a).cos())
+#define PI (CONST_PI)
+
#endif
} \ No newline at end of file
diff --git a/Client/Source/Phy2DLite/World.cpp b/Client/Source/Phy2DLite/World.cpp
index f20be5f..76e57ea 100644
--- a/Client/Source/Phy2DLite/World.cpp
+++ b/Client/Source/Phy2DLite/World.cpp
@@ -73,7 +73,7 @@ void World::BroadPhase()
void World::Step(fixed dt)
{
- fixed inv_dt = dt > _0 ? _1 / dt : _0;
+ fixed inv_dt = dt > _0 ? (fixed)_1 / dt : (fixed)_0;
// Determine overlapping bodies and update contact points.
BroadPhase();
diff --git a/Client/ThirdParty/fix32/fix32.cpp b/Client/ThirdParty/fix32/fix32.cpp
deleted file mode 100644
index e69de29..0000000
--- a/Client/ThirdParty/fix32/fix32.cpp
+++ /dev/null
diff --git a/Client/ThirdParty/fix32/fix32.h b/Client/ThirdParty/fix32/fix32.h
deleted file mode 100644
index fb3d65c..0000000
--- a/Client/ThirdParty/fix32/fix32.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-
-// -2,147,483,648 to 2,147,483,647
-typedef int64_t fix32_t;
-
diff --git a/Client/ThirdParty/fix32/fix32.hpp b/Client/ThirdParty/fix32/fix32.hpp
new file mode 100644
index 0000000..7999ad4
--- /dev/null
+++ b/Client/ThirdParty/fix32/fix32.hpp
@@ -0,0 +1,161 @@
+#pragma once
+
+#include <stdint.h>
+extern "C" {
+#include "math-sll/math-sll.h"
+}
+
+typedef sll fixed32_t;
+
+// Q32.32
+class Fix32
+{
+public:
+ sll value;
+
+ inline Fix32() { value = 0; }
+ inline Fix32(const Fix32 &inValue) { value = inValue.value; }
+ inline Fix32(const float inValue) { value = dbl2sll(inValue); }
+ inline Fix32(const double inValue) { value = dbl2sll(inValue); }
+ inline Fix32(const int32_t inValue) { value = int2sll(inValue); }
+ inline Fix32(const sll inValue) { value = inValue; }
+
+ inline operator sll() const { return value; }
+ inline operator double() const { return sll2dbl(value); }
+ inline operator float() const { return (float)sll2dbl(value); }
+ inline operator int32_t() const { return (int32_t)sll2int(value); }
+
+ inline Fix32 & operator=(const Fix32 &rhs) { value = rhs.value; return *this; }
+ inline Fix32 & operator=(const sll rhs) { value = rhs; return *this; }
+ inline Fix32 & operator=(const double rhs) { value = dbl2sll(rhs); return *this; }
+ inline Fix32 & operator=(const float rhs) { value = (float)dbl2sll(rhs); return *this; }
+ inline Fix32 & operator=(const int32_t rhs) { value = int2sll(rhs); return *this; }
+
+ inline Fix32 & operator+=(const Fix32 &rhs) { value += rhs.value; return *this; }
+ inline Fix32 & operator+=(const sll rhs) { value += rhs; return *this; }
+ inline Fix32 & operator+=(const double rhs) { value += dbl2sll(rhs); return *this; }
+ inline Fix32 & operator+=(const float rhs) { value += (float)dbl2sll(rhs); return *this; }
+ inline Fix32 & operator+=(const int32_t rhs) { value += int2sll(rhs); return *this; }
+
+ inline Fix32 & operator-=(const Fix32 &rhs) { value -= rhs.value; return *this; }
+ inline Fix32 & operator-=(const sll rhs) { value -= rhs; return *this; }
+ inline Fix32 & operator-=(const double rhs) { value -= dbl2sll(rhs); return *this; }
+ inline Fix32 & operator-=(const float rhs) { value -= (float)dbl2sll(rhs); return *this; }
+ inline Fix32 & operator-=(const int32_t rhs) { value -= int2sll(rhs); return *this; }
+
+ inline Fix32 & operator*=(const Fix32 &rhs) { value = sllmul(value, rhs.value); return *this; }
+ inline Fix32 & operator*=(const sll rhs) { value = sllmul(value, rhs); return *this; }
+ inline Fix32 & operator*=(const double rhs) { value = sllmul(value, dbl2sll(rhs)); return *this; }
+ inline Fix32 & operator*=(const float rhs) { value = sllmul(value, (float)dbl2sll(rhs)); return *this; }
+ inline Fix32 & operator*=(const int32_t rhs) { value *= rhs; return *this; }
+
+ inline Fix32 & operator/=(const Fix32 &rhs) { value = slldiv(value, rhs.value); return *this; }
+ inline Fix32 & operator/=(const sll rhs) { value = slldiv(value, rhs); return *this; }
+ inline Fix32 & operator/=(const double rhs) { value = slldiv(value, dbl2sll(rhs)); return *this; }
+ inline Fix32 & operator/=(const float rhs) { value = slldiv(value, (float)dbl2sll(rhs)); return *this; }
+ inline Fix32 & operator/=(const int32_t rhs) { value /= rhs; return *this; }
+
+ inline const Fix32 operator+(const Fix32 &other) const { Fix32 ret = *this; ret += other; return ret; }
+ inline const Fix32 operator+(const sll other) const { Fix32 ret = *this; ret += other; return ret; }
+ inline const Fix32 operator+(const double other) const { Fix32 ret = *this; ret += other; return ret; }
+ inline const Fix32 operator+(const float other) const { Fix32 ret = *this; ret += other; return ret; }
+ inline const Fix32 operator+(const int32_t other) const { Fix32 ret = *this; ret += other; return ret; }
+
+#ifndef FIXMATH_NO_OVERFLOW
+ inline const Fix32 sadd(const Fix32 &other) const { Fix32 ret = slladd(value, other.value); return ret; }
+ inline const Fix32 sadd(const sll other) const { Fix32 ret = slladd(value, other); return ret; }
+ inline const Fix32 sadd(const double other) const { Fix32 ret = slladd(value, dbl2sll(other)); return ret; }
+ inline const Fix32 sadd(const float other) const { Fix32 ret = slladd(value, (float)dbl2sll(other)); return ret; }
+ inline const Fix32 sadd(const int32_t other) const { Fix32 ret = slladd(value, int2sll(other)); return ret; }
+#endif
+
+ inline const Fix32 operator-(const Fix32 &other) const { Fix32 ret = *this; ret -= other; return ret; }
+ inline const Fix32 operator-(const sll other) const { Fix32 ret = *this; ret -= other; return ret; }
+ inline const Fix32 operator-(const double other) const { Fix32 ret = *this; ret -= other; return ret; }
+ inline const Fix32 operator-(const float other) const { Fix32 ret = *this; ret -= other; return ret; }
+ inline const Fix32 operator-(const int32_t other) const { Fix32 ret = *this; ret -= other; return ret; }
+
+ inline const Fix32 operator-() const { Fix32 ret = sllsub(0, value); return ret; }
+
+#ifndef FIXMATH_NO_OVERFLOW
+ inline const Fix32 ssub(const Fix32 &other) const { Fix32 ret = slladd(value, -other.value); return ret; }
+ inline const Fix32 ssub(const sll other) const { Fix32 ret = slladd(value, -other); return ret; }
+ inline const Fix32 ssub(const double other) const { Fix32 ret = slladd(value, -dbl2sll(other)); return ret; }
+ inline const Fix32 ssub(const float other) const { Fix32 ret = slladd(value, -(float)dbl2sll(other)); return ret; }
+ inline const Fix32 ssub(const int32_t other) const { Fix32 ret = slladd(value, -int2sll(other)); return ret; }
+#endif
+
+ inline const Fix32 operator*(const Fix32 &other) const { Fix32 ret = *this; ret *= other; return ret; }
+ inline const Fix32 operator*(const sll other) const { Fix32 ret = *this; ret *= other; return ret; }
+ inline const Fix32 operator*(const double other) const { Fix32 ret = *this; ret *= other; return ret; }
+ inline const Fix32 operator*(const float other) const { Fix32 ret = *this; ret *= other; return ret; }
+ inline const Fix32 operator*(const int32_t other) const { Fix32 ret = *this; ret *= other; return ret; }
+
+#ifndef FIXMATH_NO_OVERFLOW
+ inline const Fix32 smul(const Fix32 &other) const { Fix32 ret = sllmul(value, other.value); return ret; }
+ inline const Fix32 smul(const sll other) const { Fix32 ret = sllmul(value, other); return ret; }
+ inline const Fix32 smul(const double other) const { Fix32 ret = sllmul(value, dbl2sll(other)); return ret; }
+ inline const Fix32 smul(const float other) const { Fix32 ret = sllmul(value, (float)dbl2sll(other)); return ret; }
+ inline const Fix32 smul(const int32_t other) const { Fix32 ret = sllmul(value, int2sll(other)); return ret; }
+#endif
+
+ inline const Fix32 operator/(const Fix32 &other) const { Fix32 ret = *this; ret /= other; return ret; }
+ inline const Fix32 operator/(const sll other) const { Fix32 ret = *this; ret /= other; return ret; }
+ inline const Fix32 operator/(const double other) const { Fix32 ret = *this; ret /= other; return ret; }
+ inline const Fix32 operator/(const float other) const { Fix32 ret = *this; ret /= other; return ret; }
+ inline const Fix32 operator/(const int32_t other) const { Fix32 ret = *this; ret /= other; return ret; }
+
+#ifndef FIXMATH_NO_OVERFLOW
+ inline const Fix32 sdiv(const Fix32 &other) const { Fix32 ret = slldiv(value, other.value); return ret; }
+ inline const Fix32 sdiv(const sll other) const { Fix32 ret = slldiv(value, other); return ret; }
+ inline const Fix32 sdiv(const double other) const { Fix32 ret = slldiv(value, dbl2sll(other)); return ret; }
+ inline const Fix32 sdiv(const float other) const { Fix32 ret = slldiv(value, (float)dbl2sll(other)); return ret; }
+ inline const Fix32 sdiv(const int32_t other) const { Fix32 ret = slldiv(value, int2sll(other)); return ret; }
+#endif
+
+ inline int operator==(const Fix32 &other) const { return (value == other.value); }
+ inline int operator==(const sll other) const { return (value == other); }
+ inline int operator==(const double other) const { return (value == dbl2sll(other)); }
+ inline int operator==(const float other) const { return (value == (float)dbl2sll(other)); }
+ inline int operator==(const int32_t other) const { return (value == int2sll(other)); }
+
+ inline int operator!=(const Fix32 &other) const { return (value != other.value); }
+ inline int operator!=(const sll other) const { return (value != other); }
+ inline int operator!=(const double other) const { return (value != dbl2sll(other)); }
+ inline int operator!=(const float other) const { return (value != (float)dbl2sll(other)); }
+ inline int operator!=(const int32_t other) const { return (value != int2sll(other)); }
+
+ inline int operator<=(const Fix32 &other) const { return (value <= other.value); }
+ inline int operator<=(const sll other) const { return (value <= other); }
+ inline int operator<=(const double other) const { return (value <= dbl2sll(other)); }
+ inline int operator<=(const float other) const { return (value <= (float)dbl2sll(other)); }
+ inline int operator<=(const int32_t other) const { return (value <= int2sll(other)); }
+
+ inline int operator>=(const Fix32 &other) const { return (value >= other.value); }
+ inline int operator>=(const sll other) const { return (value >= other); }
+ inline int operator>=(const double other) const { return (value >= dbl2sll(other)); }
+ inline int operator>=(const float other) const { return (value >= (float)dbl2sll(other)); }
+ inline int operator>=(const int32_t other) const { return (value >= int2sll(other)); }
+
+ inline int operator< (const Fix32 &other) const { return (value < other.value); }
+ inline int operator< (const sll other) const { return (value < other); }
+ inline int operator< (const double other) const { return (value < dbl2sll(other)); }
+ inline int operator< (const float other) const { return (value < (float)dbl2sll(other)); }
+ inline int operator< (const int32_t other) const { return (value < int2sll(other)); }
+
+ inline int operator> (const Fix32 &other) const { return (value > other.value); }
+ inline int operator> (const sll other) const { return (value > other); }
+ inline int operator> (const double other) const { return (value > dbl2sll(other)); }
+ inline int operator> (const float other) const { return (value > (float)dbl2sll(other)); }
+ inline int operator> (const int32_t other) const { return (value > int2sll(other)); }
+
+ inline Fix32 sin() const { return Fix32(sllsin(value)); }
+ inline Fix32 cos() const { return Fix32(sllcos(value)); }
+ inline Fix32 tan() const { return Fix32(slltan(value)); }
+ inline Fix32 asin() const { return Fix32(sllasin(value)); }
+ inline Fix32 acos() const { return Fix32(sllacos(value)); }
+ inline Fix32 atan() const { return Fix32(sllatan(value)); }
+ //inline Fix32 atan2(const Fix32 &inY) const { return Fix32(fix16_atan2(value, inY.value)); }
+ inline Fix32 sqrt() const { return Fix32(sllsqrt(value)); }
+
+}; \ No newline at end of file
diff --git a/Client/ThirdParty/math-sll/LICENSE b/Client/ThirdParty/math-sll/LICENSE
new file mode 100644
index 0000000..4e683cf
--- /dev/null
+++ b/Client/ThirdParty/math-sll/LICENSE
@@ -0,0 +1,23 @@
+
+Licensed under the terms of the MIT license:
+
+Copyright (c) 2000,2002,2006,2012,2016 Andrew E. Mileski <andrewm@isoar.ca>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The copyright notice, and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
diff --git a/Client/ThirdParty/math-sll/Makefile b/Client/ThirdParty/math-sll/Makefile
new file mode 100644
index 0000000..b7b512f
--- /dev/null
+++ b/Client/ThirdParty/math-sll/Makefile
@@ -0,0 +1,69 @@
+#
+# Licensed under the terms of the MIT license:
+#
+# Copyright (c) 2000,2002,2006,2012,2016 Andrew E. Mileski <andrewm@isoar.ca>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The copyright notice, and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+
+#
+# Installation directories
+#
+
+PREFIX := /usr/local
+INCDIR := $(PREFIX)/include
+LIBDIR := $(PREFIX)/lib
+
+#
+# Executables
+#
+
+AR := ar
+CC := gcc
+CFLAGS := -O2 -W -Wall
+INSTALL := install
+RANLIB := ranlib
+RM := rm -f
+STRIP := strip --strip-unneeded
+
+#
+# Recipes
+#
+
+OBJS := math-sll.o
+LIBS := math-sll.a
+
+.PHONY: all clean install
+
+all: $(LIBS)
+
+clean:
+ $(RM) $(LIBS) $(OBJS)
+
+install: $(LIBS) math-sll.h
+ $(INSTALL) -m a=rx,u+w math-sll.a $(LIBDIR)
+ $(INSTALL) -m a=r,u+w math-sll.h $(INCDIR)
+
+math-sll.o: math-sll.c math-sll.h
+
+math-sll.a: math-sll.o
+ $(STRIP) $<
+ $(AR) rcs $@ $<
+ $(RANLIB) $@
+
diff --git a/Client/ThirdParty/math-sll/README b/Client/ThirdParty/math-sll/README
new file mode 100644
index 0000000..e53ca36
--- /dev/null
+++ b/Client/ThirdParty/math-sll/README
@@ -0,0 +1,51 @@
+
+math-sll
+
+ A fixed point (32.32 bit) math library.
+
+ See math-sll.h for details.
+
+License
+
+ Licensed under the terms of the MIT license as of revision v1.19
+
+ See the LICENSE file for details.
+
+ Earlier revisions were licensed under the terms of GPL or LGPL.
+
+Installation
+
+ The source can be added as-is into your project, or a library can optionally
+ be built and installed, then statically-linked into your project.
+
+ To build:
+
+ make clean
+ make all
+
+ Optionally:
+
+ make install
+
+ The default installation path prefix is /usr/local
+
+ See the Makefile for details.
+
+Repository
+
+ A math-sll project is being maintained at:
+
+ http://github.com/aemileski/math-sll
+
+ You can also obtain a copy of the latest source code directly via GIT:
+
+ git clone git://github.com/aemileski/math-sll.git
+
+Contact
+
+ Feel free to contact me with questions, bug reports, patches, feature
+ requests, etc., or just to tell me about how you are using math-sll in
+ your project!
+
+ Andrew E. Mileski <andrewm@isoar.ca>
+
diff --git a/Client/ThirdParty/math-sll/math-sll.c b/Client/ThirdParty/math-sll/math-sll.c
new file mode 100644
index 0000000..ecc4238
--- /dev/null
+++ b/Client/ThirdParty/math-sll/math-sll.c
@@ -0,0 +1,957 @@
+/*
+ * Revision v1.24
+ *
+ * Credits
+ *
+ * Maintained, conceived, written, and fiddled with by:
+ *
+ * Andrew E. Mileski <andrewm@isoar.ca>
+ *
+ * Other source code contributors:
+ *
+ * Kevin Rockel
+ * Kevin Michael Woley
+ * Mark Anthony Lisher
+ * Nicolas Pitre
+ * Anonymous
+ *
+ * License
+ *
+ * Licensed under the terms of the MIT license:
+ *
+ * Copyright (c) 2000,2002,2006,2012,2016 Andrew E. Mileski <andrewm@isoar.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The copyright notice, and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* See header for full details */
+#include "math-sll.h"
+
+/*
+ * Local prototypes
+ */
+
+static sll _sllcos(sll x);
+static sll _sllsin(sll x);
+
+static sll _sllexp(sll x);
+
+/*
+ * Unpack IEEE 754 floating point double format into fixed point sll format
+ *
+ * Description
+ *
+ * IEEE 754 specifies the binary64 type ("double" in C) as having:
+ *
+ * 1 bit sign
+ * 11 bit exponent
+ * 53 bit significand
+ *
+ * The first bit of the significand is an implied 1 which is not stored.
+ * The decimal would be to the right of that implied 1, or to the left of
+ * the stored significand.
+ *
+ * The exponent is unsigned, and biased with an offset of 1023.
+ *
+ * The IEEE 754 standard does not specify endianess, but the endian used is
+ * traditionally the same endian that the processor uses.
+ */
+
+sll dbl2sll(double dbl)
+{
+ union {
+ double d;
+ unsigned u[2];
+ ull ull;
+ sll sll;
+ } in, retval;
+ register unsigned exp;
+
+ /* Move into memory as args might be passed in regs */
+ in.d = dbl;
+
+#if defined(BROKEN_IEEE754_DOUBLE)
+
+ exp = in.u[0];
+ in.u[0] = in.u[1];
+ in.u[1] = exp;
+
+#endif /* defined(BROKEN_IEEE754_DOUBLE) */
+
+ /* Leading 1 is assumed by IEEE */
+ retval.u[1] = 0x40000000;
+
+ /* Unpack the mantissa into the unsigned long */
+ retval.u[1] |= (in.u[1] << 10) & 0x3ffffc00;
+ retval.u[1] |= (in.u[0] >> 22) & 0x000003ff;
+ retval.u[0] = in.u[0] << 10;
+
+ /* Extract the exponent and align the decimals */
+ exp = (in.u[1] >> 20) & 0x7ff;
+ if (exp)
+ /* IEEE 754 decimal begins at right of bit position 30 */
+ retval.ull >>= (1023 + 30) - exp;
+ else
+ return 0L;
+
+ /* Negate if negative flag set */
+ if (in.u[1] & 0x80000000)
+ retval.sll = _sllneg(retval.sll);
+
+ return retval.sll;
+}
+
+/*
+ * Pack fixed point sll format into IEEE 754 floating point double format
+ *
+ * Description
+ *
+ * IEEE 754 specifies the binary64 type ("double" in C) as having:
+ *
+ * 1 bit sign
+ * 11 bit exponent
+ * 53 bit significand
+ *
+ * The first bit of the significand is an implied 1 which is not stored.
+ * The decimal would be to the right of that implied 1, or to the left of
+ * the stored significand.
+ *
+ * The exponent is unsigned, and biased with an offset of 1023.
+ *
+ * The IEEE 754 standard does not specify endianess, but the endian used is
+ * traditionally the same endian that the processor uses.
+ */
+
+double sll2dbl(sll s)
+{
+ union {
+ double d;
+ unsigned u[2];
+ ull ull;
+ sll sll;
+ } in, retval;
+ register unsigned exp;
+ register unsigned flag;
+
+ if (s == 0)
+ return 0.0;
+
+ /* Move into memory as args might be passed in regs */
+ in.sll = s;
+
+ /* Handle the negative flag */
+ if (in.sll < 1) {
+ flag = 0x80000000;
+ in.ull = _sllneg(in.sll);
+ } else
+ flag = 0x00000000;
+
+ /*
+ * Normalize
+ *
+ * IEEE 754 decimal-point begins at right of bit position 30
+ */
+ for (exp = (1023 + 30); in.ull && (in.u[1] & 0x80000000) == 0; exp--) {
+ in.ull <<= 1;
+ }
+ in.ull <<= 1;
+ exp++;
+ in.ull >>= 12;
+ retval.ull = in.ull;
+ retval.u[1] |= flag | (exp << 20);
+
+#if defined(BROKEN_IEEE754_DOUBLE)
+
+ exp = retval.u[0];
+ retval.u[0] = retval.u[1];
+ retval.u[1] = exp;
+
+#endif /* defined(BROKEN_IEEE754_DOUBLE) */
+
+ return retval.d;
+}
+
+/*
+ * Multiply two sll values
+ *
+ * Description
+ *
+ * When multiplying two 64 bit sll numbers, the result is 128 bits, but there
+ * is only room for a 64 bit result with sll!
+ *
+ * The 128 bit result has 64 bits on either side of the decimal, so 32 bits
+ * of overflow to the left of the decimal, and 32 bits of underflow to the
+ * right of the decmial.
+ *
+ * 32.32 * 32.32 = 64.64 = overflow(32) + 32.32 + underflow(32)
+ *
+ * However, a "long long" multiply has 64 bits of overflow to the left of the
+ * decimal, resulting in the entire integer part being lost!
+ *
+ * 32.32 * 32.32 = 64.64 = overflow(64) + .64
+ *
+ * Hence a custom multiply routine is required, to preserve the parts
+ * of the result that sll needs.
+ *
+ * Consider two sll numbers, x and y:
+ *
+ * Let x = x_hi * 2^0 + x_lo * 2^(-32)
+ * Let y = y_hi * 2^0 + y_lo * 2^(-32)
+ *
+ * Where:
+ *
+ * *_hi is the signed 32 bit integer part to the left of the decimal
+ * *_lo is the unsigned 32 bit fractional part to the right of the decimal
+ *
+ * x * y = (x_hi * 2^0 + x_lo * 2^(-32))
+ * * (y_hi * 2^0 + y_lo * 2^(-32))
+ *
+ * Expanding the terms, we get:
+ *
+ * = x_hi * y_hi * 2^0 + x_hi * y_lo * 2^(-32)
+ * + x_lo * y_hi * 2^(-32) + x_lo * y_lo * 2^(-64)
+ *
+ * Grouping by powers of 2, we get:
+ *
+ * (x_hi * y_hi) * 2^0
+ * We only need the low 32 bits of this term, as the rest is overflow
+ *
+ * (x_hi * y_lo + x_lo * y_hi) * 2^-32
+ * We need all bits of this term
+ *
+ * x_lo * y_lo * 2^-64
+ * We only need the high 32 bits of this term, as the rest is underflow
+ */
+
+sll sllmul(sll x, sll y)
+{
+ register unsigned int x_lo;
+ register signed int x_hi;
+
+ register unsigned int y_lo;
+ register signed int y_hi;
+
+ x_hi = (signed int) ((ull) x >> 32); // Discard lower 32 bits
+ x_lo = (unsigned int) x; // Discard upper 32 bits
+
+ y_hi = (signed int) ((ull) y >> 32); // Discard lower 32 bits
+ y_lo = (unsigned int) y; // Discard upper 32 bits
+
+ return (sll) (
+ ((ull) (x_hi * y_hi) << 32)
+ + ((ull) x_hi * y_lo + x_lo * (ull) y_hi)
+ + (((ull) x_lo * y_lo) >> 32)
+ );
+}
+
+/*
+ * Calculate cos x where -pi/4 <= x <= pi/4
+ *
+ * Description
+ *
+ * cos x = 1 - x^2 / 2! + x^4 / 4! - ... + x^(2N) / (2N)!
+ * Note that (pi/4)^12 / 12! < 2^-32 which is the smallest possible number.
+ *
+ * cos x = t0 + t1 + t2 + t3 + t4 + t5 + t6
+ *
+ * Consider only the factorials:
+ * f0 = 0! = 1
+ * f1 = 2! = 2 * 1 * f0 = 2 * f0
+ * f2 = 4! = 4 * 3 * f1 = 12 * f1
+ * f3 = 6! = 6 * 5 * f2 = 30 * f2
+ * f4 = 8! = 8 * 7 * f3 = 56 * f3
+ * f5 = 10! = 10 * 9 * f4 = 90 * f4
+ * f6 = 12! = 12 * 11 * f5 = 132 * f5
+ *
+ * Now consider each term of the series:
+ * t0 = 1
+ * t1 = -t0 * x^2 / f1 = -t0 * x^2 * CONST_1_2
+ * t2 = -t1 * x^2 / f2 = -t1 * x^2 * CONST_1_12
+ * t3 = -t2 * x^2 / f3 = -t2 * x^2 * CONST_1_30
+ * t4 = -t3 * x^2 / f4 = -t3 * x^2 * CONST_1_56
+ * t5 = -t4 * x^2 / f5 = -t4 * x^2 * CONST_1_90
+ * t6 = -t5 * x^2 / f6 = -t5 * x^2 * CONST_1_132
+ */
+
+sll _sllcos(sll x)
+{
+ sll retval;
+ sll x2;
+
+ x2 = sllmul(x, x);
+
+ retval = _sllsub(CONST_1, sllmul(x2, CONST_1_132));
+ retval = _sllsub(CONST_1, sllmul(sllmul(x2, retval), CONST_1_90));
+ retval = _sllsub(CONST_1, sllmul(sllmul(x2, retval), CONST_1_56));
+ retval = _sllsub(CONST_1, sllmul(sllmul(x2, retval), CONST_1_30));
+ retval = _sllsub(CONST_1, sllmul(sllmul(x2, retval), CONST_1_12));
+ retval = _sllsub(CONST_1, slldiv2(sllmul(x2, retval)));
+
+ return retval;
+}
+
+/*
+ * Calculate sin x where -pi/4 <= x <= pi/4
+ *
+ * Description
+ *
+ * sin x = x - x^3 / 3! + x^5 / 5! - ... + x^(2N+1) / (2N+1)!
+ * Note that (pi/4)^13 / 13! < 2^-32 which is the smallest possible number.
+ *
+ * sin x = t0 + t1 + t2 + t3 + t4 + t5 + t6
+ *
+ * Consider only the factorials:
+ * f0 = 0! = 1
+ * f1 = 3! = 3 * 2 * f0 = 6 * f0
+ * f2 = 5! = 5 * 4 * f1 = 20 * f1
+ * f3 = 7! = 7 * 6 * f2 = 42 * f2
+ * f4 = 9! = 9 * 8 * f3 = 72 * f3
+ * f5 = 11! = 11 * 10 * f4 = 110 * f4
+ * f6 = 13! = 13 * 12 * f5 = 156 * f5
+ *
+ * Now consider each term of the series:
+ * t0 = 1
+ * t1 = -t0 * x^2 / 6 = -t0 * x^2 * CONST_1_6
+ * t2 = -t1 * x^2 / 20 = -t1 * x^2 * CONST_1_20
+ * t3 = -t2 * x^2 / 42 = -t2 * x^2 * CONST_1_42
+ * t4 = -t3 * x^2 / 72 = -t3 * x^2 * CONST_1_72
+ * t5 = -t4 * x^2 / 110 = -t4 * x^2 * CONST_1_110
+ * t6 = -t5 * x^2 / 156 = -t5 * x^2 * CONST_1_156
+ */
+
+sll _sllsin(sll x)
+{
+ sll retval;
+ sll x2;
+
+ x2 = sllmul(x, x);
+
+ retval = _sllsub(x, sllmul(x2, CONST_1_156));
+ retval = _sllsub(x, sllmul(sllmul(x2, retval), CONST_1_110));
+ retval = _sllsub(x, sllmul(sllmul(x2, retval), CONST_1_72));
+ retval = _sllsub(x, sllmul(sllmul(x2, retval), CONST_1_42));
+ retval = _sllsub(x, sllmul(sllmul(x2, retval), CONST_1_20));
+ retval = _sllsub(x, sllmul(sllmul(x2, retval), CONST_1_6));
+
+ return retval;
+}
+
+/*
+ * Calculate cos x for any value of x, by quadrant
+ */
+
+sll sllcos(sll x)
+{
+ int i;
+ sll retval;
+
+ /* Calculate cos (x - i * pi/2), where -pi/4 <= x - i * pi/2 <= pi/4 */
+ i = _sll2int(_slladd(sllmul(x, CONST_2_PI), CONST_1_2));
+ x = _sllsub(x, sllmul(_int2sll(i), CONST_PI_2));
+
+ /* Locate the quadrant */
+ switch (i & 3) {
+ default:
+ case 0:
+ retval = _sllcos(x);
+ break;
+ case 1:
+ retval = sllneg(_sllsin(x));
+ break;
+ case 2:
+ retval = sllneg(_sllcos(x));
+ break;
+ case 3:
+ retval = _sllsin(x);
+ break;
+ }
+
+ return retval;
+}
+
+/*
+ * Calculate sin x for any value of x, by quadrant
+ */
+
+sll sllsin(sll x)
+{
+ int i;
+ sll retval;
+
+ /* Calculate sin (x - n * pi/2), where -pi/4 <= x - i * pi/2 <= pi/4 */
+ i = _sll2int(_slladd(sllmul(x, CONST_2_PI), CONST_1_2));
+ x = _sllsub(x, sllmul(_int2sll(i), CONST_PI_2));
+
+ /* Locate the quadrant */
+ switch (i & 3) {
+ default:
+ case 0:
+ retval = _sllsin(x);
+ break;
+ case 1:
+ retval = _sllcos(x);
+ break;
+ case 2:
+ retval = sllneg(_sllsin(x));
+ break;
+ case 3:
+ retval = sllneg(_sllcos(x));
+ break;
+ }
+
+ return retval;
+}
+
+/*
+ * Calculate tan x for any value of x, by quadrant
+ */
+
+sll slltan(sll x)
+{
+ int i;
+ sll retval;
+
+ i = _sll2int(_slladd(sllmul(x, CONST_2_PI), CONST_1_2));
+ x = _sllsub(x, sllmul(_int2sll(i), CONST_PI_2));
+
+ /* Locate the quadrant */
+ switch (i & 3) {
+ default:
+ case 0:
+ case 2:
+ retval = slldiv(_sllsin(x), _sllcos(x));
+ break;
+ case 1:
+ case 3:
+ retval = _sllneg(slldiv(_sllcos(x), _sllsin(x)));
+ break;
+ }
+
+ return retval;
+}
+
+/*
+ *
+ * Calculate asin x, where |x| <= 1
+ *
+ * Description
+ *
+ * asin x = SUM[n=0,) C(2 * n, n) * x^(2 * n + 1) / (4^n * (2 * n + 1)), |x| <= 1
+ *
+ * where C(n, r) = nCr = n! / (r! * (n - r)!)
+ *
+ * Using a two term approximation:
+ * [1] a = x + x^3 / 6
+ *
+ * Results in:
+ * asin x = a + D
+ * where D is the difference from the exact result
+ *
+ * Letting D = asin d results in:
+ * [2] asin x = a + asin d
+ *
+ * Re-arranging:
+ * asin x - a = asin d
+ *
+ * Applying sin to both sides:
+ * sin (asin x - a) = sin asin d
+ * sin (asin x - a) = d
+ * d = sin (asin x - a)
+ *
+ * Applying the standard identity:
+ * sin (u - v) = sin u * cos v - cos u * sin v
+ *
+ * Results in:
+ * d = sin asin x * cos a - cos asin x * sin a
+ * d = x * cos a - cos asin x * sin a
+ *
+ * Applying the standard identity:
+ * cos asin u = (1 - u^2)^(1 / 2)
+ *
+ * Results in:
+ * [3] d = x * cos a - (1 - x^2)^(1 / 2) * sin a
+ *
+ * Putting the pieces together:
+ * [1] a = x + x^3 / 6
+ * [3] d = x * cos a - (1 - x^2)^(1 / 2) * sin a
+ * [2] asin x = a + asin d
+ *
+ * The worst case is x = 1.0 which converges after 2 iterations.
+ */
+
+sll sllasin(sll x)
+{
+ int left_side;
+ sll a;
+ sll retval;
+
+ /* asin -x = -asin x */
+ if ((left_side = x < 0))
+ x = _sllneg(x);
+
+ /* Out-of-range */
+ if (x > CONST_1)
+ return 0;
+
+ /* Initial approximate */
+ a = sllmul(x, _slladd(CONST_1, sllmul(x, sllmul(x, CONST_1_6))));
+ retval = a;
+
+ /* First iteration */
+ x = _sllsub(sllmul(x, sllcos(a)), sllmul(sllsqrt(_sllsub(CONST_1, sllmul(x, x))), sllsin(a)));
+ a = sllmul(x, _slladd(CONST_1, sllmul(x, sllmul(x, CONST_1_6))));
+ retval = _slladd(retval, a);
+
+ /* Second iteration */
+ x = _sllsub(sllmul(x, sllcos(a)), sllmul(sllsqrt(_sllsub(CONST_1, sllmul(x, x))), sllsin(a)));
+ a = sllmul(x, _slladd(CONST_1, sllmul(x, sllmul(x, CONST_1_6))));
+ retval = _slladd(retval, a);
+
+ /* Negate result if necessary */
+ return (left_side ? _sllneg(retval): retval);
+}
+
+/*
+ * Calculate atan x
+ *
+ * Description
+ *
+ * atan x = SUM[n=0,) (-1)^n * x^(2 * n + 1) / (2 * n + 1), |x| <= 1
+ *
+ * Using a two term approximation:
+ * [1] a = x - x^3 / 3
+ *
+ * Results in:
+ * atan x = a + D
+ * where D is the difference from the exact result
+ *
+ * Letting D = atan d results in:
+ * [2] atan x = a + atan d
+ *
+ * Re-arranging:
+ * atan x - a = atan d
+ *
+ * Applying tan to both sides:
+ * tan (atan x - a) = tan atan d
+ * tan (atan x - a) = d
+ * d = tan (atan x - a)
+ *
+ * Applying the standard identity:
+ * tan (u - v) = (tan u - tan v) / (1 + tan u * tan v)
+ *
+ * Results in:
+ * d = tan (atan x - a) = (tan atan x - tan a) / (1 + tan atan x * tan a)
+ * d = tan (atan x - a) = (x - tan a) / (1 + x * tan a)
+ *
+ * Let:
+ * [3] t = tan a
+ *
+ * Results in:
+ * [4] d = (x - t) / (1 + x * t)
+ *
+ * So putting the pieces together:
+ * [1] a = x - x^3 / 3
+ * [3] t = tan a
+ * [4] d = (x - t) / (1 + x * t)
+ * [2] atan x = a + atan d
+ * atan x = a + atan ((x - t) / (1 + x * t))
+ *
+ * The worst case is x = 1.0 which converges after 2 iterations.
+ */
+
+sll sllatan(sll x)
+{
+ int side;
+ sll a;
+ sll t;
+ sll retval;
+
+
+ if (x < CONST_1) {
+
+ /* Left: if (x < -1) then atan x = pi / 2 + atan 1 / x */
+ side = -1;
+ x = sllinv(x);
+
+ } else if (x > CONST_1) {
+
+ /* Right: if (x > 1) then atan x = pi / 2 - atan 1 / x */
+ side = 1;
+ x = sllinv(x);
+
+ } else {
+ /* Middle: -1 <= x <= 1 */
+ side = 0;
+ }
+
+ /* Initial approximate */
+ a = sllmul(x, _sllsub(CONST_1, sllmul(x, sllmul(x, CONST_1_3))));
+ retval = a;
+
+ /* First iteration */
+ t = _slldiv(_sllsin(a), _sllcos(a));
+ x = _slldiv(_sllsub(x, t), _slladd(CONST_1, sllmul(x, t)));
+ a = sllmul(x, _sllsub(CONST_1, sllmul(x, sllmul(x, CONST_1_3))));
+ retval = _slladd(retval, a);
+
+ /* Second iteration */
+ t = _slldiv(_sllsin(a), _sllcos(a));
+ x = _slldiv(_sllsub(x, t), _slladd(CONST_1, sllmul(x, t)));
+ a = sllmul(x, _sllsub(CONST_1, sllmul(x, sllmul(x, CONST_1_3))));
+ retval = _slladd(retval, a);
+
+ if (side == -1) {
+
+ /* Left: if (x < -1) then atan x = pi / 2 + atan 1 / x */
+ retval = _slladd(CONST_PI_2, retval);
+
+ } else if (side == 1) {
+
+ /* Right: if (x > 1) then atan x = pi / 2 - atan 1 / x */
+ retval = _sllsub(CONST_PI_2, retval);
+ }
+
+ return retval;
+}
+
+/*
+ * Calculate e^x where -0.5 <= x <= 0.5
+ *
+ * Description:
+ * e^x = x^0 / 0! + x^1 / 1! + ... + x^N / N!
+ * Note that 0.5^11 / 11! < 2^-32 which is the smallest possible number.
+ */
+
+sll _sllexp(sll x)
+{
+ sll retval;
+
+ retval = CONST_1;
+
+ retval = _slladd(CONST_1, sllmul(retval, sllmul(x, CONST_1_11)));
+ retval = _slladd(CONST_1, sllmul(retval, sllmul(x, CONST_1_10)));
+ retval = _slladd(CONST_1, sllmul(retval, sllmul(x, CONST_1_9)));
+ retval = _slladd(CONST_1, sllmul(retval, slldiv2n(x, 3)));
+ retval = _slladd(CONST_1, sllmul(retval, sllmul(x, CONST_1_7)));
+ retval = _slladd(CONST_1, sllmul(retval, sllmul(x, CONST_1_6)));
+ retval = _slladd(CONST_1, sllmul(retval, sllmul(x, CONST_1_5)));
+ retval = _slladd(CONST_1, sllmul(retval, slldiv4(x)));
+ retval = _slladd(CONST_1, sllmul(retval, sllmul(x, CONST_1_3)));
+ retval = _slladd(CONST_1, sllmul(retval, slldiv2(x)));
+ retval = _slladd(CONST_1, sllmul(retval, x));
+
+ return retval;
+}
+
+/*
+ * Calculate e^x for any value of x
+ */
+
+sll sllexp(sll x)
+{
+ int i;
+ sll e;
+ sll retval;
+
+ e = CONST_E;
+
+ /* -0.5 <= x <= 0.5 */
+ i = _sll2int(_slladd(x, CONST_1_2));
+ retval = _sllexp(_sllsub(x, _int2sll(i)));
+
+ /* i >= 0 */
+ if (i < 0) {
+ i = -i;
+ e = CONST_1_E;
+ }
+
+ /* Scale the result */
+ for (; i; i >>= 1) {
+ if (i & 1)
+ retval = sllmul(retval, e);
+ e = sllmul(e, e);
+ }
+
+ return retval;
+}
+
+/*
+ * Calculate natural logarithm using Netwton-Raphson method
+ */
+
+sll slllog(sll x)
+{
+ sll x1;
+ sll ln;
+
+ ln = 0;
+
+ /* Scale: e^(-1/2) <= x <= e^(1/2) */
+ while (x < CONST_1_SQRTE) {
+ ln = _sllsub(ln, CONST_1);
+ x = sllmul(x, CONST_E);
+ }
+ while (x > CONST_SQRTE) {
+ ln = _slladd(ln, CONST_1);
+ x = sllmul(x, CONST_1_E);
+ }
+
+ /* First iteration */
+ x1 = sllmul(_sllsub(x, CONST_1), slldiv2(_sllsub(x, CONST_3)));
+ ln = _sllsub(ln, x1);
+ x = sllmul(x, _sllexp(x1));
+
+ /* Second iteration */
+ x1 = sllmul(_sllsub(x, CONST_1), slldiv2(_sllsub(x, CONST_3)));
+ ln = _sllsub(ln, x1);
+ x = sllmul(x, _sllexp(x1));
+
+ /* Third iteration */
+ x1 = sllmul(_sllsub(x, CONST_1), slldiv2(_sllsub(x, CONST_3)));
+ ln = _sllsub(ln, x1);
+
+ return ln;
+}
+
+/*
+ * Calculate the inverse for non-zero values
+ */
+
+sll sllinv(sll x)
+{
+ int sgn;
+ sll u;
+ ull s;
+
+ /* Use positive numbers, or the approximation won't work */
+ if (x < CONST_0) {
+ x = _sllneg(x);
+ sgn = 1;
+ } else {
+ sgn = 0;
+ }
+
+ /* Starting-point (gets shifted right to become positive) */
+ s = -1;
+
+ /* An approximation - must be larger than the actual value */
+ for (u = x; u; u = ((ull) u) >> 1)
+ s >>= 1;
+
+ /* Newton's Method */
+ u = sllmul(s, _sllsub(CONST_2, sllmul(x, s)));
+ u = sllmul(u, _sllsub(CONST_2, sllmul(x, u)));
+ u = sllmul(u, _sllsub(CONST_2, sllmul(x, u)));
+ u = sllmul(u, _sllsub(CONST_2, sllmul(x, u)));
+ u = sllmul(u, _sllsub(CONST_2, sllmul(x, u)));
+ u = sllmul(u, _sllsub(CONST_2, sllmul(x, u)));
+
+ return ((sgn) ? _sllneg(u): u);
+}
+
+/*
+ * Calculate x^y
+ *
+ * Description
+ *
+ * The standard identity:
+ * ln x^y = y * log x
+ *
+ * Raising e to the power of either sides:
+ * e^(ln x^y) = e^(y * log x)
+ *
+ * Which simplifies to:
+ * x^y = e^(y * ln x)
+ */
+
+sll sllpow(sll x, sll y)
+{
+ if (y == CONST_0)
+ return CONST_1;
+ if (y == CONST_1)
+ return x;
+ if (y == CONST_2)
+ return sllmul(x, x);
+
+ return sllexp(sllmul(y, slllog(x)));
+}
+
+/*
+ * Calculate the square-root
+ *
+ * Description
+ *
+ * Consider a parabola centered on the y-axis:
+ * y = a * x^2 + b
+ *
+ * Has zeros (y = 0) located at:
+ * a * x^2 + b = 0
+ * a * x^2 = -b
+ * x^2 = -b / a
+ * x = +- (-b / a)^(1 / 2)
+ *
+ * Letting a = 1 and b = -X results in:
+ * y = x^2 - X
+ * x = +- X^(1 / 2)
+ *
+ * Which is a convenient result, since we want to find the square root of X,
+ * and we can * use Newton's Method to find the zeros of any f(x):
+ * xn = x - f(x) / f'(x)
+ *
+ * Applying Newton's Method to our parabola:
+ * f(x) = x^2 - X
+ * xn = x - (x^2 - X) / (2 * x)
+ * xn = x - (x - X / x) / 2
+ *
+ * To make this converge quickly, we scale X so that:
+ * X = 4^N * z
+ *
+ * Taking the roots of both sides
+ * X^(1 / 2) = (4^n * z)^(1 / 2)
+ * X^(1 / 2) = 2^n * z^(1 / 2)
+ *
+ * Letting N = 2^n results in:
+ * x^(1 / 2) = N * z^(1 / 2)
+ *
+ * We want this to converge to the positive root, so we must start at a point
+ * 0 < start <= x^(1 / 2)
+ * or
+ * x^(1/2) <= start <= infinity
+ *
+ * Since:
+ * (1/2)^(1/2) = 0.707
+ * 2^(1/2) = 1.414
+ *
+ * A good choice is 1 which lies in the middle, and takes 4 iterations to
+ * converge from either extreme.
+ */
+
+sll sllsqrt(sll x)
+{
+ sll n;
+ sll xn;
+
+ /* Quick solutions for the simple cases */
+ if (x <= CONST_0 || x == CONST_1)
+ return x;
+
+ /* Start with a scaling factor of 1 */
+ n = CONST_1;
+
+ /* Scale x so that 0.5 <= x < 2 */
+ while (x >= CONST_2) {
+ x = slldiv4(x);
+ n = sllmul2(n);
+ }
+ while (x < CONST_1_2) {
+ x = sllmul4(x);
+ n = slldiv2(n);
+ }
+
+ /* Simple solution if x = 4^n */
+ if (x == CONST_1)
+ return n;
+
+ /* The starting point */
+ xn = CONST_1;
+
+ /* Four iterations will be enough */
+ xn = _sllsub(xn, slldiv2(_sllsub(xn, slldiv(x, xn))));
+ xn = _sllsub(xn, slldiv2(_sllsub(xn, slldiv(x, xn))));
+ xn = _sllsub(xn, slldiv2(_sllsub(xn, slldiv(x, xn))));
+ xn = _sllsub(xn, slldiv2(_sllsub(xn, slldiv(x, xn))));
+
+ /* Scale the result */
+ return sllmul(n, xn);
+}
+
+sll slld2dsqrt(sll num)
+{
+ if (num <= CONST_0 || num == CONST_1)
+ {
+ return num;
+ }
+ sll result = 0;
+ sll bit;
+
+ // Many numbers will be less than 15, so
+ // this gives a good balance between time spent
+ // in if vs. time spent in the while loop
+ // when searching for the starting value.
+ if (num & 0xFFFFFF0000000000LL)
+ bit = 0x4000000000000000LL; //(sll)1 << 62;
+ else
+ bit = 0x0000004000000000LL; //(sll)1 << 38;
+
+ while (bit > num) bit >>= 2;
+
+ while (bit)
+ {
+ if (num >= result + bit)
+ {
+ num -= result + bit;
+ result = (result >> 1) + bit;
+ }
+ else
+ {
+ result = (result >> 1);
+ }
+ bit >>= 2;
+ }
+
+ // Then process it again to get the lowest 8 bits.
+ // 灏炬暟瀹氱偣鏁板ぇ浜庣瓑浜1
+ if (num > CONST_P9999)
+ {
+ // The remainder 'num' is too large to be shifted left
+ // by 32, so we have to add 0.5 to result manually and
+ // adjust 'num' accordingly. a鏄師鏈殑鏁
+ // why 0.5 is enough? because: result^2 <= a < (result+1)^2
+ // num = a - (result + 0.5)^2
+ // = num + result^2 - (result + 0.5)^2
+ // = num - result - 0.25
+ num -= result;
+ // 娉ㄦ剰锛屼弗鏍兼潵璇达紝杩欓噷瑕佸乏绉16浣嶆墠缂╁皬鍒扮粨鏋滐紝浣嗘槸涓轰簡鍚庣画灏忔暟涓嶇敤鍐嶆斁澶э紝杩欓噷鎻愬墠鍋氫簡鏀惧ぇ
+ num = (num << 32) - CONST_1_4;
+ result = (result << 32) + CONST_1_2;
+ }
+ else
+ {
+ num <<= 32;
+ result <<= 32;
+ }
+
+ bit = 0x0000000040000000LL; //(sll)1 << 30;
+
+ while (bit)
+ {
+ if (num >= result + bit)
+ {
+ num -= result + bit;
+ result = (result >> 1) + bit;
+ }
+ else
+ {
+ result = (result >> 1);
+ }
+ bit >>= 2;
+ }
+
+ return result;
+} \ No newline at end of file
diff --git a/Client/ThirdParty/math-sll/math-sll.h b/Client/ThirdParty/math-sll/math-sll.h
new file mode 100644
index 0000000..b10dbe7
--- /dev/null
+++ b/Client/ThirdParty/math-sll/math-sll.h
@@ -0,0 +1,770 @@
+#if !defined(MATH_SLL_H)
+# define MATH_SLL_H
+
+/*
+ * Revision v1.24
+ *
+ * A fixed point (32.32 bit) math library.
+ *
+ * Description
+ *
+ * Floating point packs the most accuracy in the available bits, but it
+ * often provides more accuracy than is required. It is time consuming to
+ * carry the extra precision around, particularly on platforms that don't
+ * have a dedicated floating point processor.
+ *
+ * This library is a compromise. All math is done using the 64 bit signed
+ * "long long" format (sll), and is not intended to be portable, just as
+ * simple and as fast as possible.
+ *
+ * As some processors lack division instructions but have multiplication
+ * instructions, multiplication is favored over division. This can be a
+ * penalty when used on a processor with a division instruction, so it is
+ * recommended to modify the division functions and macros in that case.
+ *
+ * On procesors without multiplication instructions, other algorithms, for
+ * example CORDIC, are probably faster.
+ *
+ * Since "long long" is a elementary type, it can be passed around without
+ * resorting to the use of pointers. Since the format used is fixed point,
+ * there is never a need to do time consuming checks and adjustments to
+ * maintain normalized numbers, as is the case in floating point.
+ *
+ * Simply put, this library is limited to handling numbers with a whole
+ * part of up to 2^31 - 1 = 2.147483647e9 in magnitude, and fractional
+ * parts down to 2^-32 = 2.3283064365e-10 in magnitude. This yields a
+ * decent range and accuracy for many applications.
+ *
+ * IMPORTANT
+ *
+ * No checking for arguments out of range (error).
+ * No checking for divide by zero (error).
+ * No checking for overflow (error).
+ * No checking for underflow (warning).
+ * Chops, doesn't round.
+ *
+ * Functions
+ *
+ * sll dbl2sll(double d) double to sll
+ * double sll2dbl(sll s) sll to double
+ *
+ * sll int2sll(int i) integer to sll
+ * int sll2int(sll s) sll to integer
+ *
+ * sll sllint(sll s) Set fractional-part to 0
+ * sll sllfrac(sll s) Set integer-part to 0
+ *
+ * sll slladd(sll x, sll y) x + y
+ * sll sllneg(sll x) -x
+ * sll sllsub(sll x, sll y) x - y
+ *
+ * sll sllmul(sll x, sll y) x * y
+ * sll sllmul2(sll x) x * 2
+ * sll sllmul2n(sll x, int n) x * 2^n, 0 <= n <= 31
+ * sll sllmul4(sll x) x * 4
+ *
+ * sll slldiv(sll x, sll y) x / y
+ * sll slldiv2(sll x) x / 2
+ * sll slldiv2n(sll x, int n) x / 2^n, 0 <= n <= 31
+ * sll slldiv4(sll x) x / 4
+ *
+ * sll sllcos(sll x) cos x
+ * sll sllsin(sll x) sin x
+ * sll slltan(sll x) tan x
+ *
+ * sll sllsec(sll x) sec x = 1 / cos x
+ * sll sllcsc(sll x) csc x = 1 / sin x
+ * sll sllcot(sll x) cot x = 1 / tan x = cos x / sin x
+ *
+ * sll sllacos(sll x) acos x
+ * sll sllasin(sll x) asin x
+ * sll sllatan(sll x) atan x
+ *
+ * sll sllcosh(sll x) cosh x
+ * sll sllsinh(sll x) sinh x
+ * sll slltanh(sll x) tanh x
+ *
+ * sll sllsech(sll x) sech x
+ * sll sllcsch(sll x) cosh x
+ * sll sllcoth(sll x) coth x
+ *
+ * sll sllexp(sll x) e^x
+ * sll slllog(sll x) ln x
+ *
+ * sll sllinv(sll v) 1 / x
+ * sll sllpow(sll x, sll y) x^y
+ * sll sllsqrt(sll x) x^(1 / 2)
+ *
+ * sll sllfloor(sll x) floor x
+ * sll sllceil(sll x) ceiling x
+ *
+ * Macros
+ *
+ * Use of the following macros is optional, but may be beneficial with
+ * some compilers. Using the non-macro versions is strongly recommended.
+ *
+ * WARNING: macros do not type-check their arguments!
+ *
+ * _int2sll(X) See function int2sll()
+ * _sll2int(X) See function sll2int()
+ *
+ * _sllint(X) See function sllint()
+ * _sllfrac(X) See function sllfrac()
+ *
+ * _slladd(X,Y) See function slladd()
+ * _sllneg(X) See function sllneg()
+ * _sllsub(X,Y) See function sllsub()
+ *
+ * _sllmul2(X) See function sllmul2()
+ * _sllmul2n(X) See function sllmul2n()
+ * _sllmul4(X) See function sllmul4()
+ *
+ * _slldiv(X,Y) See function slldiv()
+ * _slldiv2(X,Y) See function slldiv2()
+ * _slldiv2n(X,Y) See function slldiv2n()
+ * _slldiv4(X,Y) See function slldiv4()
+ *
+ * Credits
+ *
+ * Maintained, conceived, written, and fiddled with by:
+ *
+ * Andrew E. Mileski <andrewm@isoar.ca>
+ *
+ * Other source code contributors:
+ *
+ * Kevin Rockel
+ * Kevin Michael Woley
+ * Mark Anthony Lisher
+ * Nicolas Pitre
+ * Anonymous
+ *
+ * License
+ *
+ * Licensed under the terms of the MIT license:
+ *
+ * Copyright (c) 2000,2002,2006,2012,2016 Andrew E. Mileski <andrewm@isoar.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The copyright notice, and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* DEC SA-110 "StrongARM" (armv4l) architecture has a big-endian double */
+#if defined(__arm__)
+# if (!defined(__BYTE_ORDER__) || (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
+# define BROKEN_IEEE754_DOUBLE
+# endif
+#endif
+
+#ifdef _MSC_VER
+# define __inline__ __inline
+# ifndef _MSC_STDINT_H_
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#endif
+#define __extension__
+#else
+#include <stdint.h>
+#if defined(__GNUC__)
+
+#else
+ #define __inline__ inline
+#endif
+#endif
+/*
+ * Data types
+ */
+
+__extension__ typedef int64_t sll;
+__extension__ typedef uint64_t ull;
+
+/*
+ * Function prototypes
+ */
+
+sll dbl2sll(double d);
+double sll2dbl(sll s);
+
+static __inline__ sll int2sll(int i);
+static __inline__ int sll2int(sll s);
+
+static __inline__ sll sllint(sll s);
+static __inline__ sll sllfrac(sll s);
+
+static __inline__ sll slladd(sll x, sll y);
+static __inline__ sll sllneg(sll s);
+static __inline__ sll sllsub(sll x, sll y);
+sll sllmul(sll x, sll y);
+static __inline__ sll sllmul2(sll x);
+static __inline__ sll sllmul4(sll x);
+static __inline__ sll sllmul2n(sll x, int n);
+
+static __inline__ sll slldiv(sll x, sll y);
+static __inline__ sll slldiv2(sll x);
+static __inline__ sll slldiv4(sll x);
+static __inline__ sll slldiv2n(sll x, int n);
+
+sll sllcos(sll x);
+sll sllsin(sll x);
+sll slltan(sll x);
+
+static __inline__ sll sllacos(sll x);
+sll sllasin(sll x);
+sll sllatan(sll x);
+
+static __inline__ sll sllsec(sll x);
+static __inline__ sll sllcsc(sll x);
+static __inline__ sll sllcot(sll x);
+
+static __inline__ sll sllcosh(sll x);
+static __inline__ sll sllsinh(sll x);
+static __inline__ sll slltanh(sll x);
+
+static __inline__ sll sllsech(sll x);
+static __inline__ sll sllcsch(sll x);
+static __inline__ sll sllcoth(sll x);
+
+sll sllexp(sll x);
+sll slllog(sll x);
+
+sll sllpow(sll x, sll y);
+sll sllinv(sll v);
+sll sllsqrt(sll x);
+sll slld2dsqrt(sll x);
+
+static __inline__ sll sllfloor(sll x);
+static __inline__ sll sllceil(sll x);
+
+/*
+ * Macros
+ *
+ * WARNING - Macros don't type-check!
+ */
+
+#define _int2sll(X) (((sll) (X)) << 32)
+#define _sll2int(X) ((int) ((X) >> 32))
+
+#define _sllint(X) ((X) & 0xffffffff00000000LL)
+#define _sllfrac(X) ((X) & 0x00000000ffffffffLL)
+
+#define _slladd(X,Y) ((X) + (Y))
+#define _sllneg(X) (-(X))
+#define _sllsub(X,Y) ((X) - (Y))
+
+#define _sllmul2(X) ((X) << 1)
+#define _sllmul4(X) ((X) << 2)
+#define _sllmul2n(X,N) ((X) << (N))
+
+#define _slldiv(X,Y) sllmul((X), sllinv(Y))
+#define _slldiv2(X) ((X) >> 1)
+#define _slldiv4(X) ((X) >> 2)
+#define _slldiv2n(X,N) ((X) >> (N))
+
+/*
+ * Constants (converted from double)
+*/
+
+#define CONST_0 0x0000000000000000LL // 0.0
+#define CONST_1 0x0000000100000000LL // 1.0
+#define CONST_neg1 0xffffffff00000000LL // -1.0
+#define CONST_2 0x0000000200000000LL // 2.0
+#define CONST_3 0x0000000300000000LL // 3.0
+#define CONST_4 0x0000000400000000LL // 4.0
+#define CONST_10 0x0000000a00000000LL // 10.0
+#define CONST_10 0x0000000a00000000LL // 10.0
+#define CONST_1_2 0x0000000080000000LL // 1.0 / 2.0
+#define CONST_1_3 0x0000000055555555LL // 1.0 / 3.0
+#define CONST_1_4 0x0000000040000000LL // 1.0 / 4.0
+#define CONST_1_5 0x0000000033333333LL // 1.0 / 5.0
+#define CONST_1_6 0x000000002aaaaaaaLL // 1.0 / 6.0
+#define CONST_1_7 0x0000000024924924LL // 1.0 / 7.0
+#define CONST_1_8 0x0000000020000000LL // 1.0 / 8.0
+#define CONST_1_9 0x000000001c71c71cLL // 1.0 / 9.0
+#define CONST_1_10 0x0000000019999999LL // 1.0 / 10.0
+#define CONST_1_11 0x000000001745d174LL // 1.0 / 11.0
+#define CONST_1_12 0x0000000015555555LL // 1.0 / 12.0
+#define CONST_1_20 0x000000000cccccccLL // 1.0 / 20.0
+#define CONST_1_30 0x0000000008888888LL // 1.0 / 30.0
+#define CONST_1_42 0x0000000006186186LL // 1.0 / 42.0
+#define CONST_1_56 0x0000000004924924LL // 1.0 / 56.0
+#define CONST_1_72 0x00000000038e38e3LL // 1.0 / 72.0
+#define CONST_1_90 0x0000000002d82d82LL // 1.0 / 90.0
+#define CONST_1_110 0x000000000253c825LL // 1.0 / 110.0
+#define CONST_1_132 0x0000000001f07c1fLL // 1.0 / 132.0
+#define CONST_1_156 0x0000000001a41a41LL // 1.0 / 156.0
+#define CONST_P9999 0x00000000FFFFFFFFLL // 0.999999999999
+
+#define CONST_E 0x00000002b7e15162LL // E
+#define CONST_1_E 0x000000005e2d58d8LL // 1 / E
+#define CONST_SQRTE 0x00000001a61298e1LL // sqrt(E)
+#define CONST_1_SQRTE 0x000000009b4597e3LL // 1 / sqrt(E)
+#define CONST_LOG2_E 0x0000000171547652LL // ln(E)
+#define CONST_LOG10_E 0x000000006f2dec54LL // log(E)
+#define CONST_LN2 0x00000000b17217f7LL // ln(2)
+#define CONST_LN10 0x000000024d763776LL // ln(10)
+
+#define CONST_PI 0x00000003243f6a88LL // PI
+#define CONST_2PI 0x00000006487ED510LL // PI
+#define CONST_PI_2 0x00000001921fb544LL // PI / 2
+#define CONST_PI_4 0x00000000c90fdaa2LL // PI / 4
+#define CONST_1_PI 0x00000000517cc1b7LL // 1 / PI
+#define CONST_2_PI 0x00000000a2f9836eLL // 2 / PI
+#define CONST_180_PI 0x000000394BB834C7LL // 180 / PI 246083499207.51537232162612011973
+#define CONST_PI_180 0x000000000477d1a8LL // PI / 180 74961320.580677883103327681382757
+#define CONST_2_SQRTPI 0x0000000120dd7504LL // 2 / sqrt(PI)
+#define CONST_SQRT2 0x000000016a09e667LL // sqrt(2)
+#define CONST_1_SQRT2 0x00000000b504f333LL // 1 / sqrt(2)
+
+#define CONST_FACT_0 0x0000000100000000LL // 0!
+#define CONST_FACT_1 0x0000000100000000LL // 1!
+#define CONST_FACT_2 0x0000000200000000LL // 2!
+#define CONST_FACT_3 0x0000000600000000LL // 3!
+#define CONST_FACT_4 0x0000001800000000LL // 4!
+#define CONST_FACT_5 0x0000007800000000LL // 5!
+#define CONST_FACT_6 0x000002d000000000LL // 6!
+#define CONST_FACT_7 0x000013b000000000LL // 7!
+#define CONST_FACT_8 0x00009d8000000000LL // 8!
+#define CONST_FACT_9 0x0005898000000000LL // 9!
+#define CONST_FACT_10 0x00375f0000000000LL // 10!
+#define CONST_FACT_11 0x0261150000000000LL // 11!
+#define CONST_FACT_12 0x1c8cfc0000000000LL // 12!
+
+#define CONST_MAX 0x7FFFFFFFFFFFFFFFLL // 鏈澶
+#define CONST_MIN 0x8000000000000000LL // 鏈灏
+
+/*
+ * Convert integer to sll
+ */
+
+static __inline__ sll int2sll(int i)
+{
+ return _int2sll(i);
+}
+
+/*
+ * Convert sll to integer (truncates)
+ */
+
+static __inline__ int sll2int(sll s)
+{
+ return _sll2int(s);
+}
+
+/*
+ * Integer-part of sll (fractional-part set to 0)
+ */
+
+static __inline__ sll sllint(sll s)
+{
+ return _sllint(s);
+}
+
+/*
+ * Fractional-part of sll (integer-part set to 0)
+ */
+
+static __inline__ sll sllfrac(sll s)
+{
+ return _sllfrac(s);
+}
+
+/*
+ * Addition
+ */
+
+static __inline__ sll slladd(sll x, sll y)
+{
+ return _slladd(x, y);
+}
+
+/*
+ * Negate
+ */
+
+static __inline__ sll sllneg(sll s)
+{
+ return _sllneg(s);
+}
+
+/*
+ * Subtraction
+ */
+
+static __inline__ sll sllsub(sll x, sll y)
+{
+ return _sllsub(x, y);
+}
+
+/*
+ * Multiply two sll values
+ *
+ * Description
+ *
+ * Let a = A * 2^32 + a_h * 2^0 + a_l * 2^(-32)
+ * Let b = B * 2^32 + b_h * 2^0 + b_l * 2^(-32)
+ *
+ * Where:
+ *
+ * *_h is the integer part
+ * *_l the fractional part
+ * A and B are the sign (0 for positive, -1 for negative).
+ *
+ * a * b = (A * 2^32 + a_h * 2^0 + a_l * 2^-32)
+ * * (B * 2^32 + b_h * 2^0 + b_l * 2^-32)
+ *
+ * Expanding the terms, we get:
+ *
+ * = A * B * 2^64 + A * b_h * 2^32 + A * b_l * 2^0
+ * + a_h * B * 2^32 + a_h * b_h * 2^0 + a_h * b_l * 2^-32
+ * + a_l * B * 2^0 + a_l * b_h * 2^-32 + a_l * b_l * 2^-64
+ *
+ * Grouping by powers of 2, we get:
+ *
+ * = A * B * 2^64
+ * Meaningless overflow from sign extension - ignore
+ *
+ * + (A * b_h + a_h * B) * 2^32
+ * Overflow which we can't handle - ignore
+ *
+ * + (A * b_l + a_h * b_h + a_l * B) * 2^0
+ * We only need the low 32 bits of this term, as the rest is overflow
+ *
+ * + (a_h * b_l + a_l * b_h) * 2^-32
+ * We need all 64 bits of this term
+ *
+ * + a_l * b_l * 2^-64
+ * We only need the high 32 bits of this term, as the rest is underflow
+ *
+ * Note that:
+ * a > 0 && b > 0: A = 0, B = 0 and the third term is a_h * b_h
+ * a < 0 && b > 0: A = -1, B = 0 and the third term is a_h * b_h - b_l
+ * a > 0 && b < 0: A = 0, B = -1 and the third term is a_h * b_h - a_l
+ * a < 0 && b < 0: A = -1, B = -1 and the third term is a_h * b_h - a_l - b_l
+ */
+
+/*
+ * Multiplication by 2
+ */
+
+static __inline__ sll sllmul2(sll x)
+{
+ return _sllmul2(x);
+}
+
+/*
+ * Multiplication by 4
+ */
+
+static __inline__ sll sllmul4(sll x)
+{
+ return _sllmul4(x);
+}
+
+/*
+ * Multiplication by power of 2
+ */
+
+static __inline__ sll sllmul2n(sll x, int n)
+{
+ return _sllmul2n(x, n);
+}
+
+/*
+ * Division
+ */
+
+static __inline__ sll slldiv(sll x, sll y)
+{
+ return _slldiv(x, y);
+}
+
+/*
+ * Division by 2
+ */
+
+static __inline__ sll slldiv2(sll x)
+{
+ return _slldiv2(x);
+}
+
+/*
+ * Division by 4
+ */
+
+static __inline__ sll slldiv4(sll x)
+{
+ return _slldiv4(x);
+}
+
+/*
+ * Division by power of 2
+ */
+
+static __inline__ sll slldiv2n(sll x, int n)
+{
+ return _slldiv2n(x, n);
+}
+
+/*
+ *
+ * Calculate acos x, where |x| <= 1
+ *
+ * Description
+ *
+ * acos x = pi / 2 - asin x
+ * acos x = pi / 2 - SUM[n=0,) C(2 * n, n) * x^(2 * n + 1) / (4^n * (2 * n + 1)), |x| <= 1
+ *
+ * where C(n, r) = nCr = n! / (r! * (n - r)!)
+ */
+
+static __inline__ sll sllacos(sll x)
+{
+ return _sllsub(CONST_PI_2, sllasin(x));
+}
+
+/*
+ * Trigonometric secant
+ *
+ * Description
+ *
+ * sec x = 1 / cos x
+ *
+ * An alternate algorithm, like a power series, would be more accurate.
+ */
+
+static __inline__ sll sllsec(sll x)
+{
+ return sllinv(sllcos(x));
+}
+
+/*
+ * Trigonometric cosecant
+ *
+ * Description
+ *
+ * csc x = 1 / sin x
+ *
+ * An alternate algorithm, like a power series, would be more accurate.
+ */
+
+static __inline__ sll sllcsc(sll x)
+{
+ return sllinv(sllsin(x));
+}
+
+/*
+ * Trigonometric cotangent
+ *
+ * Description
+ *
+ * cot x = 1 / tan x
+ *
+ * cot x = cos x / sin x
+ *
+ * An alternate algorithm, like a power series, would be more accurate.
+ */
+
+static __inline__ sll sllcot(sll x)
+{
+ return _slldiv(sllcos(x), sllsin(x));
+}
+
+/*
+ * Hyperbolic cosine
+ *
+ * Description
+ *
+ * cosh x = (e^x + e^(-x)) / 2
+ *
+ * cosh x = 1 + x^2 / 2! + ... + x^(2 * N) / (2 * N)!
+ *
+ * An alternate algorithm, like a power series, would be more accurate.
+ */
+
+static __inline__ sll sllcosh(sll x)
+{
+ return _slldiv2(_slladd(sllexp(x), sllexp(_sllneg(x))));
+}
+
+/*
+ * Hyperbolic sine
+ *
+ * Description
+ *
+ * sinh x = (e^x - e^(-x)) / 2
+ *
+ * sinh x = 1 + x^3 / 3! + ... + x^(2 * N + 1) / (2 * N + 1)!
+ *
+ * An alternate algorithm, like a power series, would be more accurate.
+ */
+
+static __inline__ sll sllsinh(sll x)
+{
+ return _slldiv2(_sllsub(sllexp(x), sllexp(_sllneg(x))));
+}
+
+/*
+ * Hyperbolic tangent
+ *
+ * Description
+ *
+ * tanh x = sinh x / cosh x
+ *
+ * tanh x = (e^x - e^(-x)) / (e^x + e^(-x))
+ *
+ * tanh x = (e^(2 * x) - 1) / (e^(2 * x) + 1)
+ *
+ * An alternate algorithm, like a power series, would be more accurate.
+ */
+
+static __inline__ sll slltanh(sll x)
+{
+ register sll e2x;
+
+ e2x = sllexp(_sllmul2(x));
+
+ return _slldiv(_sllsub(e2x, CONST_1), _slladd(e2x, CONST_1));
+}
+
+/*
+ * Hyperbolic secant
+ *
+ * Description
+ *
+ * sech x = 1 / cosh x
+ *
+ * sech x = 2 / (e^x + e^(-x))
+ *
+ * sech x = 2 * e^x / (e^(2 * x) + 1)
+ *
+ * An alternate algorithm, like a power series, would be more accurate.
+ */
+
+static __inline__ sll sllsech(sll x)
+{
+ return _slldiv(_sllmul2(sllexp(x)), _slladd(sllexp(_sllmul2(x)), CONST_1));
+}
+
+/*
+ * Hyperbolic cosecant
+ *
+ * Description
+ *
+ * csch x = = 1 / sinh x
+ *
+ * csch x = 2 / (e^x - e^(-x))
+ *
+ * csch x = 2 * e^x / (e^(2 * x) - 1)
+ *
+ * An alternate algorithm, like a power series, would be more accurate.
+ */
+
+static __inline__ sll sllcsch(sll x)
+{
+ return _slldiv(_sllmul2(sllexp(x)), _sllsub(sllexp(_sllmul2(x)), CONST_1));
+}
+
+/*
+ * Hyperbolic cotangent
+ *
+ * Description
+ *
+ * coth x = 1 / tanh x
+ *
+ * coth x = cosh x / sinh x
+ *
+ * coth x = (e^x + e^(-x)) / (e^x - e^(-x))
+ *
+ * coth x = (e^(2 * x) + 1) / (e^(2 * x) - 1)
+ *
+ * An alternate algorithm, like a power series, would be more accurate.
+ */
+
+static __inline__ sll sllcoth(sll x)
+{
+ register sll e2x;
+
+ e2x = sllexp(sllmul2(x));
+
+ return _slldiv(_slladd(e2x, CONST_1), _sllsub(e2x, CONST_1));
+}
+
+/*
+ * Floor
+ *
+ * Description
+ *
+ * floor x = largest integer not larger than x
+ */
+
+static __inline__ sll sllfloor(sll x)
+{
+ register sll retval;
+
+ retval = _sllint(x);
+
+ return ((retval > x) ? _sllsub(retval, CONST_1): retval);
+}
+
+/*
+ * Ceiling
+ *
+ * Description
+ *
+ * ceil x = smallest integer not smaller than x
+ */
+
+static __inline__ sll sllceil(sll x)
+{
+ register sll retval;
+
+ retval = _sllint(x);
+
+ return ((retval < x) ? _slladd(retval, CONST_1): retval);
+}
+
+#define sllabs(x) ((x) < 0 ? -(x) : (x))
+#define __VECTOR2_META__ "__VECTOR2_META__"
+#define __VECTOR3_META__ "__VECTOR3_META__"
+#define __ROT2_META__ "__ROT2_META__"
+#define __ROT4_META__ "__ROT4_META__"
+#define __METATABLE_NAME "__FIX_METATABLE__"
+
+static int _mul[] = {1, 10, 100, 1000, 10000, 100000, 1000000};
+
+typedef struct Vector2
+{
+ sll x;
+ sll y;
+}Vector2;
+
+typedef struct Vector3
+{
+ sll x;
+ sll y;
+ sll z;
+}Vector3;
+
+typedef struct Vector4
+{
+ sll x;
+ sll y;
+ sll z;
+ sll w;
+
+}Vector4;
+#endif