How to Query an AABB in Planck.js?

This article provides a practical guide on how to perform an Axis-Aligned Bounding Box (AABB) query in planck.js to find intersecting physics fixtures. We will cover the essential setup, the execution of the queryAABB method, and how to utilize the callback function to filter and collect the results efficiently.

Understanding the AABB Query in Planck.js

In 2D physics engines like planck.js (a JavaScript port of Box2D), spatial querying is crucial for performance. Instead of checking every object in your world for collisions, an AABB query allows you to define a rectangular boundary and quickly retrieve all fixtures whose bounding boxes overlap with it. This is incredibly useful for implementing features like area-of-effect damage, custom radar systems, or selecting objects in a strategy game.

Step 1: Define the AABB Boundary

To start, you need to define the area you want to search using the AABB class. You must provide the lower (bottom-left) and upper (top-right) 2D vector coordinates for your bounding box.

const planck = require('planck-js');
const Vec2 = planck.Vec2;
const AABB = planck.AABB;

// Define the search area from (0, 0) to (10, 10)
const lowerBound = Vec2(0.0, 0.0);
const upperBound = Vec2(10.0, 10.0);
const aabb = new AABB(lowerBound, upperBound);

Step 2: Implement the Callback Function

The world.queryAABB() method requires a callback function. This function is triggered automatically for every fixture found within the specified boundary.

The callback receives a fixture argument. Inside this function, you can perform additional checks (like filtering by user data or fixture types) and store the results.

Important Control Flow: Your callback function must return a boolean value. Returning true tells the engine to keep searching for more fixtures. Returning false immediately terminates the query, which is perfect if you only need to find the first intersecting object.

const intersectingFixtures = [];

function queryCallback(fixture) {
    // Example: Only collect fixtures attached to dynamic bodies
    const body = fixture.getBody();
    if (body.isDynamic()) {
        intersectingFixtures.push(fixture);
    }
    
    // Return true to continue scanning the area for other fixtures
    return true; 
}

Step 3: Execute the Query

With your world instance, AABB boundary, and callback function ready, you can now execute the query on your physics world.

// Assuming 'world' is your initialized planck.World instance
world.queryAABB(aabb, queryCallback);

// After execution, your array contains the results
console.log(`Found ${intersectingFixtures.length} intersecting dynamic fixtures.`);

Precise Shape Checking (Optional)

It is important to note that queryAABB checks for overlaps based on the bounding boxes of the fixtures, not their precise geometric shapes. If a complex polygon fixture has a large bounding box that overlaps your query area, it will trigger the callback even if the actual polygon shape does not touch the AABB.

If your game logic requires pixel-perfect accuracy, you should perform a secondary check inside your callback using planck.Distance.testOverlap(shapeA, transformA, shapeB, transformB) to verify if the actual shapes are intersecting.