Gallery

Nine scenes, each one a world built through the public API and drawn by a renderer that knows nothing about Box3D beyond IDebugDrawer and IDebugShapeFactory.

dotnet run --project src/Box3D.NET.Visualizer -- --list      # what there is
dotnet run --project src/Box3D.NET.Visualizer -- stack       # render one
dotnet run --project src/Box3D.NET.Visualizer                # render all of them

Everything on this page is generated by that command. Nothing is hand-drawn, retouched or posed.

stack

A pyramid of crates struck by a heavy ball

Fifteen boxes and a ball with a lot of momentum. The simplest thing a physics engine does, and the one worth checking first.

pour

Spheres, capsules and boxes poured into a pen

Fifty-four bodies of three different shapes, dropped one every few steps into a pen made of four static walls. Spheres roll, capsules settle on their sides, boxes stack.

contacts

Contact points, normals and broad-phase bounds

The same simulation with the engine's own diagnostics turned on: DrawContacts, DrawContactNormals and DrawBounds. Every dot is a point the solver is working with, and every yellow box is a broad-phase bound.

Two draw calls rather than one, because options apply to the whole call: the first draws every shape, the second draws only the annotations, restricted with CategoryMask to the dynamic bodies. The floor's bounding box is eighty metres across and would otherwise be the only thing in the picture.

The numbers come out of the engine through DrawString — the large one over each body is its mass, the small one at each contact is that point's separation in centimetres. The arrangement is chosen around those labels: a box resting squarely on another box costs four numbers where a capsule lying on the same box costs two, which is why the thing on top of the crate is a capsule.

chain

A chain of revolute joints swinging

Nine capsules and a weight, hinged end to end and set swinging about the anchor. The small markers along it are the joint frames, drawn with DrawJoints.

The chain starts hanging straight and is given angular velocity rather than being built at an angle. A chain assembled already displaced has every joint violated on the first step and snaps.

vehicle

A cart on wheel joints driving over bumps

A chassis, two wheel joints with suspension and a motor on the rear one. The bumps are static boxes; the take-off ramp at the end is a triangle mesh, which is borrowed rather than copied — so it is released after the world, not before.

raycast

A sweeping fan of ray casts

Twenty-eight rays a frame, sweeping a full turn. Each one is RaycastClosest; the dot is where it hit and the short red line is the surface normal there.

Rays are the one thing on this page the engine cannot draw for you. A cast leaves no trace in the world, so the scene draws what it asked for and what came back.

character

A kinematic character climbing a ramp

The character controller from the samples, unchanged: gather the planes the capsule is touching, solve them, clip the velocity. It turns orange on the ground and yellow in the air.

The red marker under its feet is a plane the mover is solving against, drawn through the capsule on purpose — an annotation hidden by the body it describes shows nothing at all. Note that a contact point comes back relative to the query origin, not in world space.

compound

A colonnade baked into one shape, with balls bouncing off it

Thirty-seven children — a mesh plinth, twelve hull columns, twelve capsule lintels and twelve sphere capitals — baked into a single CompoundGeometry and attached with one call to AddCompound. The gold box is the broad-phase bound, and there is exactly one of it.

The trade shows in the picture too: one shape means one filter, one set of events and one colour, and the children cannot be told apart from outside.

terrain

Balls rolling into a height field bowl

A 41 by 41 height field with twelve balls dropped around the rim. The terrain mesh is read back out of the engine's own compressed grid rather than from the array it was built from, so the picture shows what the simulation is actually colliding against — the quantization steps included, which are the faint terraces across the slope.

How the pictures are made

src/Box3D.NET.Visualizer is a console application with no dependencies beyond the base class library: a software rasterizer, a PNG writer and a GIF writer, consuming Box3D.NET exactly as an application would.

That arrangement is the point. The library is deliberately renderer-agnostic, so the way to prove the drawing interface is usable is to write a renderer against it and no other privileged access. One exception exists and is visible here: hulls, meshes and height fields all have a b3Shape_Get… accessor, but a baked compound has none, so the scene that baked one hands it to the shape factory itself.

Debug draw covers the interface it is written against.