Overview
MC-CPP uses AABB (Axis-Aligned Bounding Box) collision detection with swept tests for continuous collision detection. The system includes:Colliderclass for AABB operations and swept collisionHitRayclass for ray-casting to find targeted blocks
Collider Class
Location:src/physics/collider.h
The Collider class represents an axis-aligned bounding box and performs swept collision tests.
Structure
Constructor
Atcollider.h:12-15:
pos1– Minimum corner (x1, y1, z1)pos2– Maximum corner (x2, y2, z2)
Translation Operator
Atcollider.h:17-20, the + operator translates the collider:
Intersection Test
Atcollider.h:22-27, the & operator tests for overlap:
trueif the two AABBs overlapfalseotherwise
- Computes overlap distance on each axis
- Boxes intersect only if all three overlaps are positive
Swept Collision Detection
Atcollider.h:29-60, the collide() method performs swept AABB collision:
static_col– The stationary AABB (e.g., a block)velocity– Movement vector for this frame
pair<float, glm::vec3>:first– Time of impact (0.0 to 1.0), or 1.0 if no collisionsecond– Surface normal of collision, or (0,0,0) if no collision
-
Compute entry/exit times for each axis:
- Entry time = when moving box first touches static box on that axis
- Exit time = when moving box leaves static box on that axis
- If velocity is zero on an axis, entry/exit are ±infinity
-
Early rejection:
- All entry times < 0 → already overlapping/past
- Any entry time > 1 → won’t reach in this time step
-
Find collision time:
entry = max(x_entry, y_entry, z_entry)– when all axes are overlappingexit = min(x_exit, y_exit, z_exit)– when any axis stops overlapping- If
entry > exit, the ranges don’t overlap → no collision
-
Determine normal:
- Whichever axis has the largest entry time is the collision axis
- Normal points opposite to velocity direction on that axis
Ray Casting (HitRay)
Location:src/physics/hit.h, src/physics/hit.cpp
The HitRay class performs voxel ray-casting to find the block the player is looking at.
Structure
Constructor
Athit.cpp:5-14:
rotation.x– Yaw angle (horizontal rotation)rotation.y– Pitch angle (vertical rotation)start_pos– Starting position (usually player’s eye position)
vector– Normalized ray direction from rotation anglesblock– Initial block coordinates (rounded from position)
Check Method
Athit.cpp:16-26, tests if next block is solid:
Step Method (DDA Traversal)
Athit.cpp:28-69, implements 3D DDA (Digital Differential Analyzer):
- Convert position to local block space (0 to 1 within current block)
- Transform to absolute space where ray direction is positive (easier math)
- For each axis (X, Y, Z):
- Calculate where ray intersects the exit face on that axis
- Check if intersection point is within the face bounds
- If valid, this is the next block boundary
- Return the closest face intersection
- Callback receives:
current– Last air blocknext– Hit block (or next air block to check)
Collision System Integration
The collision system integrates into the physics update atentity.cpp:65-176:
Performance Notes
- Broad phase: Entity physics only checks blocks within
±width/2and±heightof the entity - Swept tests: Continuous collision prevents tunneling through blocks even at high speeds
- Multiple passes: 3 collision iterations resolve corner cases and multi-axis collisions
- Ray casting: DDA traversal is efficient, typically checking only a few blocks per step
Block Colliders
Blocks can have multiple colliders (defined inBlockType):