urhosharpurho3d

How to visualize PhysicsWorld / CollisionShape with debug renderer?


My test scene for Urho3D/Urhosharp contains two boxes (see screenshot). For both, the red and the green box I added a RigidBody and a CollisionShape.

enter image description here

The shape for the red box is a sphere and for the blue one a box. I've enabled debug visualisation by adding:

app.Engine.SubscribeToPostRenderUpdate(args => {
    app.Renderer.DrawDebugGeometry(false);
});

However, this does not render the collision shapes but only the wireframe of the objects (green lines).

Here's the code for the blue node:

var floorNode = app.RootNode.CreateChild("Floor");
    floorNode.Position = Vector3.Zero;
    floorNode.Scale = new Vector3(10, 1, 10);
    var floorComp = floorNode.CreateComponent<Box>();
    floorComp.SetMaterial(Material.FromColor(new Color(0, 0, 1, 0.5f)));

var rigidBody = floorNode.CreateComponent<RigidBody>();
    rigidBody.Mass = 0;
    var collNode = floorNode.CreateComponent<CollisionShape>();
    collNode.SetBox(Vector3.One, Vector3.Zero, Quaternion.Identity);

And for the red one:

var boxNode = app.RootNode.CreateChild("Box");
    boxNode.SetScale(2f);
    var boxComp = boxNode.CreateComponent<Box>();
    boxComp.Color = Color.Red;
    boxComp.SetMaterial(Material.FromColor(Color.Red));

var rigidBody = boxNode.CreateComponent<RigidBody>();
    rigidBody.Mass = 0f;
    var collNode = boxNode.CreateComponent<CollisionShape>();

    collNode.SetBox(Vector3.One, Vector3.Zero, Quaternion.Identity);
    collNode.SetSphere(3f, Vector3.Zero, Quaternion.Identity);

The collision works but I'd love to see the physics world because it makes it easier to experiment.


Solution

  • And here's the solution: the default debug output of the Urho3D renderer does not include the physics components. It has to be added manually.

    app.Engine.SubscribeToPostRenderUpdate(args => {
        // Default debug rendering.
        app.Renderer.DrawDebugGeometry(false);
    
        // Use debug renderer to output physics world debug.
        var debugRendererComp = app.Scene.GetComponent<DebugRenderer>();
        var physicsComp = app.Scene.GetComponent<PhysicsWorld>();
        if(physicsComp != null)
        {
            physicsComp.DrawDebugGeometry(debugRendererComp, false);
        }
    });
    

    For this to work the scene must of course have a debug renderer and a physics component:

    app.Scene.GetOrCreateComponent<PhysicsWorld>();
    app.Scene.GetOrCreateComponent<DebugRenderer>();
    

    Then the result is as expected. In the image below the red box has got a spherical collision shape:

    Physics debug rendering

    The nice thing I noticed: since the collision shape is a child node of the actual node it will scale together with the node. This means if the box or sphere (or whatever) is created with a size of Vector3.One it will always match the actual node size.