Skip to content

Commit f31dcdd

Browse files
committed
refactor: use CollisionLayer enum instead of string comparisons
1 parent 363559c commit f31dcdd

4 files changed

Lines changed: 33 additions & 42 deletions

File tree

src/game/components/collider.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,24 @@ static gameplay::ColliderShape parseColliderShape(const std::string& value, game
66
return fallback;
77
}
88

9+
static inline gameplay::CollisionLayer layerStringToGroup(const std::string& layer) {
10+
if (layer == "player") return gameplay::CollisionLayer::LAYER_PLAYER;
11+
if (layer == "enemy") return gameplay::CollisionLayer::LAYER_ENEMY;
12+
if (layer == "projectile") return gameplay::CollisionLayer::LAYER_PROJECTILE;
13+
if (layer == "trigger") return gameplay::CollisionLayer::LAYER_TRIGGER;
14+
return gameplay::CollisionLayer::LAYER_ENVIRONMENT; // environment is the default layer
15+
}
16+
917
namespace gameplay {
1018

1119
void ColliderComponent::deserialize(const nlohmann::json& data) {
1220
if (!data.is_object()) return;
1321
shape = parseColliderShape(data.value("shape", std::string("Sphere")), shape);
14-
layer = data.value("layer", layer);
1522
radius = data.value("radius", radius);
1623
height = data.value("height", height);
1724
isTrigger = data.value("isTrigger", isTrigger);
25+
std::string stringLayer = data.value("layer", "");
26+
layer = layerStringToGroup(stringLayer);
1827
}
1928

2029
} // namespace gameplay

