Skip to content

Collision Types

Basic geometric types and collision layer definitions.

Description

This document describes the collision primitives (Rect, Circle, Segment) and collision layer system used by the collision detection system.

Namespace

namespace pixelroot32::physics {
    // Types and functions
}

CollisionLayer Type

Collision layer type (bit flags).

Type: uint16_t (typedef)

Notes: - Uses bit flags for layer assignment - Actors can be on multiple layers (bitwise OR) - Masks define which layers an actor can collide with

DefaultLayers Namespace

Predefined collision layers.

kNone

No layer (0).

Value: 0

Usage:

actor->layer = pixelroot32::physics::DefaultLayers::kNone;

kAll

All layers (0xFFFF).

Value: 0xFFFF

Usage:

actor->mask = pixelroot32::physics::DefaultLayers::kAll;  // Collide with everything

Custom Layers

Define custom layers using bit flags:

namespace MyLayers {
    const pixelroot32::physics::CollisionLayer kPlayer = 1 << 0;      // Bit 0
    const pixelroot32::physics::CollisionLayer kEnemy = 1 << 1;       // Bit 1
    const pixelroot32::physics::CollisionLayer kObstacle = 1 << 2;    // Bit 2
    const pixelroot32::physics::CollisionLayer kProjectile = 1 << 3;  // Bit 3
    const pixelroot32::physics::CollisionLayer kCollectible = 1 << 4;  // Bit 4
}

// Usage
actor->layer = MyLayers::kPlayer;
actor->mask = MyLayers::kEnemy | MyLayers::kObstacle;

Circle Structure

Represents a circle for collision detection.

Members: - float x: Center X coordinate - float y: Center Y coordinate - float radius: Radius of the circle

Example:

pixelroot32::physics::Circle circle;
circle.x = 100.0f;
circle.y = 100.0f;
circle.radius = 10.0f;

Segment Structure

Represents a line segment for collision detection.

Members: - float x1, y1: Start point coordinates - float x2, y2: End point coordinates

Example:

pixelroot32::physics::Segment segment;
segment.x1 = 0.0f;
segment.y1 = 0.0f;
segment.x2 = 100.0f;
segment.y2 = 100.0f;

Intersection Functions

bool intersects(const Circle& a, const Circle& b)

Checks if two circles intersect.

Parameters: - a (const Circle&): First circle - b (const Circle&): Second circle

Returns: - bool: true if circles intersect

Example:

pixelroot32::physics::Circle circle1{100.0f, 100.0f, 10.0f};
pixelroot32::physics::Circle circle2{110.0f, 100.0f, 10.0f};

if (pixelroot32::physics::intersects(circle1, circle2)) {
    // Circles overlap
}

bool intersects(const Circle& c, const Rect& r)

Checks if a circle and rectangle intersect.

Parameters: - c (const Circle&): Circle - r (const Rect&): Rectangle

Returns: - bool: true if circle and rectangle intersect

Example:

pixelroot32::physics::Circle circle{100.0f, 100.0f, 10.0f};
pixelroot32::core::Rect rect{95.0f, 95.0f, 20, 20};

if (pixelroot32::physics::intersects(circle, rect)) {
    // Circle overlaps rectangle
}

bool intersects(const Segment& s, const Rect& r)

Checks if a line segment and rectangle intersect.

Parameters: - s (const Segment&): Line segment - r (const Rect&): Rectangle

Returns: - bool: true if segment and rectangle intersect

Example:

pixelroot32::physics::Segment segment{0.0f, 0.0f, 100.0f, 100.0f};
pixelroot32::core::Rect rect{50.0f, 50.0f, 20, 20};

if (pixelroot32::physics::intersects(segment, rect)) {
    // Segment intersects rectangle
}

bool sweepCircleVsRect(const Circle& start, const Circle& end, const Rect& target, float& tHit)

Performs a sweep test: checks if a moving circle collides with a rectangle.

Parameters: - start (const Circle&): Circle at start position - end (const Circle&): Circle at end position - target (const Rect&): Target rectangle - tHit (float&): Output parameter for collision time (0.0 to 1.0)

Returns: - bool: true if collision occurs during sweep

Notes: - Useful for fast-moving projectiles - tHit indicates when collision occurs (0.0 = start, 1.0 = end) - More expensive than simple AABB check

Example:

// Projectile moving from (0, 0) to (100, 100)
pixelroot32::physics::Circle start{0.0f, 0.0f, 5.0f};
pixelroot32::physics::Circle end{100.0f, 100.0f, 5.0f};
pixelroot32::core::Rect wall{50.0f, 50.0f, 20, 20};

float tHit = 0.0f;
if (pixelroot32::physics::sweepCircleVsRect(start, end, wall, tHit)) {
    // Collision at time tHit
    float hitX = 0.0f + (100.0f - 0.0f) * tHit;
    float hitY = 0.0f + (100.0f - 0.0f) * tHit;
}

Rect Structure (from core/Entity.h)

Represents a 2D rectangle for collision detection.

Members: - float x, y: Top-left corner coordinates - int width, height: Dimensions

Methods: - bool intersects(const Rect& other) const: Checks if rectangles overlap

Example:

pixelroot32::core::Rect rect1{10.0f, 20.0f, 50, 50};
pixelroot32::core::Rect rect2{30.0f, 40.0f, 50, 50};

if (rect1.intersects(rect2)) {
    // Rectangles overlap
}

Usage Examples

Layer-Based Collision

// Define layers
namespace GameLayers {
    const pixelroot32::physics::CollisionLayer kPlayer = 1 << 0;
    const pixelroot32::physics::CollisionLayer kEnemy = 1 << 1;
    const pixelroot32::physics::CollisionLayer kObstacle = 1 << 2;
    const pixelroot32::physics::CollisionLayer kProjectile = 1 << 3;
}

// Player collides with enemies and obstacles
player->layer = GameLayers::kPlayer;
player->mask = GameLayers::kEnemy | GameLayers::kObstacle;

// Enemy collides with player and obstacles
enemy->layer = GameLayers::kEnemy;
enemy->mask = GameLayers::kPlayer | GameLayers::kObstacle;

// Projectile collides with enemies only
projectile->layer = GameLayers::kProjectile;
projectile->mask = GameLayers::kEnemy;

Circle vs Circle Collision

bool checkCollision(const Circle& a, const Circle& b) {
    return pixelroot32::physics::intersects(a, b);
}

Sweep Test for Fast Projectiles

class ProjectileActor : public pixelroot32::core::Actor {
private:
    float startX, startY;
    float endX, endY;
    float radius = 2.0f;

public:
    bool checkWallCollision(const Rect& wall) {
        pixelroot32::physics::Circle start{startX, startY, radius};
        pixelroot32::physics::Circle end{endX, endY, radius};

        float tHit = 0.0f;
        if (pixelroot32::physics::sweepCircleVsRect(start, end, wall, tHit)) {
            // Collision detected at time tHit
            return true;
        }
        return false;
    }
};

Performance Considerations

  • AABB checks: Very fast (simple rectangle intersection)
  • Circle checks: Slightly slower (distance calculation)
  • Sweep tests: More expensive (use only for fast-moving objects)
  • Layer filtering: Essential for performance with many actors

ESP32 Considerations

  • Float math: Uses floating point; acceptable but integer math would be faster
  • Sweep tests: Use sparingly (more CPU intensive)
  • Layer efficiency: Use layers effectively to minimize checks

See Also