Circle3D         Drawing Circles in 3D

To draw circles in 3D, the ManualObject class (starting from Ogre 1.2 and up) can be easily used for that purpose, here is how:

// Assuming scene_mgr is your SceneManager.
    ManualObject * circle = scene_mgr->createManualObject("circle_name");
    
    float const radius = 7;
    
    // accuracy is the count of points (and lines).
    // Higher values make the circle smoother, but may slowdown the performance.
    // The performance also is related to the count of circles.
    float const accuracy = 35;
    
    circle->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP);
    
    unsigned point_index = 0;
    for(float theta = 0; theta <= 2 * Math::PI; theta += Math::PI / accuracy) {
        circle->position(radius * cos(theta), 0, radius * sin(theta));
        circle->index(point_index++);
    }
    circle->index(0); // Rejoins the last point to the first.
    
    circle->end();
    
    scene_mgr->getRootSceneNode()->createChildSceneNode()->attachObject(circle);


This give a white simple circle in the XZ-Plane. If you want it in another plane, say the XY-Plane, just replace this line:

circle->position(radius * cos(theta), 0, radius * sin(theta));


by this line:

circle->position(radius * cos(theta), radius * sin(theta), 0);


It's as simple as that.

Circle line with certain thickness

Now if you want your circle to have a certain thickness, you'll have to use triangles. The code below does just that.

ManualObject * circle = scene_mgr->createManualObject("circle_name");

    float const radius = 7,
                thickness = 2, // Of course this must be less than the radius value.
                accuracy = 35;

    circle->begin("BaseWhiteNoLighting", RenderOperation::OT_TRIANGLE_LIST);

    unsigned point_index = 0;
    for(float theta = 0; theta <= 2 * Math::PI; theta += Math::PI / accuracy) {
        circle->position(radius * cos(theta),
                         0,
                         radius * sin(theta));
        circle->position(radius * cos(theta - Math::PI / accuracy),
                         0,
                         radius * sin(theta - Math::PI / accuracy));
        circle->position((radius - thickness) * cos(theta - Math::PI / accuracy),
                         0,
                         (radius - thickness) * sin(theta - Math::PI / accuracy));
        circle->position((radius - thickness) * cos(theta),
                         0,
                         (radius - thickness) * sin(theta));
        // Join the 4 vertices created above to form a quad.
        circle->quad(point_index, point_index + 1, point_index + 2, point_index + 3);
        point_index += 4;
    }

    circle->end();

    scene_mgr->getRootSceneNode()->createChildSceneNode()->attachObject(circle);

Remark

If there are problems, you can try the old version.

This was not optimal, because in the old code the count of points (what is a value for accuracy / smoothness) was dependend to the radius. Now the current code should be fine and the count of points is independend of radius. The radius doesn't matter at quality.

With the code of Circle line with certain thickness I'm not sure, if it is ok. I didn't test it, because I'm a Mogre user. If both snippits works, please remove this remark. --Beauty

References

This code was based on these 3 articles:

  • ManualObject which shows how to draw a square as an example of using the ManualObject class
  • Line 3D which shows how to use the ManualObject class to draw a line, but also, shows how to render lines in version of Ogre previous to 1.2
  • ManualObject Ogre Reference

See also