Skip to content

Debug draw (#163, second part) - #165

Merged
nicolas-maman merged 1 commit into
mainfrom
api/debug-draw
Oct 9, 2026
Merged

nicolas-maman merged 1 commit into
mainfrom
api/debug-draw

Conversation

@nicolas-maman

Copy link
Copy Markdown
Collaborator

The second and last part of #163: debug draw, as the reference's b3DebugDraw, b3World_Draw, its joints' drawings, the debug-shape callbacks and b3RecPlayer_DrawFrameQueries have it. With #164 this covers #163.

Closes #163.

aephysics.debug_draw (new)

  • DebugDraw: the callbacks (user shape, segment, transform, point, sphere, capsule, bounds, box, string), the drawing bounds, the force and joint scales, and every option of the reference's.
  • default_debug_draw: callbacks that draw nothing, bounds 100 m out every way, unit scales.
  • The reference's 145 named colours as COLOR_*, its material presets with make_debug_color, and graph_color.
  • fixed and hex for the labels: the reference's %.2f-style and %#X formats.

Drawing a world

physics_world.world_draw(id, draw, mask_bits):

  • Shapes. Every shape whose fat bounds overlap the drawing bounds and whose category the mask takes is drawn once. Its colour is picked as the reference picks it: its material's own colour if it has one, else its body's state as a hue (bad mass, disabled, sensor, time of impact, bullet, speed capped, fast, static, kinematic awake or asleep, awake, sleeping) and its energy as a material preset.
  • Bodies. For the drawn bodies, the options draw names, the centre of mass and mass, the sleep velocity against the threshold, and islands as bounds.
  • Joints. Each joint is drawn once, each kind as the reference draws it: distance limits and rest length, revolute and spherical twist wedges and cones, prismatic and wheel limits, steering arcs, weld boxes, motor and filter lines. Graph colours and the constraint force and torque are drawn as extras.
  • Contacts. Each manifold point is coloured by state (added, speculative far or near, persisting) or by graph colour, with its normal and separation, its force or its feature id, plus the friction's anchor and force.
  • Not drawn: the reference's per-worker debug points and lines. They are a developer aid inside its task contexts, with nothing here that fills them.

The host's drawables

  • The world def gains create_debug_shape, destroy_debug_shape and user_debug_shape_context. Each shape keeps its user_shape, made when it is first drawn.
  • A drawable is given back when its shape goes, as in the reference. Two departures from the reference:
    • when the shape's geometry changes: the reference keeps drawing the stale one, here the next draw makes a new one;
    • when the world goes: the reference leaves those to the host, here every one comes back.
  • An in-place restore (snapshot.restore_world) keeps the drawables of the shapes still in their slot (same generation) and gives back the rest, as the reference's does. A seek in the player doesn't remake every drawable.
  • dynamics.set_debug_shape_callbacks changes them on a live world, giving back what the old ones made first.

The player

  • recording.player_set_debug_shape_callbacks (b3RecPlayer_SetDebugShapeCallbacks): the player's world draws with the host's drawables and rewinds to frame 0.
  • recording.player_draw_frame_queries(p, draw, query, selected) (b3RecPlayer_DrawFrameQueries):
    • rays and their hits and normals;
    • cast shapes with the proxy at the start and at each hit;
    • mover casts with the capsule at its fraction;
    • collide movers with their planes;
    • overlap boxes and shapes with the hit shapes' bounds;
    • the selected query in the reserved colour, labelled with its caller.
  • To draw these, the frame store now keeps each query's mover capsule and proxy points. A collide mover's plane points are now stored in world space; before, they were relative to the query's origin.

Tests

test_debug_draw.ae, 41 checks, on a world of every kind of thing through counting callbacks:

  • every shape drawn once, with the reference's colour for a static, a sensor, a kinematic, an awake body and a material's own colour;
  • a drawable each, made once and kept;
  • every option counted against the world: a bound per shape, a name per named body, a transform per body, the weld's two boxes, a label per awake joint, a point per manifold point with normals and separations, island bounds, sleep;
  • the drawing bounds and the mask culling;
  • drawables given back through destroy, geometry change, restore (the kept ones not remade) and the world's end;
  • a player's world drawn with the host's drawables across seeks, its queries drawn, the selected one labelled bullet (42);
  • the number formats.

Pins

Aether 0.796.0 and aeb v0.325, both the latest releases.

aephysics.debug_draw has the reference's b3DebugDraw, its colours and
material presets; physics_world.world_draw draws a world as
b3World_Draw does, each joint kind as the reference draws it; the world
def's debug shape callbacks give a host its own drawable per shape, made
when first drawn and given back when the shape goes, its geometry
changes or the world goes, and kept through an in-place restore; the
player draws a replayed frame's queries.
@nicolas-maman
nicolas-maman merged commit 8a5cbd3 into main Oct 9, 2026
2 checks passed
@nicolas-maman
nicolas-maman deleted the api/debug-draw branch October 9, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Public API not ported: contact data by id, constraint tuning getter, world counts, capacity, host hooks, dumps, debug draw

1 participant