Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion config/app.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,8 @@
{
"type": "Collider",
"layer": "enemy",
"radius": 0.8
"shape": "Box",
"size": [1.0, 1.0, 1.0]
}
]
}
Expand Down
7 changes: 7 additions & 0 deletions src/game/components/collider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
static gameplay::ColliderShape parseColliderShape(const std::string& value, gameplay::ColliderShape fallback) {
if (value == "Sphere") return gameplay::ColliderShape::Sphere;
if (value == "Capsule") return gameplay::ColliderShape::Capsule;
if (value == "Box") return gameplay::ColliderShape::Box;
return fallback;
}

Expand All @@ -22,8 +23,14 @@ namespace gameplay {
radius = data.value("radius", radius);
height = data.value("height", height);
isTrigger = data.value("isTrigger", isTrigger);

std::string stringLayer = data.value("layer", "");
layer = layerStringToGroup(stringLayer);

std::vector<float> extents = data.value("size", std::vector<float>{0.5f, 0.5f, 0.5f});
if (extents.size() == 3) {
halfExtents = glm::vec3(extents[0], extents[1], extents[2]);
}
Comment thread
LoayAhmed304 marked this conversation as resolved.
Outdated
}

} // namespace gameplay
4 changes: 3 additions & 1 deletion src/game/components/collider.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#pragma once

#include <ecs/component.hpp>
#include <glm/glm.hpp>

namespace gameplay {

enum class ColliderShape { Sphere, Capsule };
enum class ColliderShape { Sphere, Capsule, Box };

enum CollisionLayer : short {
LAYER_PLAYER = 1 << 0, // bit 0: 0000 0001
Expand All @@ -21,6 +22,7 @@ namespace gameplay {
float radius = 0.5f;
float height = 1.0f; // must be the total height
bool isTrigger = false;
glm::vec3 halfExtents = glm::vec3(0.5f);

static std::string getID() {
return "Collider";
Expand Down
27 changes: 27 additions & 0 deletions src/game/systems/collision-debug-drawer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,33 @@ void main() {
addCircle(center, forward, up, radius, color, 32); // ZY circle
}

void CollisionDebugDrawer::drawBoxWireframe(const glm::mat4& transform, const glm::vec3& halfExtents,
const glm::vec3& color) {
glm::vec3 center = glm::vec3(transform[3]);
glm::vec3 right = glm::normalize(glm::vec3(transform[0]));
glm::vec3 up = glm::normalize(glm::vec3(transform[1]));
glm::vec3 forward = glm::normalize(glm::vec3(transform[2]));

// 8 corners of the box
glm::vec3 corners[8];
for (int i = 0; i < 8; i++) {
float x = (i & 1) ? halfExtents.x : -halfExtents.x;
float y = (i & 2) ? halfExtents.y : -halfExtents.y;
float z = (i & 4) ? halfExtents.z : -halfExtents.z;
corners[i] = center + right * x + up * y + forward * z;
}

// 12 edges of the box (pairs of corner indices)
int edgeIndices[12][2] = {
{0, 1}, {1, 3}, {3, 2}, {2, 0}, // bottom face
{4, 5}, {5, 7}, {7, 6}, {6, 4}, // top face
{0, 4}, {1, 5}, {2, 6}, {3, 7} // vertical edges
};
for (int i = 0; i < 12; i++) {
addLine(corners[edgeIndices[i][0]], corners[edgeIndices[i][1]], color);
}
}

void CollisionDebugDrawer::drawCapsuleWireframe(const glm::mat4& transform, float radius, float totalHeight,
const glm::vec3& color) {
glm::vec3 center = glm::vec3(transform[3]);
Expand Down
1 change: 1 addition & 0 deletions src/game/systems/collision-debug-drawer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace gameplay {

// ---- Manual wireframe generators (used instead of Bullet's debugDrawObject) ----
void drawSphereWireframe(const glm::mat4& transform, float radius, const glm::vec3& color);
void drawBoxWireframe(const glm::mat4& transform, const glm::vec3& halfExtents, const glm::vec3& color);
void drawCapsuleWireframe(const glm::mat4& transform, float radius, float totalHeight, const glm::vec3& color);

// ---- btIDebugDraw overrides (required by interface) ----
Expand Down
17 changes: 13 additions & 4 deletions src/game/systems/collision-system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace gameplay {
case LAYER_PLAYER:
return LAYER_ENEMY | LAYER_ENVIRONMENT | LAYER_TRIGGER;
case LAYER_ENEMY:
return LAYER_PLAYER | LAYER_PROJECTILE | LAYER_ENVIRONMENT;
return LAYER_PLAYER | LAYER_PROJECTILE | LAYER_ENVIRONMENT | LAYER_ENEMY;
Comment thread
LoayAhmed304 marked this conversation as resolved.
case LAYER_ENVIRONMENT:
return LAYER_PLAYER | LAYER_ENEMY | LAYER_PROJECTILE;
case LAYER_PROJECTILE:
Expand Down Expand Up @@ -275,11 +275,13 @@ namespace gameplay {
// Create or reuse collision shape based on collider data
btCollisionShape* shape = nullptr;

// Shape_r_h_Scale_x_y_z
// Shape_r_h_HalfExtents_x_y_z_Scale_x_y_z
std::string shapeKey =
std::to_string(static_cast<int>(collider->shape)) + "_" + std::to_string(collider->radius) + "_" +
std::to_string(collider->height) + "_Scale_" + std::to_string(entity->localTransform.scale.x) + "_" +
std::to_string(entity->localTransform.scale.y) + "_" + std::to_string(entity->localTransform.scale.z);
std::to_string(collider->height) + "_HalfExtents_" + std::to_string(collider->halfExtents[0]) + "_" +
std::to_string(collider->halfExtents[1]) + "_" + std::to_string(collider->halfExtents[2]) + "_Scale_" +
std::to_string(entity->localTransform.scale.x) + "_" + std::to_string(entity->localTransform.scale.y) +
"_" + std::to_string(entity->localTransform.scale.z);
Comment thread
LoayAhmed304 marked this conversation as resolved.
Outdated
if (shapesCache.find(shapeKey) != shapesCache.end()) {
ownedShapes[shapesCache[shapeKey]]++;
shape = shapesCache[shapeKey];
Expand All @@ -289,6 +291,9 @@ namespace gameplay {
case ColliderShape::Sphere:
shape = new btSphereShape(collider->radius);
break;
case ColliderShape::Box:
shape = new btBoxShape(glmToBtVec3(collider->halfExtents));
break;
case ColliderShape::Capsule: {
float spine = collider->height - 2.0f * collider->radius;
if (spine < 0.0f) spine = 0.0f;
Expand Down Expand Up @@ -419,6 +424,10 @@ namespace gameplay {
case ColliderShape::Capsule:
debugDrawer->drawCapsuleWireframe(transform, scaledRadius, scaledHeight, color);
break;
case ColliderShape::Box:
debugDrawer->drawBoxWireframe(
transform, collider->halfExtents * glm::vec3(scale.getX(), scale.getY(), scale.getZ()), color);
break;
}
}

Expand Down