Skip to content

Commit 55f7209

Browse files
committed
The Physics Library 🍎
Converted to C++ (not guaranteed to work by this point, atleast it's free from compiler error and warns)
1 parent 55ce1ac commit 55f7209

33 files changed

+3446
-0
lines changed

source/CMakeLists.txt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,53 @@ set(forth_visualizer_srcs
5050
visualizer/WireVisualizer.h
5151
)
5252

53+
set(forth_physics_broadphase_srcs
54+
physics/broadphase/BroadPhase.cpp
55+
physics/broadphase/BroadPhase.h
56+
physics/broadphase/DynamicTree.cpp
57+
physics/broadphase/DynamicTree.h
58+
)
59+
60+
set(forth_physics_collision_srcs
61+
physics/collision/Algorithm.cpp
62+
physics/collision/Algorithm.h
63+
physics/collision/Box.cpp
64+
physics/collision/Box.h
65+
physics/collision/Capsule.cpp
66+
physics/collision/Capsule.h
67+
physics/collision/Collide.cpp
68+
physics/collision/Collide.h
69+
physics/collision/Convex.h
70+
physics/collision/Shape.cpp
71+
physics/collision/Shape.h
72+
physics/collision/Sphere.cpp
73+
physics/collision/Sphere.h
74+
)
75+
76+
set(forth_physics_dynamics_srcs
77+
physics/dynamics/Body.cpp
78+
physics/dynamics/Body.h
79+
physics/dynamics/Contact.cpp
80+
physics/dynamics/Contact.h
81+
physics/dynamics/ContactManager.cpp
82+
physics/dynamics/ContactManager.h
83+
physics/dynamics/ContactSolver.cpp
84+
physics/dynamics/ContactSolver.h
85+
physics/dynamics/Island.cpp
86+
physics/dynamics/Island.h
87+
physics/dynamics/RaycastHit4.h
88+
physics/dynamics/Scene.cpp
89+
physics/dynamics/Scene.h
90+
)
91+
92+
set(forth_physics_srcs
93+
physics/Common.cpp
94+
physics/Common.h
95+
${forth_physics_broadphase_srcs}
96+
${forth_physics_collision_srcs}
97+
${forth_physics_dynamics_srcs}
98+
)
99+
53100
add_library(forth_static
54101
../include/forth.h
55102
forth.h
@@ -58,6 +105,7 @@ add_library(forth_static
58105
${forth_math_srcs}
59106
${forth_rendering_srcs}
60107
${forth_visualizer_srcs}
108+
${forth_physics_srcs}
61109
)
62110

63111
set_target_properties(forth_static PROPERTIES LINKER_LANGUAGE CXX)

source/physics/Common.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include "Common.h"
2+
#include "collision/Shape.h"
3+
4+
namespace Forth
5+
{
6+
namespace Physics
7+
{
8+
Vector4 Common::GRAVITY = Vector4(0, -9.8f, 0, 0);
9+
Bounds4 Common::SIM_RANGE = Bounds4(Vector4(-1000), Vector4(1000));
10+
int Common::ITERATIONS = 15;
11+
bool Common::ALLOW_SLEEP = true;
12+
bool Common::ENABLE_FRICTION = true;
13+
float Common::SLEEP_LINEAR = 0.01f;
14+
float Common::SLEEP_ANGULAR = (2 / 180.f) * PI;
15+
float Common::SLEEP_TIME = 0.5f;
16+
float Common::BAUMGARTE = 0.2f;
17+
float Common::PENETRATION_SLOP = 0.02f;
18+
float Common::MAX_DT = 0.02f;
19+
20+
float Common::DefMixRestitution(Shape* A, Shape* B)
21+
{
22+
return A->restitution > B->restitution ? A->restitution : B->restitution;
23+
}
24+
float Common::DefMixFriction(Shape* A, Shape* B)
25+
{
26+
return (A->friction + B->friction) * 0.5f;
27+
}
28+
29+
static Common::ShapeMixCB MixRestitution = Common::DefMixRestitution;
30+
static Common::ShapeMixCB MixFriction = Common::DefMixFriction;
31+
} // namespace Physics
32+
} // namespace Forth

source/physics/Common.h

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#pragma once
2+
3+
#include "../extras/Utils.h"
4+
#include "../math/Bounds4.h"
5+
#include "../math/math.h"
6+
#include "../math/Matrix4.h"
7+
#include "../math/Plane4.h"
8+
#include "../math/Ray4.h"
9+
#include "../math/Transform4.h"
10+
#include "../math/Vector4.h"
11+
#include "../math/Tensor4.h"
12+
#include <vector>
13+
#include <stack>
14+
#include <map>
15+
#include <algorithm>
16+
17+
namespace Forth
18+
{
19+
namespace Physics
20+
{
21+
/// Common constant for physics simulation
22+
struct Common
23+
{
24+
25+
/// <summary>
26+
/// Default gravity for all simulations.
27+
/// This parameter can be dynamically adjusted.
28+
/// </summary>
29+
static Vector4 GRAVITY;
30+
31+
/// <summary>
32+
/// Simulation range helps to avoid wasted time computation of computing
33+
/// Objects that out of range (e.g. object keeps falling down).
34+
/// The object is deactivated once becomes so.
35+
/// </summary>
36+
static Bounds4 SIM_RANGE;
37+
38+
/// <summary>
39+
/// Constant collision solving iteration.
40+
/// Higher values are more realistic, yet more expensive.
41+
/// Default is 15, can be put between 5 to 20
42+
/// </summary>
43+
static int ITERATIONS;
44+
45+
/// <summary>
46+
/// Enables or disables rigid body sleeping.
47+
/// It's an important optimization on every physics engine.
48+
/// It's recommended to leave this on.
49+
/// </summary>
50+
static bool ALLOW_SLEEP;
51+
52+
/// <summary>
53+
/// When two objects lay on each other should the simulator simulate friction?
54+
/// It's recommended to leave this on.
55+
/// </summary>
56+
static bool ENABLE_FRICTION;
57+
58+
/// <summary>
59+
/// Constant maximum multi contact count. Don't change.
60+
/// </summary>
61+
const static int MULTICONTACT_COUNT = 16;
62+
63+
/// <summary>
64+
/// Maximum allowed linear velocity that makes a rigidbody sleeps (Default is 0.01)
65+
/// </summary>
66+
static float SLEEP_LINEAR;
67+
68+
/// <summary>
69+
/// Maximum allowed angular velocity that makes a rigidbody sleeps (Default is 2 deg)
70+
/// </summary>
71+
static float SLEEP_ANGULAR;
72+
73+
/// <summary>
74+
/// Simulator don't make rigidbody sleeps instantly.
75+
/// They have a chance by given time to awake by itself. (Default is 0.5)
76+
/// </summary>
77+
static float SLEEP_TIME;
78+
79+
/// <summary>
80+
/// How fast the collision must be resolved? (Default is 0.2)
81+
/// </summary>
82+
static float BAUMGARTE;
83+
84+
/// <summary>
85+
/// Offset of allowed contact depth before kicked out by the solver.
86+
/// Allow very small number to avoid jitter. (Default is 0.05)
87+
/// </summary>
88+
static float PENETRATION_SLOP;
89+
90+
/// <summary>
91+
/// Maximum allowed delta time. This prevents objects bypassing
92+
/// each other because of too large delta time. (Default is 0.02)
93+
/// </summary>
94+
static float MAX_DT;
95+
96+
typedef float(*ShapeMixCB)(class Shape*, class Shape*);
97+
98+
static ShapeMixCB MixRestitution;
99+
static ShapeMixCB MixFriction;
100+
101+
/// <summary>
102+
/// Restitution (bounce) mixing. Default is max
103+
/// </summary>
104+
static float DefMixRestitution(class Shape* A, class Shape* B);
105+
106+
/// <summary>
107+
/// Friction (slide) mixing. Default is average
108+
/// </summary>
109+
static float DefMixFriction(class Shape* A, class Shape* B);
110+
};
111+
} // namespace Physics
112+
} // namespace Forth
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "BroadPhase.h"
2+
#include "../dynamics/ContactManager.h"
3+
4+
namespace Forth
5+
{
6+
namespace Physics
7+
{
8+
BroadPhase::BroadPhase(ContactManager* manager)
9+
{
10+
Manager = manager;
11+
12+
PairBuffer = ::std::vector<ContactPair>();
13+
MoveBuffer = ::std::vector<int>();
14+
}
15+
16+
void BroadPhase::InsertShape(Shape* shape, const Bounds4 &aabb)
17+
{
18+
int id = Tree.Insert(aabb, shape);
19+
shape->broadPhaseIndex = id;
20+
BufferMove(id);
21+
}
22+
23+
void BroadPhase::RemoveShape(Shape* shape)
24+
{
25+
Tree.Remove(shape->broadPhaseIndex);
26+
}
27+
28+
// Generates the contact list.
29+
30+
void BroadPhase::UpdatePairs()
31+
{
32+
PairBuffer.clear();
33+
34+
// Query the tree with all moving boxs
35+
for (size_t i = 0; i < MoveBuffer.size(); ++i)
36+
{
37+
CurrentIndex = MoveBuffer[i];
38+
39+
Tree.Query(this, Tree.GetFatAABB(CurrentIndex));
40+
}
41+
42+
// Reset the move buffer
43+
MoveBuffer.clear();
44+
45+
for (size_t i = 0; i < PairBuffer.size(); ++i)
46+
{
47+
// Add contact to manager
48+
ContactPair pair = PairBuffer[i];
49+
Manager->AddContact(Tree.GetShape(pair.A), Tree.GetShape(pair.B));
50+
}
51+
}
52+
53+
void BroadPhase::Update(int id, Bounds4 aabb)
54+
{
55+
if (Tree.Update(id, aabb))
56+
BufferMove(id);
57+
}
58+
59+
bool BroadPhase::TestOverlap(int A, int B)
60+
{
61+
return IsIntersecting(Tree.GetFatAABB(A), Tree.GetFatAABB(B));
62+
}
63+
64+
void BroadPhase::BufferMove(int id)
65+
{
66+
MoveBuffer.push_back(id);
67+
}
68+
69+
void BroadPhase::TreeCallback(int index)
70+
{
71+
// Cannot collide with self
72+
if (index == CurrentIndex)
73+
return;
74+
75+
int iA = Min(index, CurrentIndex);
76+
int iB = Max(index, CurrentIndex);
77+
78+
PairBuffer.push_back({ iA, iB });
79+
}
80+
81+
} // namespace Physics
82+
} // namespace Forth
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma once
2+
3+
#include "../Common.h"
4+
#include "DynamicTree.h"
5+
6+
namespace Forth
7+
{
8+
namespace Physics
9+
{
10+
struct ContactPair
11+
{
12+
int A;
13+
int B;
14+
};
15+
16+
class BroadPhase : public ITreeCallback
17+
{
18+
public:
19+
BroadPhase() {}
20+
21+
BroadPhase(class ContactManager *manager);
22+
23+
void InsertShape(Shape *shape, const Bounds4 &aabb);
24+
25+
void RemoveShape(Shape *shape);
26+
27+
// Generates the contact list.
28+
void UpdatePairs();
29+
30+
void Update(int id, Bounds4 aabb);
31+
32+
bool TestOverlap(int A, int B);
33+
34+
class ContactManager *Manager;
35+
36+
::std::vector<ContactPair> PairBuffer;
37+
38+
::std::vector<int> MoveBuffer;
39+
40+
DynamicTree Tree = DynamicTree();
41+
42+
int CurrentIndex;
43+
44+
void BufferMove(int id);
45+
46+
void TreeCallback(int index);
47+
};
48+
} // namespace Physics
49+
} // namespace Forth

0 commit comments

Comments
 (0)