check2d

repository·main·Indexed 42 days ago

https://github.com/nenjack/check2d

A high-performance 2D collision detection library for real-time games and simulations. It utilizes Bounding Volume Hierarchy (BVH) for quick tree trimming and the Separating Axis Theorem (SAT) for accurate detection. Version 9.36.4 supports RayCasting, offsets, rotation, scaling, and group filtering for shapes including Boxes, Circles, and Polygons.

Tokens
18.3K
Snippets
76
Records
84
Agent score
54%

What's inside check2d

  1. Visualize bodies and BVH for debugging

    main

    You can debug your collision system by drawing bodies or the internal BVH structure directly onto a HTML5 <canvas> context.

    // Draw all bodies in the system
    context.beginPath()
    system.draw(context)
    context.stroke()
    
    // Draw the BVH bounding boxes
    context.beginPath()
    system.drawBVH(context)
    context.stroke()
  2. Quick start with check2d

    main

    To begin using check2d, instantiate a System. The System manages the Bounding Volume Hierarchy (BVH) and handles collision detection logic.

    const { System } = require('check2d')
    
    const system = new System()
  3. Configure collision filtering with groups

    main

    Collision filtering is handled via a group property on bodies. The group is a 32-bit integer where:

    • The upper 16 bits represent the category.
    • The lower 16 bits represent the mask (which categories this body can interact with).

    Two bodies can interact if (categoryA & maskB) !== 0 and (categoryB & maskA) !== 0.

    Helper Functions

    • groupBits(category, mask): Creates a group integer from category and mask bits.
    • bin2dec(binary): Converts a binary string (e.g., '0001') to a decimal number.
    • ensureNumber(input): Ensures the input is a number, converting binary strings if necessary.
    // Example: Setting up collision groups
    // Category 1, Mask 2
    const group1 = groupBits(0x0001, 0x0002);
    
    // Category 2, Mask 1
    const group2 = groupBits(0x0002, 0x0001);
    
    const body1 = new Circle({ x: 0, y: 0 }, 10, { group: group1 });
    const body2 = new Circle({ x: 5, y: 5 }, 10, { group: group2 });
    
    // canInteract(body1, body2) would return true
  4. Manage body state with dirty flags

    main

    Both Circle and Polygon use a dirty flag to optimize performance. When a body's position, angle, scale, or points change, it is marked as dirty.

    • markAsDirty(updateNow): If updateNow is true, the body is immediately updated in the collision system. If false, it is simply flagged to be updated during the next collision check.
    • updateBody(updateNow): Synchronizes the body with the collision system (e.g., updating AABB or convex polygon positions).
  5. Configure collision filtering with group bits

    main

    Collision filtering is handled via a 32-bit integer group. The high 16 bits represent the category and the low 16 bits represent the mask.

    • Use groupBits(category, mask) to generate a group value.
    • Use ensureNumber(input) to handle both numeric and binary string inputs.
    • Use canInteract(bodyA, bodyB) to determine if two bodies are allowed to collide based on their groups.
    import { groupBits, canInteract } from './utils';
    
    // Define categories and masks using binary strings
    const playerGroup = groupBits('00000000_00000001', '11111111_11111111');
    const wallGroup = groupBits('00000000_00000010', '00000000_00000001');
    
    // Check if they can interact
    const collisionAllowed = canInteract({ group: playerGroup }, { group: wallGroup });
  6. Import modules from check2d

    main

    The check2d library provides a comprehensive suite of tools for 2D collision detection, body manipulation, and raycasting. You can import all core functionality from the main entrypoint. The library is organized into several functional areas:

    • Bodies: Geometric primitives including Circle, Ellipse, Polygon, Box, Point, and Line.
    • System: Core engine logic and management.
    • Intersect: Low-level intersection and collision detection algorithms.
    • Utils: Helper functions for geometric and mathematical operations.
    • Clock: Time-related utilities for managing simulation steps or animations.
    import * as check2d from 'check2d';
    
    // Accessing components via the main namespace
    const circle = new check2d.Circle(...);
    const intersection = check2d.intersectSomething(...);
  7. Manipulate body properties

    main

    Bodies in check2d support transformations including position, rotation, and scale. To optimize performance, changes are batched. When you modify a body, pass false as the last argument to prevent immediate updates, then call body.updateBody() once all transformations are complete to apply them in a single batch.

    // Batching transformations for performance
    box.setPosition(10, 5, false)
    box.setAngle(Math.PI / 4, false)
    box.setScale(2, 1, false)
    box.move(1, false)
    
    // Apply all changes at once
    box.updateBody()
  8. Perform collision checks

    main

    The System provides methods to check for collisions between bodies:

    • system.checkAll(callback): Checks all bodies in the system and executes the callback for every collision result found.
    • system.checkOne(body, callback): Checks a specific body against all other bodies in the system.
    • system.separate(): An optional method to automatically handle separation of colliding bodies.

    To find the exact points where two bodies are colliding, use system.getCollisionPoints(bodyA, bodyB).

    // Check all collisions in the system
    system.checkAll((result) => {
      console.log(result)
    })
    
    // Check collisions for a specific body
    system.checkOne(box, (result) => {
      console.log(result)
    })
    
    // Automatically separate colliding bodies
    system.separate()
    
    // Get specific collision points from a result
    const points = system.getCollisionPoints(result.a, result.b)
  9. Perform raycasting

    main

    Use system.raycast to detect collisions along a line segment. The method takes a starting point, an end point, and an optional filter function. If a hit is detected, it returns an object containing the point of impact and the body hit.

    const hit = system.raycast(
      { x: 0, y: 0 },      // Start point
      { x: 0, y: -10 },    // End point
      (body) => true       // Filter function (returns true to include body)
    )
    
    if (hit) {
      const { point, body } = hit
      console.log(point, body)
    }
  10. Create collision bodies

    main

    You can create various shape types such as Box, Circle, and Polygon. While some shapes can be instantiated directly, it is recommended to use the system.createBox method (or similar factory methods) to ensure they are properly integrated with the system. After creation, use system.insert(body) to add the body to the collision detection engine.

    const { Box, Circle, Polygon } = require('check2d')
    
    // Using a factory method from the system
    const box = system.createBox({ x: 0, y: 0 }, 10, 10)
    
    // Instantiating a shape directly
    const circle = new Circle({ x: 5, y: 0 }, 5)
    
    // Adding the body to the system for collision checks
    system.insert(circle)