src/game/components/collider.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,18 @@ namespace gameplay {
66

77
enum class ColliderShape { Sphere, Capsule };
88

9+
enum CollisionLayer : short {
10+
LAYER_PLAYER = 1 << 0, // bit 0: 0000 0001
11+
LAYER_ENEMY = 1 << 1, // bit 1: 0000 0010
12+
LAYER_ENVIRONMENT = 1 << 2, // bit 2: 0000 0100
13+
LAYER_PROJECTILE = 1 << 3, // bit 3: 0000 1000
14+
LAYER_TRIGGER = 1 << 4, // bit 4: 0001 0000
15+
};
16+
917
class ColliderComponent : public our::Component {
1018
public:
1119
ColliderShape shape = ColliderShape::Sphere;
12-
std::string layer = "default";
20+
CollisionLayer layer = CollisionLayer::LAYER_ENVIRONMENT;
1321
float radius = 0.5f;
1422
float height = 1.0f; // must be the total height
1523
bool isTrigger = false;

src/game/systems/collision-system.cpp

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,6 @@ static btTransform entityToBtTransform(our::Entity* entity) {
3737

3838
namespace gameplay {
3939

40-
inline short layerStringToGroup(const std::string& layer) {
41-
if (layer == "player") return CollisionLayer::LAYER_PLAYER;
42-
if (layer == "enemy") return CollisionLayer::LAYER_ENEMY;
43-
if (layer == "environment") return CollisionLayer::LAYER_ENVIRONMENT;
44-
if (layer == "projectile") return CollisionLayer::LAYER_PROJECTILE;
45-
if (layer == "trigger") return CollisionLayer::LAYER_TRIGGER;
46-
return 0; // default to no layer
47-
}
48-
4940
inline short getMaskForLayer(short group) {
5041
switch (group) {
5142
case LAYER_PLAYER:
@@ -179,9 +170,9 @@ namespace gameplay {
179170
if (colliderA->isTrigger || colliderB->isTrigger) continue;
180171

181172
// push back logic (don't push environments)
182-
if (colliderA->layer == "environment") {
173+
if (colliderA->layer == CollisionLayer::LAYER_ENVIRONMENT) {
183174
event.entityB->localTransform.position -= event.normal * event.penetrationDepth;
184-
} else if (colliderB->layer == "environment") {
175+
} else if (colliderB->layer == CollisionLayer::LAYER_ENVIRONMENT) {
185176
event.entityA->localTransform.position += event.normal * event.penetrationDepth;
186177
} else { // this may be edited or removed later
187178
event.entityA->localTransform.position -= event.normal * (event.penetrationDepth / 2.0f);
@@ -191,18 +182,17 @@ namespace gameplay {
191182
}
192183

193184
// On-demand function
194-
HitInfo CollisionSystem::raycast(const Ray& ray, float maxDistance, const std::string targetLayer) const {
185+
HitInfo CollisionSystem::raycast(const Ray& ray, float maxDistance, const short targetLayer) const {
195186
HitInfo hitInfo;
196187

197188
if (!collisionWorld) return hitInfo;
198189
btVector3 from = glmToBtVec3(ray.origin);
199190
btVector3 to = glmToBtVec3(ray.origin + ray.direction * maxDistance);
200191

201192
btCollisionWorld::ClosestRayResultCallback callback(from, to);
202-
if (!targetLayer.empty()) {
203-
callback.m_collisionFilterGroup = btBroadphaseProxy::AllFilter; // check against all layers
204-
callback.m_collisionFilterMask = layerStringToGroup(targetLayer); // only collide with the target layer
205-
}
193+
194+
callback.m_collisionFilterGroup = btBroadphaseProxy::AllFilter; // check against all layers
195+
callback.m_collisionFilterMask = targetLayer; // only collide with the target layer
206196

207197
collisionWorld->rayTest(from, to, callback);
208198

@@ -218,21 +208,13 @@ namespace gameplay {
218208
}
219209

220210
// On-demand function
221-
std::vector<our::Entity*> CollisionSystem::overlapSphere(const glm::vec3& center, float radius,
222-
std::string targetLayer) {
211+
std::vector<our::Entity*> CollisionSystem::overlapSphere(const glm::vec3& center, float radius, short targetLayer) {
223212
std::vector<our::Entity*> results;
224213
if (!collisionWorld) return results;
225214

226-
short targetMask = 0;
227-
if (!targetLayer.empty()) {
228-
targetMask = layerStringToGroup(targetLayer);
229-
}
230-
231215
for (const auto& [entity, obj] : entityToBullet) {
232-
if (targetMask != 0) {
233-
short objGroup = obj->getBroadphaseHandle()->m_collisionFilterGroup;
234-
if ((objGroup & targetMask) == 0) continue;
235-
}
216+
short objGroup = obj->getBroadphaseHandle()->m_collisionFilterGroup;
217+
if ((objGroup & targetLayer) == 0) continue;
236218

237219
glm::vec3 entityPos = btToGlmVec3(obj->getWorldTransform().getOrigin());
238220

@@ -276,12 +258,12 @@ namespace gameplay {
276258
obj->setUserPointer(entity); // so we can go back to the entity
277259

278260
// Mark non-environment objects as KINEMATIC.
279-
if (collider->layer != "environment") {
261+
if (collider->layer != CollisionLayer::LAYER_ENVIRONMENT) {
280262
obj->setCollisionFlags(obj->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
281263
}
282264

283265
// Add to Bullet world with layer filtering
284-
short group = layerStringToGroup(collider->layer);
266+
short group = collider->layer;
285267
short mask = getMaskForLayer(group);
286268
collisionWorld->addCollisionObject(obj, group, mask);
287269
entityToBullet[entity] = obj;

src/game/systems/collision-system.hpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,6 @@ namespace gameplay {
3939
float penetrationDepth = 0.0f; // how much the two colliders are penetrating each other
4040
};
4141

42-
enum CollisionLayer : short {
43-
LAYER_PLAYER = 1 << 0, // bit 0: 0000 0001
44-
LAYER_ENEMY = 1 << 1, // bit 1: 0000 0010
45-
LAYER_ENVIRONMENT = 1 << 2, // bit 2: 0000 0100
46-
LAYER_PROJECTILE = 1 << 3, // bit 3: 0000 1000
47-
LAYER_TRIGGER = 1 << 4, // bit 4: 0001 0000
48-
};
49-
50-
short layerStringToGroup(const std::string& layer);
5142
short getMaskForLayer(short group);
5243

5344
class CollisionSystem {
@@ -77,10 +68,11 @@ namespace gameplay {
7768
void update(our::World* world);
7869

7970
// On-demand raycast function that can be used outside of the update loop to query the world for collisions.
80-
HitInfo raycast(const Ray& ray, float maxDistance, const std::string targetLayer = "") const;
71+
HitInfo raycast(const Ray& ray, float maxDistance,
72+
const short targetLayer = CollisionLayer::LAYER_ENVIRONMENT) const;
8173

8274
// On-demand overlap sphere function that can be used outside of the update loop
83-
std::vector<our::Entity*> overlapSphere(const glm::vec3& center, float radius, std::string targetLayer = "");
75+
std::vector<our::Entity*> overlapSphere(const glm::vec3& center, float radius, short targetLayer);
8476

8577
const std::vector<CollisionEvent>& getCollisions() const;
8678
};

0 commit comments

Comments
 (0)