Skip to content

BoundingBox

Axis-aligned bounding box (AABB) for entity collision detection.

BoundingBox boundingBoxComponent = store.getComponent(ref, BoundingBox.getComponentType());
Box box = boundingBoxComponent.getBoundingBox();
Box box = boundingBoxComponent.getBoundingBox();
// dimensions
double width = box.width(); // max.x - min.x
double height = box.height(); // max.y - min.y
double depth = box.depth(); // max.z - min.z
double volume = box.getVolume();
// corners
Vector3d min = box.getMin(); // minimum corner
Vector3d max = box.getMax(); // maximum corner
// horizontally centered at origin, bottom at y=0 (typical for entities)
Box entityBox = Box.horizontallyCentered(0.6, 1.8, 0.6);
// creates: min=(-0.3, 0, -0.3), max=(0.3, 1.8, 0.3)
// explicit min/max corners
Box customBox = new Box(-0.5, 0.0, -0.5, 0.5, 2.0, 0.5);
// set on entity
store.putComponent(ref, BoundingBox.getComponentType(), new BoundingBox(entityBox));

For complex collision shapes, entities can have named sub-hitboxes:

Map<String, DetailBox[]> detailBoxes = boundingBoxComponent.getDetailBoxes();
// detail boxes are typically set from ModelComponent
boundingBoxComponent.setDetailBoxes(model.getDetailBoxes());

Detail boxes are used for precise hit detection (e.g., headshots) rather than general collision.

When an entity has a ModelComponent, its bounding box is automatically updated:

  • ModelSystems.ModelSpawned - sets initial bounding box from model
  • ModelSystems.UpdateBoundingBox - updates when model changes
  • UpdateCrouchingBoundingBox - adjusts for crouch state

Entities with BoundingBox + TransformComponent (and without Intangible) are tracked in spatial queries for collision detection.

CollisionResult result = new CollisionResult();
// find what a moving box would hit (static method)
boolean hit = CollisionModule.findCollisions(
boundingBox, // the collider shape
position, // starting position
velocity, // movement direction
result, // stores collision data
componentAccessor
);
if (hit) {
BlockCollisionData collision = result.getFirstBlockCollision();
if (collision != null) {
Vector3d hitPoint = collision.collisionPoint;
Vector3d normal = collision.collisionNormal;
}
}
// check if two entities overlap
BoundingBox boxA = store.getComponent(refA, BoundingBox.getComponentType());
BoundingBox boxB = store.getComponent(refB, BoundingBox.getComponentType());
TransformComponent transformA = store.getComponent(refA, TransformComponent.getComponentType());
TransformComponent transformB = store.getComponent(refB, TransformComponent.getComponentType());
// manual AABB intersection check
Box worldBoxA = boxA.getBoundingBox().clone().translate(transformA.getPosition());
Box worldBoxB = boxB.getBoundingBox().clone().translate(transformB.getPosition());
boolean overlaps = worldBoxA.isIntersecting(worldBoxB);

Add the Intangible component to exclude an entity from collision queries:

store.ensureComponent(ref, Intangible.getComponentType());

See Intangible for details.

ComponentRelationship
TransformComponentProvides position for world-space collision
ModelComponentSource of bounding box dimensions
IntangibleExcludes from collision spatial queries
InvulnerableSeparate from collision (affects damage only)