Examples » Engine » Gizmos

Using the Gizmos plugin.

This example shows the Gizmos plugin, which allows drawing simple primitives. These are not intended for use in the final product, only in developer tools and for debugging.

The plugin function is included from the engine/gizmos/plugin.hpp header.

    cubos.plugin(gizmosPlugin);

To draw a gizmo, all you need to do is to get a reference to the cubos::engine::Gizmos resource, and then call the draw function on it for the gizmo you want to draw. Additionally, you can also call the cubos::engine::Gizmos::color function to set the color for future gizmos. So, for example if you want to draw an arrow in a given system, all you need to do is the following:

    cubos.startupSystem("draw line at startup").after(gizmosInitTag).call([](Gizmos& gizmos) {
        gizmos.color({1, 0, 1});
        gizmos.drawArrow("arrow", {0.6F, 0.6F, 0.0F}, {-0.1F, -0.1F, 0.0F}, 0.003F, 0.009F, 0.7F, 10.0F,
                         Gizmos::Space::Screen);
    });

This code will draw an arrow poiting at the center of the screen, and it will stay there for 10 seconds.

In this other example, we draw lines, a box, and a wire box. Unlike the one in the previous example, this system is not a start-up system, so the draw functions get called every single frame. When this happens, you should set the lifetime of a gizmo to 0, which means it will be drawn for a single frame only. This way we avoid drawing gizmos on top of identical ones that were already there, or in the case of moving gizmos, leaving a trail of old version behind them.

Let's start with the lines. We are using four cameras in our scene, so let's add two lines to separate each camera. These lines will be in Screen space, as we want them to be just drawn once, indepently of the number of cameras; and we want them to use screen coordinates, as they should be drawn in the middle of the screen.

        gizmos.color({1.0F, 1.0F, 1.0F});
        gizmos.drawLine("separator line", {1.0F, 0.5F, 0.5F}, {0.0F, 0.5F, 0.5F}, 0, Gizmos::Space::Screen);
        gizmos.drawLine("separator line", {0.5F, 1.0F, 0.5F}, {0.5F, 0.0F, 0.5F}, 0, Gizmos::Space::Screen);

Let's now add a wireboxe. We want to know were exactly is the centre of each camera, so let's add a reticule. This box will be in View space, as we want it to be drawn once per camera and we want it to use view coordinates, as it should be drawn in the middle of each viewport.

        gizmos.color({1.0F, 0.5F, 1.0F});
        gizmos.drawBox("box", {0.4, 0.4, 0}, {0.55, 0.55, 0}, 0, Gizmos::Space::View);

Let's add a box. This box will be in World space, as it's the last space left to cover. It will be drawn by any camera that is looking at it, much like if it was an object in the world.

        gizmos.color({0.2F, 0.2F, 1.0F});
        gizmos.drawWireBox("wire box", {-5, -5, -5}, {-7, -7, -7}, 0, Gizmos::Space::World);

Finally let's add a cut cone. A cut cone is cylinder with faces that can have different radiuses. If you set one of the bases to have a radius of 0, you'll have a simple cone. If you set them both to have the same radius, you'll have a cylinder. Our cut cone will have different radiuses:

        if (gizmos.hovered("cut cone"))
        {
            gizmos.color({0.25F, 0.15F, 0.5F});
        }
        else if (gizmos.pressed("cut cone"))
        {
            gizmos.color({0.5F, 0.3F, 1});
        }
        else
        {
            gizmos.color({0.1F, 0.05F, 0.25F});
        }

        gizmos.drawCutCone("cut cone", {0.7F, 0.7F, 0.7F}, 5.0F, {-3, -3, -3}, 3.0F, 0, Gizmos::Space::World);

For the cut cone, we'll set the color a bit differently: We'll make it so the color of the cone changes depending on whether you are pressing the cone, or have your mouse over it. We'll make it a bit darker while the mouse is not over the cone, a bit lighter when it is, and even lighter when the cone is pressed.

The whole system looks like this:

    cubos.system("draw gizmos").call([](Gizmos& gizmos) {
        gizmos.color({1.0F, 1.0F, 1.0F});
        gizmos.drawLine("separator line", {1.0F, 0.5F, 0.5F}, {0.0F, 0.5F, 0.5F}, 0, Gizmos::Space::Screen);
        gizmos.drawLine("separator line", {0.5F, 1.0F, 0.5F}, {0.5F, 0.0F, 0.5F}, 0, Gizmos::Space::Screen);

        gizmos.color({1.0F, 0.5F, 1.0F});
        gizmos.drawBox("box", {0.4, 0.4, 0}, {0.55, 0.55, 0}, 0, Gizmos::Space::View);

        gizmos.color({0.2F, 0.2F, 1.0F});
        gizmos.drawWireBox("wire box", {-5, -5, -5}, {-7, -7, -7}, 0, Gizmos::Space::World);

        if (gizmos.hovered("cut cone"))
        {
            gizmos.color({0.25F, 0.15F, 0.5F});
        }
        else if (gizmos.pressed("cut cone"))
        {
            gizmos.color({0.5F, 0.3F, 1});
        }
        else
        {
            gizmos.color({0.1F, 0.05F, 0.25F});
        }

        gizmos.drawCutCone("cut cone", {0.7F, 0.7F, 0.7F}, 5.0F, {-3, -3, -3}, 3.0F, 0, Gizmos::Space::World);
    });