Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/modules/jolt_physics/spaces/jolt_layers.cpp
10278 views
1
/**************************************************************************/
2
/* jolt_layers.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "jolt_layers.h"
32
33
#include "../jolt_project_settings.h"
34
#include "jolt_broad_phase_layer.h"
35
36
#include "core/error/error_macros.h"
37
#include "core/variant/variant.h"
38
39
static_assert(sizeof(JPH::ObjectLayer) == 2, "Size of Jolt's object layer has changed.");
40
static_assert(sizeof(JPH::BroadPhaseLayer::Type) == 1, "Size of Jolt's broadphase layer has changed.");
41
static_assert(JoltBroadPhaseLayer::COUNT <= 8, "Maximum number of broadphase layers exceeded.");
42
43
namespace {
44
45
template <uint8_t TSize = JoltBroadPhaseLayer::COUNT>
46
class JoltBroadPhaseMatrix {
47
typedef JPH::BroadPhaseLayer LayerType;
48
typedef LayerType::Type UnderlyingType;
49
50
public:
51
JoltBroadPhaseMatrix() {
52
using namespace JoltBroadPhaseLayer;
53
54
allow_collision(BODY_STATIC, BODY_DYNAMIC);
55
allow_collision(BODY_STATIC, AREA_DETECTABLE);
56
allow_collision(BODY_STATIC, AREA_UNDETECTABLE);
57
allow_collision(BODY_STATIC_BIG, BODY_DYNAMIC);
58
allow_collision(BODY_STATIC_BIG, AREA_DETECTABLE);
59
allow_collision(BODY_STATIC_BIG, AREA_UNDETECTABLE);
60
allow_collision(BODY_DYNAMIC, BODY_STATIC);
61
allow_collision(BODY_DYNAMIC, BODY_STATIC_BIG);
62
allow_collision(BODY_DYNAMIC, BODY_DYNAMIC);
63
allow_collision(BODY_DYNAMIC, AREA_DETECTABLE);
64
allow_collision(BODY_DYNAMIC, AREA_UNDETECTABLE);
65
allow_collision(AREA_DETECTABLE, BODY_DYNAMIC);
66
allow_collision(AREA_DETECTABLE, BODY_STATIC);
67
allow_collision(AREA_DETECTABLE, BODY_STATIC_BIG);
68
allow_collision(AREA_DETECTABLE, AREA_DETECTABLE);
69
allow_collision(AREA_DETECTABLE, AREA_UNDETECTABLE);
70
allow_collision(AREA_UNDETECTABLE, BODY_DYNAMIC);
71
allow_collision(AREA_UNDETECTABLE, BODY_STATIC);
72
allow_collision(AREA_UNDETECTABLE, BODY_STATIC_BIG);
73
allow_collision(AREA_UNDETECTABLE, AREA_DETECTABLE);
74
}
75
76
void allow_collision(UnderlyingType p_layer1, UnderlyingType p_layer2) { masks[p_layer1] |= uint8_t(1U << p_layer2); }
77
void allow_collision(LayerType p_layer1, LayerType p_layer2) { allow_collision((UnderlyingType)p_layer1, (UnderlyingType)p_layer2); }
78
79
bool should_collide(UnderlyingType p_layer1, UnderlyingType p_layer2) const { return (masks[p_layer1] & uint8_t(1U << p_layer2)) != 0; }
80
bool should_collide(LayerType p_layer1, LayerType p_layer2) const { return should_collide((UnderlyingType)p_layer1, (UnderlyingType)p_layer2); }
81
82
private:
83
uint8_t masks[TSize] = {};
84
};
85
86
constexpr JPH::ObjectLayer encode_layers(JPH::BroadPhaseLayer p_broad_phase_layer, JPH::ObjectLayer p_object_layer) {
87
const uint16_t upper_bits = uint16_t((uint8_t)p_broad_phase_layer << 13U);
88
const uint16_t lower_bits = uint16_t(p_object_layer);
89
return JPH::ObjectLayer(upper_bits | lower_bits);
90
}
91
92
constexpr void decode_layers(JPH::ObjectLayer p_encoded_layers, JPH::BroadPhaseLayer &r_broad_phase_layer, JPH::ObjectLayer &r_object_layer) {
93
r_broad_phase_layer = JPH::BroadPhaseLayer(uint8_t(p_encoded_layers >> 13U));
94
r_object_layer = JPH::ObjectLayer(p_encoded_layers & 0b0001'1111'1111'1111U);
95
}
96
97
constexpr uint64_t encode_collision(uint32_t p_collision_layer, uint32_t p_collision_mask) {
98
const uint64_t upper_bits = (uint64_t)p_collision_layer << 32U;
99
const uint64_t lower_bits = (uint64_t)p_collision_mask;
100
return upper_bits | lower_bits;
101
}
102
103
constexpr void decode_collision(uint64_t p_collision, uint32_t &r_collision_layer, uint32_t &r_collision_mask) {
104
r_collision_layer = uint32_t(p_collision >> 32U);
105
r_collision_mask = uint32_t(p_collision & 0xFFFFFFFFU);
106
}
107
108
} // namespace
109
110
uint32_t JoltLayers::GetNumBroadPhaseLayers() const {
111
return JoltBroadPhaseLayer::COUNT;
112
}
113
114
JPH::BroadPhaseLayer JoltLayers::GetBroadPhaseLayer(JPH::ObjectLayer p_layer) const {
115
JPH::BroadPhaseLayer broad_phase_layer = JoltBroadPhaseLayer::BODY_STATIC;
116
JPH::ObjectLayer object_layer = 0;
117
decode_layers(p_layer, broad_phase_layer, object_layer);
118
119
return broad_phase_layer;
120
}
121
122
#if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED)
123
124
const char *JoltLayers::GetBroadPhaseLayerName(JPH::BroadPhaseLayer p_layer) const {
125
switch ((JPH::BroadPhaseLayer::Type)p_layer) {
126
case (JPH::BroadPhaseLayer::Type)JoltBroadPhaseLayer::BODY_STATIC: {
127
return "BODY_STATIC";
128
}
129
case (JPH::BroadPhaseLayer::Type)JoltBroadPhaseLayer::BODY_STATIC_BIG: {
130
return "BODY_STATIC_BIG";
131
}
132
case (JPH::BroadPhaseLayer::Type)JoltBroadPhaseLayer::BODY_DYNAMIC: {
133
return "BODY_DYNAMIC";
134
}
135
case (JPH::BroadPhaseLayer::Type)JoltBroadPhaseLayer::AREA_DETECTABLE: {
136
return "AREA_DETECTABLE";
137
}
138
case (JPH::BroadPhaseLayer::Type)JoltBroadPhaseLayer::AREA_UNDETECTABLE: {
139
return "AREA_UNDETECTABLE";
140
}
141
default: {
142
return "UNKNOWN";
143
}
144
}
145
}
146
147
#endif
148
149
bool JoltLayers::ShouldCollide(JPH::ObjectLayer p_encoded_layer1, JPH::ObjectLayer p_encoded_layer2) const {
150
JPH::BroadPhaseLayer broad_phase_layer1 = JoltBroadPhaseLayer::BODY_STATIC;
151
uint32_t collision_layer1 = 0;
152
uint32_t collision_mask1 = 0;
153
from_object_layer(p_encoded_layer1, broad_phase_layer1, collision_layer1, collision_mask1);
154
155
JPH::BroadPhaseLayer broad_phase_layer2 = JoltBroadPhaseLayer::BODY_STATIC;
156
uint32_t collision_layer2 = 0;
157
uint32_t collision_mask2 = 0;
158
from_object_layer(p_encoded_layer2, broad_phase_layer2, collision_layer2, collision_mask2);
159
160
const bool first_scans_second = (collision_mask1 & collision_layer2) != 0;
161
const bool second_scans_first = (collision_mask2 & collision_layer1) != 0;
162
163
return first_scans_second || second_scans_first;
164
}
165
166
bool JoltLayers::ShouldCollide(JPH::ObjectLayer p_encoded_layer1, JPH::BroadPhaseLayer p_broad_phase_layer2) const {
167
static const JoltBroadPhaseMatrix matrix;
168
169
JPH::BroadPhaseLayer broad_phase_layer1 = JoltBroadPhaseLayer::BODY_STATIC;
170
JPH::ObjectLayer object_layer1 = 0;
171
decode_layers(p_encoded_layer1, broad_phase_layer1, object_layer1);
172
173
return matrix.should_collide(broad_phase_layer1, p_broad_phase_layer2);
174
}
175
176
JPH::ObjectLayer JoltLayers::_allocate_object_layer(uint64_t p_collision) {
177
const JPH::ObjectLayer new_object_layer = next_object_layer++;
178
179
collisions_by_layer.resize(new_object_layer + 1);
180
collisions_by_layer[new_object_layer] = p_collision;
181
182
layers_by_collision[p_collision] = new_object_layer;
183
184
return new_object_layer;
185
}
186
187
JoltLayers::JoltLayers() {
188
_allocate_object_layer(0);
189
}
190
191
// MinGW GCC using LTO will emit errors during linking if this is defined in the header file, implicitly or otherwise.
192
// Likely caused by this GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94156
193
JoltLayers::~JoltLayers() = default;
194
195
JPH::ObjectLayer JoltLayers::to_object_layer(JPH::BroadPhaseLayer p_broad_phase_layer, uint32_t p_collision_layer, uint32_t p_collision_mask) {
196
const uint64_t collision = encode_collision(p_collision_layer, p_collision_mask);
197
198
JPH::ObjectLayer object_layer = 0;
199
200
HashMap<uint64_t, JPH::ObjectLayer>::Iterator iter = layers_by_collision.find(collision);
201
if (iter != layers_by_collision.end()) {
202
object_layer = iter->value;
203
} else {
204
constexpr uint16_t object_layer_count = 1U << 13U;
205
206
ERR_FAIL_COND_V_MSG(next_object_layer == object_layer_count, 0,
207
vformat("Maximum number of object layers (%d) reached. "
208
"This means there are %d combinations of collision layers and masks."
209
"This should not happen under normal circumstances. Consider reporting this.",
210
object_layer_count, object_layer_count));
211
212
object_layer = _allocate_object_layer(collision);
213
}
214
215
return encode_layers(p_broad_phase_layer, object_layer);
216
}
217
218
void JoltLayers::from_object_layer(JPH::ObjectLayer p_encoded_layer, JPH::BroadPhaseLayer &r_broad_phase_layer, uint32_t &r_collision_layer, uint32_t &r_collision_mask) const {
219
JPH::ObjectLayer object_layer = 0;
220
decode_layers(p_encoded_layer, r_broad_phase_layer, object_layer);
221
222
const uint64_t collision = collisions_by_layer[object_layer];
223
decode_collision(collision, r_collision_layer, r_collision_mask);
224
}
225
226