Grindstone Game Engine
v0.2.0
An open source game engine and toolkit.
Toggle main menu visibility
Loading...
Searching...
No Matches
PhysicsWorldContext.hpp
1
#pragma once
2
3
#include <Jolt/Physics/PhysicsSystem.h>
4
#include <Jolt/Core/TempAllocator.h>
5
#include <Jolt/Core/JobSystemThreadPool.h>
6
#include <Jolt/Physics/Body/BodyActivationListener.h>
7
8
#include <Common/HashedString.hpp>
9
#include <Common/Memory/SmartPointers/UniquePtr.hpp>
10
#include <EngineCore/WorldContext/WorldContext.hpp>
11
12
const
Grindstone::ConstHashedString
physicsWorldContextName(
"Grindstone::Physics::WorldContext"
);
13
14
namespace
Grindstone::Physics
{
15
// Layer that objects can be in, determines which other objects it can collide with
16
// Typically you at least want to have 1 layer for moving bodies and 1 layer for static bodies, but you can have more
17
// layers if you want. E.g. you could have a layer for high detail collision (which is not used by the physics simulation
18
// but only if you do collision testing).
19
namespace
Layers
{
20
static
constexpr
JPH::ObjectLayer NON_MOVING = 0;
21
static
constexpr
JPH::ObjectLayer MOVING = 1;
22
static
constexpr
JPH::ObjectLayer NUM_LAYERS = 2;
23
};
24
26
class
ObjectLayerPairFilterImpl
:
public
JPH::ObjectLayerPairFilter {
27
public
:
28
virtual
bool
ShouldCollide(JPH::ObjectLayer inObject1, JPH::ObjectLayer inObject2)
const override
{
29
switch
(inObject1) {
30
case
Layers::NON_MOVING:
31
return
inObject2 == Layers::MOVING;
// Non moving only collides with moving
32
case
Layers::MOVING:
33
return
true
;
// Moving collides with everything
34
default
:
35
JPH_ASSERT(
false
);
36
return
false
;
37
}
38
}
39
};
40
41
// Each broadphase layer results in a separate bounding volume tree in the broad phase. You at least want to have
42
// a layer for non-moving and moving objects to avoid having to update a tree full of static objects every frame.
43
// You can have a 1-on-1 mapping between object layers and broadphase layers (like in this case) but if you have
44
// many object layers you'll be creating many broad phase trees, which is not efficient. If you want to fine tune
45
// your broadphase layers define JPH_TRACK_BROADPHASE_STATS and look at the stats reported on the TTY.
46
namespace
BroadPhaseLayers
{
47
static
constexpr
JPH::BroadPhaseLayer NON_MOVING(0);
48
static
constexpr
JPH::BroadPhaseLayer MOVING(1);
49
static
constexpr
uint32_t NUM_LAYERS(2);
50
};
51
52
// BroadPhaseLayerInterface implementation
53
// This defines a mapping between object and broadphase layers.
54
class
BPLayerInterfaceImpl final :
public
JPH::BroadPhaseLayerInterface {
55
public
:
56
BPLayerInterfaceImpl() {
57
// Create a mapping table from object to broad phase layer
58
mObjectToBroadPhase[Layers::NON_MOVING] = BroadPhaseLayers::NON_MOVING;
59
mObjectToBroadPhase[Layers::MOVING] = BroadPhaseLayers::MOVING;
60
}
61
62
virtual
uint32_t GetNumBroadPhaseLayers()
const override
{
63
return
BroadPhaseLayers::NUM_LAYERS;
64
}
65
66
virtual
JPH::BroadPhaseLayer GetBroadPhaseLayer(JPH::ObjectLayer inLayer)
const override
{
67
JPH_ASSERT(inLayer < Layers::NUM_LAYERS);
68
return
mObjectToBroadPhase[inLayer];
69
}
70
71
#if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED)
72
virtual
const
char
* GetBroadPhaseLayerName(JPH::BroadPhaseLayer inLayer)
const override
{
73
switch
((JPH::BroadPhaseLayer::Type)inLayer) {
74
case
(JPH::BroadPhaseLayer::Type)BroadPhaseLayers::NON_MOVING:
return
"NON_MOVING"
;
75
case
(JPH::BroadPhaseLayer::Type)BroadPhaseLayers::MOVING:
return
"MOVING"
;
76
default
: JPH_ASSERT(
false
);
return
"INVALID"
;
77
}
78
}
79
#endif
// JPH_EXTERNAL_PROFILE || JPH_PROFILE_ENABLED
80
81
private
:
82
JPH::BroadPhaseLayer mObjectToBroadPhase[Layers::NUM_LAYERS];
83
};
84
86
class
ObjectVsBroadPhaseLayerFilterImpl
:
public
JPH::ObjectVsBroadPhaseLayerFilter {
87
public
:
88
virtual
bool
ShouldCollide(JPH::ObjectLayer inLayer1, JPH::BroadPhaseLayer inLayer2)
const override
{
89
switch
(inLayer1) {
90
case
Layers::NON_MOVING:
91
return
inLayer2 == BroadPhaseLayers::MOVING;
92
case
Layers::MOVING:
93
return
true
;
94
default
:
95
JPH_ASSERT(
false
);
96
return
false
;
97
}
98
}
99
};
100
101
// An example contact listener
102
class
MyContactListener
:
public
JPH::ContactListener {
103
public
:
104
// See: ContactListener
105
virtual
JPH::ValidateResult OnContactValidate(
const
JPH::Body& inBody1,
const
JPH::Body& inBody2, JPH::RVec3Arg inBaseOffset,
const
JPH::CollideShapeResult& inCollisionResult)
override
{
106
std::cout <<
"Contact validate callback"
<< std::endl;
107
108
// Allows you to ignore a contact before it is created (using layers to not make objects collide is cheaper!)
109
return
JPH::ValidateResult::AcceptAllContactsForThisBodyPair;
110
}
111
112
virtual
void
OnContactAdded(
const
JPH::Body& inBody1,
const
JPH::Body& inBody2,
const
JPH::ContactManifold& inManifold, JPH::ContactSettings& ioSettings)
override
{
113
std::cout <<
"A contact was added"
<< std::endl;
114
}
115
116
virtual
void
OnContactPersisted(
const
JPH::Body& inBody1,
const
JPH::Body& inBody2,
const
JPH::ContactManifold& inManifold, JPH::ContactSettings& ioSettings)
override
{
117
}
118
119
virtual
void
OnContactRemoved(
const
JPH::SubShapeIDPair& inSubShapePair)
override
{
120
std::cout <<
"A contact was removed"
<< std::endl;
121
}
122
};
123
124
// An example activation listener
125
class
MyBodyActivationListener
:
public
JPH::BodyActivationListener {
126
public
:
127
virtual
void
OnBodyActivated(
const
JPH::BodyID& inBodyID, uint64_t inBodyUserData)
override
{
128
std::cout <<
"A body got activated"
<< std::endl;
129
}
130
131
virtual
void
OnBodyDeactivated(
const
JPH::BodyID& inBodyID, uint64_t inBodyUserData)
override
{
132
std::cout <<
"A body went to sleep"
<< std::endl;
133
}
134
};
135
136
class
WorldContext
:
public
Grindstone::WorldContext
{
137
public
:
138
WorldContext
();
139
WorldContext
(
const
WorldContext
&) =
delete
;
140
WorldContext
(
WorldContext
&& ) noexcept = default;
141
virtual ~
WorldContext
() override = default;
142
143
JPH
::BodyInterface& GetBodyInterface();
144
JPH
::PhysicsSystem& GetPhysicsSystem();
145
JPH
::TempAllocatorImpl& GetTempAllocator();
146
JPH
::JobSystemThreadPool& GetJobSystem();
147
148
[[nodiscard]] static
WorldContext
* GetActiveContext();
149
static
void
SetActiveContext(
WorldContext
& cxt);
150
virtual
void
SetAsActive() override;
151
152
protected:
153
JPH
::TempAllocatorImpl tempAllocator;
154
JPH
::JobSystemThreadPool jobSystem;
155
JPH
::PhysicsSystem physicsSystem;
156
JPH
::BodyInterface* bodyInterface =
nullptr
;
157
158
BPLayerInterfaceImpl
broadphaseLayerInterface;
159
ObjectVsBroadPhaseLayerFilterImpl
objectVsBroadphaseLayerFilter;
160
ObjectLayerPairFilterImpl
objectVsObjectLayerFilter;
161
MyBodyActivationListener
bodyActivationListener;
162
MyContactListener
contactListener;
163
};
164
}
Grindstone::ConstHashedString
Definition
HashedString.hpp:54
Grindstone::Physics::BPLayerInterfaceImpl
Definition
PhysicsWorldContext.hpp:54
Grindstone::Physics::MyBodyActivationListener
Definition
PhysicsWorldContext.hpp:125
Grindstone::Physics::MyContactListener
Definition
PhysicsWorldContext.hpp:102
Grindstone::Physics::ObjectLayerPairFilterImpl
Class that determines if two object layers can collide.
Definition
PhysicsWorldContext.hpp:26
Grindstone::Physics::ObjectVsBroadPhaseLayerFilterImpl
Class that determines if an object layer can collide with a broadphase layer.
Definition
PhysicsWorldContext.hpp:86
Grindstone::Physics::WorldContext
Definition
PhysicsWorldContext.hpp:12
Grindstone::WorldContext
Definition
WorldContext.hpp:7
Grindstone::Physics::BroadPhaseLayers
Definition
PhysicsWorldContext.hpp:46
Grindstone::Physics::Layers
Definition
PhysicsWorldContext.hpp:19
Grindstone::Physics
Definition
PhysicsLayer.hpp:6
JPH
Definition
CharacterKinematicControllerComponent.hpp:16
plugins
Grindstone.Physics.Jolt
include
PhysicsWorldContext.hpp
Generated by
1.17.0