Debug Drawing Utility Class

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.

Debug Drawing Utility Class

Postby fishcakedev » Sun May 29, 2011 10:26 am

After days and hours of struggle, I finally managed to implement my own debug drawing class! :D And it's quite optimized (I think). Credit goes to the author of this post, because my implementation is based on his.

Edited: I updated the code below, adding DebugDrawer::drawCuboid() function, and some small modifications here and there.

DebugDrawer.h:
Code: Select all
#ifndef DEBUGDRAWER_H_INCLUDED
#define DEBUGDRAWER_H_INCLUDED
 
#include <OgreSingleton.h>
#include <map>
 
typedef std::pair<Ogre::Vector3, Ogre::ColourValue> VertexPair;

#define DEFAULT_ICOSPHERE_RECURSION_LEVEL   1

class IcoSphere
{
public:
   struct TriangleIndices
   {
      int v1, v2, v3;
 
      TriangleIndices(int _v1, int _v2, int _v3) : v1(_v1), v2(_v2), v3(_v3) {}
 
      bool operator < (const TriangleIndices &o) const { return v1 < o.v1 && v2 < o.v2 && v3 < o.v3; }
   };
 
   struct LineIndices
   {
      int v1, v2;
 
      LineIndices(int _v1, int _v2) : v1(_v1), v2(_v2) {}
 
      bool operator == (const LineIndices &o) const
      {
         return (v1 == o.v1 && v2 == o.v2) || (v1 == o.v2 && v2 == o.v1);
      }
   };
 
   IcoSphere();
   ~IcoSphere();
 
   void create(int recursionLevel);
   void addToLineIndices(int baseIndex, std::list<int> *target);
   int addToVertices(std::list<VertexPair> *target, const Ogre::Vector3 &position, const Ogre::ColourValue &colour, float scale);
   void addToTriangleIndices(int baseIndex, std::list<int> *target);
 
private:
   int addVertex(const Ogre::Vector3 &vertex);
   void addLineIndices(int index0, int index1);
   void addTriangleLines(int index0, int index1, int index2);
   int getMiddlePoint(int index0, int index1);
   void addFace(int index0, int index1, int index2);
 
   void removeLineIndices(int index0, int index1);
 
   std::vector<Ogre::Vector3> vertices;
   std::list<LineIndices> lineIndices;
   std::list<int> triangleIndices;
   std::list<TriangleIndices> faces;
   std::map<__int64, int> middlePointIndexCache;
   int index;
};
 
class DebugDrawer : public Ogre::Singleton<DebugDrawer>
{
public:
   DebugDrawer(Ogre::SceneManager *_sceneManager, float _fillAlpha);
   ~DebugDrawer();

   static DebugDrawer& getSingleton(void);
   static DebugDrawer* getSingletonPtr(void);
 
   void build();
 
   void setIcoSphereRecursionLevel(int recursionLevel);
 
   void drawLine(const Ogre::Vector3 &start, const Ogre::Vector3 &end, const Ogre::ColourValue &colour);
   void drawCircle(const Ogre::Vector3 &centre, float radius, int segmentsCount, const Ogre::ColourValue& colour, bool isFilled = false);
   void drawCylinder(const Ogre::Vector3 &centre, float radius, int segmentsCount, float height, const Ogre::ColourValue& colour, bool isFilled = false);
   void drawQuad(const Ogre::Vector3 *vertices, const Ogre::ColourValue& colour, bool isFilled = false);
   void drawCuboid(const Ogre::Vector3 *vertices, const Ogre::ColourValue& colour, bool isFilled = false);
   void drawSphere(const Ogre::Vector3 &centre, float radius, const Ogre::ColourValue& colour, bool isFilled = false);
   void drawTetrahedron(const Ogre::Vector3 &centre, float scale, const Ogre::ColourValue& colour, bool isFilled = false);

   void clear();
 
private:
 
   Ogre::SceneManager *sceneManager;
   Ogre::ManualObject *manualObject;
   float fillAlpha;
   IcoSphere icoSphere;
 
   std::list<VertexPair> lineVertices, triangleVertices;
   std::list<int> lineIndices, triangleIndices;
 
   int linesIndex, trianglesIndex;

   void initialise();
   void shutdown();
 
   void buildLine(const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::ColourValue& colour, float alpha = 1.0f);
   void buildQuad(const Ogre::Vector3 *vertices, const Ogre::ColourValue& colour, float alpha = 1.0f);
   void buildFilledQuad(const Ogre::Vector3 *vertices, const Ogre::ColourValue& colour, float alpha = 1.0f);
   void buildFilledTriangle(const Ogre::Vector3 *vertices, const Ogre::ColourValue& colour, float alpha = 1.0f);
   void buildCuboid(const Ogre::Vector3 *vertices, const Ogre::ColourValue& colour, float alpha = 1.0f);
   void buildFilledCuboid(const Ogre::Vector3 *vertices, const Ogre::ColourValue& colour, float alpha = 1.0f);
 
   void buildCircle(const Ogre::Vector3 &centre, float radius, int segmentsCount, const Ogre::ColourValue& colour, float alpha = 1.0f);
   void buildFilledCircle(const Ogre::Vector3 &centre, float radius, int segmentsCount, const Ogre::ColourValue& colour, float alpha = 1.0f);
 
   void buildCylinder(const Ogre::Vector3 &centre, float radius, int segmentsCount, float height, const Ogre::ColourValue& colour, float alpha = 1.0f);
   void buildFilledCylinder(const Ogre::Vector3 &centre, float radius, int segmentsCount, float height, const Ogre::ColourValue& colour, float alpha = 1.0f);

   void buildTetrahedron(const Ogre::Vector3 &centre, float scale, const Ogre::ColourValue &colour, float alpha = 1.0f);
   void buildFilledTetrahedron(const Ogre::Vector3 &centre, float scale, const Ogre::ColourValue &colour, float alpha = 1.0f);

   int addLineVertex(const Ogre::Vector3 &vertex, const Ogre::ColourValue &colour);
   void addLineIndices(int index1, int index2);
 
   int addTriangleVertex(const Ogre::Vector3 &vertex, const Ogre::ColourValue &colour);
   void addTriangleIndices(int index1, int index2, int index3);
 
   void addQuadIndices(int index1, int index2, int index3, int index4);
};
 
#endif


DebugDrawer.cpp:
Code: Select all
#include "DebugDrawer.h"
 
#include <OgreSceneManager.h>
#include <OgreRenderQueue.h>
#include <OgreManualObject.h>
#include <OgreAxisAlignedBox.h>
 
IcoSphere::IcoSphere()
   : index(0)
{
}
 
IcoSphere::~IcoSphere()
{
}
 
void IcoSphere::create(int recursionLevel)
{
   vertices.clear();
   lineIndices.clear();
   triangleIndices.clear();
   faces.clear();
   middlePointIndexCache.clear();
   index = 0;
 
   float t = (1.0f + Ogre::Math::Sqrt(5.0f)) / 2.0f;
 
   addVertex(Ogre::Vector3(-1.0f,  t,  0.0f));
   addVertex(Ogre::Vector3( 1.0f,  t,  0.0f));
   addVertex(Ogre::Vector3(-1.0f, -t,  0.0f));
   addVertex(Ogre::Vector3( 1.0f, -t,  0.0f));
 
   addVertex(Ogre::Vector3( 0.0f, -1.0f,  t));
   addVertex(Ogre::Vector3( 0.0f,  1.0f,  t));
   addVertex(Ogre::Vector3( 0.0f, -1.0f, -t));
   addVertex(Ogre::Vector3( 0.0f,  1.0f, -t));
 
   addVertex(Ogre::Vector3( t,  0.0f, -1.0f));
   addVertex(Ogre::Vector3( t,  0.0f,  1.0f));
   addVertex(Ogre::Vector3(-t,  0.0f, -1.0f));
   addVertex(Ogre::Vector3(-t,  0.0f,  1.0f));
 
   addFace(0, 11, 5);
   addFace(0, 5, 1);
   addFace(0, 1, 7);
   addFace(0, 7, 10);
   addFace(0, 10, 11);
 
   addFace(1, 5, 9);
   addFace(5, 11, 4);
   addFace(11, 10, 2);
   addFace(10, 7, 6);
   addFace(7, 1, 8);
 
   addFace(3, 9, 4);
   addFace(3, 4, 2);
   addFace(3, 2, 6);
   addFace(3, 6, 8);
   addFace(3, 8, 9);
 
   addFace(4, 9, 5);
   addFace(2, 4, 11);
   addFace(6, 2, 10);
   addFace(8, 6, 7);
   addFace(9, 8, 1);
 
   addLineIndices(1, 0);
   addLineIndices(1, 5);
   addLineIndices(1, 7);
   addLineIndices(1, 8);
   addLineIndices(1, 9);
 
   addLineIndices(2, 3);
   addLineIndices(2, 4);
   addLineIndices(2, 6);
   addLineIndices(2, 10);
   addLineIndices(2, 11);
 
   addLineIndices(0, 5);
   addLineIndices(5, 9);
   addLineIndices(9, 8);
   addLineIndices(8, 7);
   addLineIndices(7, 0);
 
   addLineIndices(10, 11);
   addLineIndices(11, 4);
   addLineIndices(4, 3);
   addLineIndices(3, 6);
   addLineIndices(6, 10);
 
   addLineIndices(0, 11);
   addLineIndices(11, 5);
   addLineIndices(5, 4);
   addLineIndices(4, 9);
   addLineIndices(9, 3);
   addLineIndices(3, 8);
   addLineIndices(8, 6);
   addLineIndices(6, 7);
   addLineIndices(7, 10);
   addLineIndices(10, 0);
 
   for (int i = 0; i < recursionLevel; i++)
   {
      std::list<TriangleIndices> faces2;
 
      for (std::list<TriangleIndices>::iterator j = faces.begin(); j != faces.end(); j++)
      {
         TriangleIndices f = *j;
         int a = getMiddlePoint(f.v1, f.v2);
         int b = getMiddlePoint(f.v2, f.v3);
         int c = getMiddlePoint(f.v3, f.v1);
 
         removeLineIndices(f.v1, f.v2);
         removeLineIndices(f.v2, f.v3);
         removeLineIndices(f.v3, f.v1);
 
         faces2.push_back(TriangleIndices(f.v1, a, c));
         faces2.push_back(TriangleIndices(f.v2, b, a));
         faces2.push_back(TriangleIndices(f.v3, c, b));
         faces2.push_back(TriangleIndices(a, b, c));
 
         addTriangleLines(f.v1, a, c);
         addTriangleLines(f.v2, b, a);
         addTriangleLines(f.v3, c, b);
      }
 
      faces = faces2;
   }
}
 
void IcoSphere::addLineIndices(int index0, int index1)
{
   lineIndices.push_back(LineIndices(index0, index1));
}
 
void IcoSphere::removeLineIndices(int index0, int index1)
{
   std::list<LineIndices>::iterator result = std::find(lineIndices.begin(), lineIndices.end(), LineIndices(index0, index1));
 
   if (result != lineIndices.end())
      lineIndices.erase(result);
}
 
void IcoSphere::addTriangleLines(int index0, int index1, int index2)
{
   addLineIndices(index0, index1);
   addLineIndices(index1, index2);
   addLineIndices(index2, index0);
}
 
int IcoSphere::addVertex(const Ogre::Vector3 &vertex)
{
   Ogre::Real length = vertex.length();
   vertices.push_back(Ogre::Vector3(vertex.x / length, vertex.y / length, vertex.z / length));
   return index++;
}
 
int IcoSphere::getMiddlePoint(int index0, int index1)
{
   bool isFirstSmaller = index0 < index1;
   __int64 smallerIndex = isFirstSmaller ? index0 : index1;
   __int64 largerIndex = isFirstSmaller ? index1 : index0;
   __int64 key = (smallerIndex << 32) | largerIndex;
 
   if (middlePointIndexCache.find(key) != middlePointIndexCache.end())
      return middlePointIndexCache[key];
 
   Ogre::Vector3 point1 = vertices[index0];
   Ogre::Vector3 point2 = vertices[index1];
   Ogre::Vector3 middle = point1.midPoint(point2);
 
   int index = addVertex(middle);
   middlePointIndexCache[key] = index;
   return index;
}
 
void IcoSphere::addFace(int index0, int index1, int index2)
{
   faces.push_back(TriangleIndices(index0, index1, index2));
}
 
void IcoSphere::addToLineIndices(int baseIndex, std::list<int> *target)
{
   for (std::list<LineIndices>::iterator i = lineIndices.begin(); i != lineIndices.end(); i++)
   {
      target->push_back(baseIndex + (*i).v1);
      target->push_back(baseIndex + (*i).v2);
   }
}
 
void IcoSphere::addToTriangleIndices(int baseIndex, std::list<int> *target)
{
   for (std::list<TriangleIndices>::iterator i = faces.begin(); i != faces.end(); i++)
   {
      target->push_back(baseIndex + (*i).v1);
      target->push_back(baseIndex + (*i).v2);
      target->push_back(baseIndex + (*i).v3);
   }
}
 
int IcoSphere::addToVertices(std::list<VertexPair> *target, const Ogre::Vector3 &position, const Ogre::ColourValue &colour, float scale)
{
   Ogre::Matrix4 transform = Ogre::Matrix4::IDENTITY;
   transform.setTrans(position);
   transform.setScale(Ogre::Vector3(scale, scale, scale));
 
   for (int i = 0; i < (int)vertices.size(); i++)
      target->push_back(VertexPair(transform * vertices[i], colour));

   return vertices.size();
}
 
// ===============================================================================================

template<> DebugDrawer* Ogre::Singleton<DebugDrawer>::ms_Singleton = 0;
DebugDrawer* DebugDrawer::getSingletonPtr(void)
{
    return ms_Singleton;
}
 
DebugDrawer& DebugDrawer::getSingleton(void)

    assert( ms_Singleton );  return ( *ms_Singleton ); 
}


DebugDrawer::DebugDrawer(Ogre::SceneManager *_sceneManager, float _fillAlpha)
   : sceneManager(_sceneManager), fillAlpha(_fillAlpha), manualObject(0), linesIndex(0), trianglesIndex(0)
{
   initialise();
}
 
DebugDrawer::~DebugDrawer()
{
   shutdown();
}
 
void DebugDrawer::initialise()
{
        manualObject = sceneManager->createManualObject("debug_object");
        sceneManager->getRootSceneNode()->createChildSceneNode("debug_object")->attachObject(manualObject);
        manualObject->setDynamic(true);
 
      icoSphere.create(DEFAULT_ICOSPHERE_RECURSION_LEVEL);
 
        manualObject->begin("debug_draw", Ogre::RenderOperation::OT_LINE_LIST);
        manualObject->position(Ogre::Vector3::ZERO);
        manualObject->colour(Ogre::ColourValue::ZERO);
        manualObject->index(0);
        manualObject->end();
        manualObject->begin("debug_draw", Ogre::RenderOperation::OT_TRIANGLE_LIST);
        manualObject->position(Ogre::Vector3::ZERO);
        manualObject->colour(Ogre::ColourValue::ZERO);
        manualObject->index(0);
        manualObject->end();
 
      linesIndex = trianglesIndex = 0;
}
 
void DebugDrawer::setIcoSphereRecursionLevel(int recursionLevel)
{
   icoSphere.create(recursionLevel);
}
 
void DebugDrawer::shutdown()
{
    sceneManager->destroySceneNode("debug_object");
    sceneManager->destroyManualObject(manualObject);
}
 
void DebugDrawer::buildLine(const Ogre::Vector3& start,
                     const Ogre::Vector3& end,
                     const Ogre::ColourValue& colour,
                     float alpha)
{
        int i = addLineVertex(start, Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
        addLineVertex(end, Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
 
        addLineIndices(i, i + 1);
}
 
void DebugDrawer::buildQuad(const Ogre::Vector3 *vertices,
                          const Ogre::ColourValue& colour,
                          float alpha)
{
        int index = addLineVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
        addLineVertex(vertices[1], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
        addLineVertex(vertices[2], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
        addLineVertex(vertices[3], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
 
        for (int i = 0; i < 4; ++i) addLineIndices(index + i, index + ((i + 1) % 4));
}
 
void DebugDrawer::buildCircle(const Ogre::Vector3 &centre,
                       float radius,
                             int segmentsCount,
                       const Ogre::ColourValue& colour,
                       float alpha)
{
   int index = linesIndex;
   float increment = 2 * Ogre::Math::PI / segmentsCount;
   float angle = 0.0f;
 
   for (int i = 0; i < segmentsCount; i++)
   {
      addLineVertex(Ogre::Vector3(centre.x + radius * Ogre::Math::Cos(angle), centre.y, centre.z + radius * Ogre::Math::Sin(angle)),
         Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
      angle += increment;
   }
 
   for (int i = 0; i < segmentsCount; i++)
      addLineIndices(index + i, i + 1 < segmentsCount ? index + i + 1 : index);
}
 
void DebugDrawer::buildFilledCircle(const Ogre::Vector3 &centre,
                       float radius,
                             int segmentsCount,
                       const Ogre::ColourValue& colour,
                       float alpha)
{
   int index = trianglesIndex;
   float increment = 2 * Ogre::Math::PI / segmentsCount;
   float angle = 0.0f;
 
   for (int i = 0; i < segmentsCount; i++)
   {
      addTriangleVertex(Ogre::Vector3(centre.x + radius * Ogre::Math::Cos(angle), centre.y, centre.z + radius * Ogre::Math::Sin(angle)),
         Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
      angle += increment;
   }
 
   addTriangleVertex(centre, Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
 
   for (int i = 0; i < segmentsCount; i++)
      addTriangleIndices(i + 1 < segmentsCount ? index + i + 1 : index, index + i, index + segmentsCount);
}

void DebugDrawer::buildCylinder(const Ogre::Vector3 &centre,
                       float radius,
                             int segmentsCount,
                       float height,
                       const Ogre::ColourValue& colour,
                       float alpha)
{
   int index = linesIndex;
   float increment = 2 * Ogre::Math::PI / segmentsCount;
   float angle = 0.0f;
 
   // Top circle
   for (int i = 0; i < segmentsCount; i++)
   {
      addLineVertex(Ogre::Vector3(centre.x + radius * Ogre::Math::Cos(angle), centre.y + height / 2, centre.z + radius * Ogre::Math::Sin(angle)),
         Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
      angle += increment;
   }

   angle = 0.0f;

   // Bottom circle
   for (int i = 0; i < segmentsCount; i++)
   {
      addLineVertex(Ogre::Vector3(centre.x + radius * Ogre::Math::Cos(angle), centre.y - height / 2, centre.z + radius * Ogre::Math::Sin(angle)),
         Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
      angle += increment;
   }
 
   for (int i = 0; i < segmentsCount; i++)
   {
      addLineIndices(index + i, i + 1 < segmentsCount ? index + i + 1 : index);
      addLineIndices(segmentsCount + index + i, i + 1 < segmentsCount ? segmentsCount + index + i + 1 : segmentsCount + index);
      addLineIndices(index + i, segmentsCount + index + i);
   }
}
 
void DebugDrawer::buildFilledCylinder(const Ogre::Vector3 &centre,
                       float radius,
                             int segmentsCount,
                       float height,
                       const Ogre::ColourValue& colour,
                       float alpha)
{
   int index = trianglesIndex;
   float increment = 2 * Ogre::Math::PI / segmentsCount;
   float angle = 0.0f;
 
   // Top circle
   for (int i = 0; i < segmentsCount; i++)
   {
      addTriangleVertex(Ogre::Vector3(centre.x + radius * Ogre::Math::Cos(angle), centre.y + height / 2, centre.z + radius * Ogre::Math::Sin(angle)),
         Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
      angle += increment;
   }

   addTriangleVertex(Ogre::Vector3(centre.x, centre.y + height / 2, centre.z), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));

   angle = 0.0f;

   // Bottom circle
   for (int i = 0; i < segmentsCount; i++)
   {
      addTriangleVertex(Ogre::Vector3(centre.x + radius * Ogre::Math::Cos(angle), centre.y - height / 2, centre.z + radius * Ogre::Math::Sin(angle)),
         Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
      angle += increment;
   }
 
   addTriangleVertex(Ogre::Vector3(centre.x, centre.y - height / 2, centre.z), Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
 
   for (int i = 0; i < segmentsCount; i++)
   {
      addTriangleIndices(i + 1 < segmentsCount ? index + i + 1 : index,
                        index + i,
                     index + segmentsCount);

      addTriangleIndices(i + 1 < segmentsCount ? (segmentsCount + 1) + index + i + 1 : (segmentsCount + 1) + index,
                     (segmentsCount + 1) + index + segmentsCount,
                     (segmentsCount + 1) + index + i);
      
      addQuadIndices(
         index + i,
         i + 1 < segmentsCount ? index + i + 1 : index,
         i + 1 < segmentsCount ? (segmentsCount + 1) + index + i + 1 : (segmentsCount + 1) + index,
         (segmentsCount + 1) + index + i);
   }
}

void DebugDrawer::buildCuboid(const Ogre::Vector3 *vertices,
                                                          const Ogre::ColourValue& colour,
                                                          float alpha)
{
    int index = addLineVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
    for (int i = 1; i < 8; ++i) addLineVertex(vertices[i], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
 
    for (int i = 0; i < 4; ++i) addLineIndices(index + i, index + ((i + 1) % 4));
    for (int i = 4; i < 8; ++i) addLineIndices(index + i, i == 7 ? index + 4 : index + i + 1);
    addLineIndices(index + 1, index + 5);
    addLineIndices(index + 2, index + 4);
    addLineIndices(index,     index + 6);
    addLineIndices(index + 3, index + 7);
}
 
void DebugDrawer::buildFilledCuboid(const Ogre::Vector3 *vertices,
                                                          const Ogre::ColourValue& colour,
                                                          float alpha)
{
    int index = addTriangleVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
    for (int i = 1; i < 8; ++i) addTriangleVertex(vertices[i], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
 
    addQuadIndices(index,     index + 1, index + 2, index + 3);
    addQuadIndices(index + 4, index + 5, index + 6, index + 7);
 
    addQuadIndices(index + 1, index + 5, index + 4, index + 2);
    addQuadIndices(index,     index + 3, index + 7, index + 6);
 
    addQuadIndices(index + 1, index    , index + 6, index + 5);
    addQuadIndices(index + 4, index + 7, index + 3, index + 2);
}
 
void DebugDrawer::buildFilledQuad(const Ogre::Vector3 *vertices,
                                  const Ogre::ColourValue& colour,
                                  float alpha)
{
    int index = addTriangleVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
    addTriangleVertex(vertices[1], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
    addTriangleVertex(vertices[2], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
    addTriangleVertex(vertices[3], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
 
    addQuadIndices(index, index + 1, index + 2, index + 3);
}
 
void DebugDrawer::buildFilledTriangle(const Ogre::Vector3 *vertices,
                                                                          const Ogre::ColourValue& colour,
                                                                          float alpha)
{
    int index = addTriangleVertex(vertices[0], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
    addTriangleVertex(vertices[1], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
    addTriangleVertex(vertices[2], Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
 
    addTriangleIndices(index, index + 1, index + 2);
}

void DebugDrawer::buildTetrahedron(const Ogre::Vector3 &centre,
                                  float scale,
                           const Ogre::ColourValue &colour,
                           float alpha)
{
   int index = linesIndex;

   // Distance from the centre
   float bottomDistance = scale * 0.2f;
   float topDistance = scale * 0.62f;
   float frontDistance = scale * 0.289f;
   float backDistance = scale * 0.577f;
   float leftRightDistance = scale * 0.5f;

   addLineVertex(Ogre::Vector3(centre.x, centre.y + topDistance, centre.z),
      Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
   addLineVertex(Ogre::Vector3(centre.x, centre.y - bottomDistance, centre.z + frontDistance),
      Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
   addLineVertex(Ogre::Vector3(centre.x + leftRightDistance, centre.y - bottomDistance, centre.z - backDistance),
      Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
   addLineVertex(Ogre::Vector3(centre.x - leftRightDistance, centre.y - bottomDistance, centre.z - backDistance),
      Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));

   addLineIndices(index, index + 1);
   addLineIndices(index, index + 2);
   addLineIndices(index, index + 3);

   addLineIndices(index + 1, index + 2);
   addLineIndices(index + 2, index + 3);
   addLineIndices(index + 3, index + 1);
}

void DebugDrawer::buildFilledTetrahedron(const Ogre::Vector3 &centre,
                               float scale,
                               const Ogre::ColourValue &colour,
                               float alpha)
{
   int index = trianglesIndex;

   // Distance from the centre
   float bottomDistance = scale * 0.2f;
   float topDistance = scale * 0.62f;
   float frontDistance = scale * 0.289f;
   float backDistance = scale * 0.577f;
   float leftRightDistance = scale * 0.5f;

   addTriangleVertex(Ogre::Vector3(centre.x, centre.y + topDistance, centre.z),
      Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
   addTriangleVertex(Ogre::Vector3(centre.x, centre.y - bottomDistance, centre.z + frontDistance),
      Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
   addTriangleVertex(Ogre::Vector3(centre.x + leftRightDistance, centre.y - bottomDistance, centre.z - backDistance),
      Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));
   addTriangleVertex(Ogre::Vector3(centre.x - leftRightDistance, centre.y - bottomDistance, centre.z - backDistance),
      Ogre::ColourValue(colour.r, colour.g, colour.b, alpha));

   addTriangleIndices(index, index + 1, index + 2);
   addTriangleIndices(index, index + 2, index + 3);
   addTriangleIndices(index, index + 3, index + 1);

   addTriangleIndices(index + 1, index + 3, index + 2);
}
 
void DebugDrawer::drawLine(const Ogre::Vector3& start,
                     const Ogre::Vector3& end,
                     const Ogre::ColourValue& colour)
{
   buildLine(start, end, colour);
}
 
void DebugDrawer::drawCircle(const Ogre::Vector3 &centre,
                            float radius,
                      int segmentsCount,
                      const Ogre::ColourValue& colour,
                      bool isFilled)
{
   buildCircle(centre, radius, segmentsCount, colour);
   if (isFilled) buildFilledCircle(centre, radius, segmentsCount, colour, fillAlpha);
}

void DebugDrawer::drawCylinder(const Ogre::Vector3 &centre,
                            float radius,
                      int segmentsCount,
                      float height,
                      const Ogre::ColourValue& colour,
                      bool isFilled)
{
   buildCylinder(centre, radius, segmentsCount, height, colour);
   if (isFilled) buildFilledCylinder(centre, radius, segmentsCount, height, colour, fillAlpha);
}
 
void DebugDrawer::drawQuad(const Ogre::Vector3 *vertices,
                     const Ogre::ColourValue& colour,
                     bool isFilled)
{
   buildQuad(vertices, colour);
   if (isFilled) buildFilledQuad(vertices, colour, fillAlpha);
}
 
void DebugDrawer::drawCuboid(const Ogre::Vector3 *vertices,
                       const Ogre::ColourValue& colour,
                      bool isFilled)
{
   buildCuboid(vertices, colour);
   if (isFilled) buildFilledCuboid(vertices, colour, fillAlpha);
}
 
void DebugDrawer::drawSphere(const Ogre::Vector3 &centre,
                             float radius,
                             const Ogre::ColourValue& colour,
                             bool isFilled)
{
   int baseIndex = linesIndex;
   linesIndex += icoSphere.addToVertices(&lineVertices, centre, colour, radius);
   icoSphere.addToLineIndices(baseIndex, &lineIndices);
 
   if (isFilled)
   {
      baseIndex = trianglesIndex;
      trianglesIndex += icoSphere.addToVertices(&triangleVertices, centre, Ogre::ColourValue(colour.r, colour.g, colour.b, fillAlpha), radius);
      icoSphere.addToTriangleIndices(baseIndex, &triangleIndices);
   }
}

void DebugDrawer::drawTetrahedron(const Ogre::Vector3 &centre,
                          float scale,
                          const Ogre::ColourValue& colour,
                          bool isFilled)
{
   buildTetrahedron(centre, scale, colour);
   if (isFilled) buildFilledTetrahedron(centre, scale, colour, fillAlpha);
}
 
void DebugDrawer::build()
{
   manualObject->beginUpdate(0);
   if (lineVertices.size() > 0)
   {
      manualObject->estimateVertexCount(lineVertices.size());
      manualObject->estimateIndexCount(lineIndices.size());
      for (std::list<VertexPair>::iterator i = lineVertices.begin(); i != lineVertices.end(); i++)
      {
            manualObject->position(i->first);
            manualObject->colour(i->second);
      }
      for (std::list<int>::iterator i = lineIndices.begin(); i != lineIndices.end(); i++)
         manualObject->index(*i);
   }
   manualObject->end();
 
   manualObject->beginUpdate(1);
   if (triangleVertices.size() > 0)
   {
      manualObject->estimateVertexCount(triangleVertices.size());
      manualObject->estimateIndexCount(triangleIndices.size());
      for (std::list<VertexPair>::iterator i = triangleVertices.begin(); i != triangleVertices.end(); i++)
      {
            manualObject->position(i->first);
            manualObject->colour(i->second.r, i->second.g, i->second.b, fillAlpha);
      }
      for (std::list<int>::iterator i = triangleIndices.begin(); i != triangleIndices.end(); i++)
         manualObject->index(*i);
   }
   manualObject->end();
}
 
void DebugDrawer::clear()
{
    lineVertices.clear();
    triangleVertices.clear();
    lineIndices.clear();
    triangleIndices.clear();
   linesIndex = trianglesIndex = 0;
}
 
int DebugDrawer::addLineVertex(const Ogre::Vector3 &vertex, const Ogre::ColourValue &colour)
{
    lineVertices.push_back(VertexPair(vertex, colour));
    return linesIndex++;
}
 
void DebugDrawer::addLineIndices(int index1, int index2)
{
    lineIndices.push_back(index1);
    lineIndices.push_back(index2);
}
 
int DebugDrawer::addTriangleVertex(const Ogre::Vector3 &vertex, const Ogre::ColourValue &colour)
{
   triangleVertices.push_back(VertexPair(vertex, colour));
   return trianglesIndex++;
}
 
void DebugDrawer::addTriangleIndices(int index1, int index2, int index3)
{
   triangleIndices.push_back(index1);
   triangleIndices.push_back(index2);
   triangleIndices.push_back(index3);
}
 
void DebugDrawer::addQuadIndices(int index1, int index2, int index3, int index4)
{
   triangleIndices.push_back(index1);
   triangleIndices.push_back(index2);
   triangleIndices.push_back(index3);
 
   triangleIndices.push_back(index1);
   triangleIndices.push_back(index3);
   triangleIndices.push_back(index4);
}


The required material:
Code: Select all
material debug_draw
{
   technique
   {
      pass
      {
         lighting off
         scene_blend alpha_blend
         depth_check on
         depth_write off
         ambient vertexcolour
         diffuse vertexcolour
         specular vertexcolour
      }
   }
}
Last edited by fishcakedev on Sun Jul 17, 2011 2:28 am, edited 9 times in total.

For this message the author fishcakedev has received 5 kudos
fishcakedev
Gnoblar
 
Posts: 24
Kudos: 10
Joined: 14 Mar 2011

Re: Debug Drawing Utility Class

Postby spacegaier » Sun May 29, 2011 10:28 am

Could you perhaps post a screenshot to illustrate it? And maybe even put it in the wiki?
Ogre Admin [DevTeamMember, PR, Finance, Wiki, etc.] | BasicOgreFramework | AdvancedOgreFramework
Don't know what to do in your sparetime? Help the Ogre wiki grow!
User avatar
spacegaier
OGRE Team Member
OGRE Team Member
 
Posts: 3843
Kudos: 86
Joined: 04 Feb 2008
Location: Germany

Re: Debug Drawing Utility Class

Postby fishcakedev » Sun May 29, 2011 6:10 pm

My codes above should work straight out of the box. To illustrate, I did a simple demo application. Using the Ogre AppWizard, I created a simple application which ended up looking like this:

Code: Select all
class DebugDrawingUtility : public BaseApplication
{
public:
    DebugDrawingUtility(void);
    virtual ~DebugDrawingUtility(void);

protected:
    virtual void createScene(void);
   virtual void destroyScene(void);

   // Override
   virtual bool frameStarted(const Ogre::FrameEvent& evt);
   virtual bool frameEnded(const Ogre::FrameEvent& evt);

   // Keep track of the ogre head
   Ogre::Entity* ogreHead;
};


First, inside createScene, I initialise the DebugDrawer: (EDIT: DebugDrawer::initialise is now private and is called inside its constructor)
Code: Select all
void DebugDrawingUtility::createScene(void)
{
    ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");

    Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    headNode->attachObject(ogreHead);

    // Set ambient light
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));

    // Create a light
    Ogre::Light* l = mSceneMgr->createLight("MainLight");
    l->setPosition(20,80,50);

   // Initialise the DebugDrawer singleton
   new DebugDrawer(mSceneMgr, 0.5f);
   //DebugDrawer::getSingleton().initialise();
}

Note: The second parameter for the constructor is the alpha value for the filled primitives.

And not to forget: (EDIT: DebugDrawer::shutdown is now private and is called inside its destructor)
Code: Select all
void DebugDrawingUtility::destroyScene(void)
{
   //DebugDrawer::getSingleton().shutdown();
   delete DebugDrawer::getSingletonPtr();
}


Then, inside frameEnded, call DebugDrawer::clear():
Code: Select all
bool DebugDrawingUtility::frameEnded(const Ogre::FrameEvent& evt)
{
   // After the frame is rendered, call DebugDrawer::clear()
   DebugDrawer::getSingleton().clear();
   return true;
}


Finally, the main code is inside frameStarted:
Code: Select all
bool DebugDrawingUtility::frameStarted(const Ogre::FrameEvent& evt)
{
   // Since this framework lacks a proper update loop, I'll just place the drawing codes here.
   // Drawing codes should go inside an update loop, before the frame is rendered.

   // Let's draw the bounding box for the ogre head!
   DebugDrawer::getSingleton().drawCuboid(ogreHead->getBoundingBox().getAllCorners(), Ogre::ColourValue::Red, true);

   // ===================================================================

   // Right before the frame is rendered, call DebugDrawer::build().
   DebugDrawer::getSingleton().build();
   return true;
}

Note: The first parameter of DebugDrawer::drawCuboid is a pointer to an array of 8 Vector3s. The order of the points follows AxisAlignedBox::getAllCorners.
Setting the third parameter to true means that the cuboid will be filled. Otherwise, only the outline of the cuboid will be drawn.

The result (release build):
screen01.png


Let's have fun with coloured boxes! :D
Code: Select all
   for (int i = 0; i < 5; ++i)
   {
      for (int j = 0; j < 5; j++)
      {
         for (int k = 0; k < 5; k++)
         {
            Ogre::AxisAlignedBox box (Ogre::Vector3(i * 10.0f + 2.0f, j * 10.0f + 2.0f, k * 10.0f + 2.0f),
               Ogre::Vector3((i + 1) * 10.0f - 2.0f, (j + 1) * 10.0f - 2.0f, (k + 1) * 10.0f - 2.0f));
            DebugDrawer::getSingleton().drawCuboid(box.getAllCorners(),
               Ogre::ColourValue(51.0f * i / 255.0f, 51.0f * j / 255.0f, 51.0f * k / 255.0f), true);
         }
      }
   }


The result (release build):
screen02.png


I'll add more primitives in the near future, like spheres, circles, etc.

spacegaier wrote:And maybe even put it in the wiki?

I'll do that soon, but I think I need some sleep now. :)
Last edited by fishcakedev on Sat Jul 16, 2011 7:36 am, edited 2 times in total.

For this message the author fishcakedev has received kudos
fishcakedev
Gnoblar
 
Posts: 24
Kudos: 10
Joined: 14 Mar 2011

Re: Debug Drawing Utility Class

Postby Jabberwocky » Sun May 29, 2011 6:18 pm

Looks useful, and very pretty for a debug utility. :)
Image
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
 
Posts: 2817
Kudos: 212
Joined: 05 Mar 2007
Location: Canada

Re: Debug Drawing Utility Class

Postby spacegaier » Sun May 29, 2011 6:25 pm

Jabberwocky wrote:Looks useful, and very pretty for a debug utility. :)

Thought the same.

fishcakedev wrote:
spacegaier wrote:And maybe even put it in the wiki?

I'll do that soon, but I think I need some sleep now. :)

Thanks!
Ogre Admin [DevTeamMember, PR, Finance, Wiki, etc.] | BasicOgreFramework | AdvancedOgreFramework
Don't know what to do in your sparetime? Help the Ogre wiki grow!
User avatar
spacegaier
OGRE Team Member
OGRE Team Member
 
Posts: 3843
Kudos: 86
Joined: 04 Feb 2008
Location: Germany

Re: Debug Drawing Utility Class

Postby fishcakedev » Mon May 30, 2011 3:59 am


For this message the author fishcakedev has received kudos
fishcakedev
Gnoblar
 
Posts: 24
Kudos: 10
Joined: 14 Mar 2011

Re: Debug Drawing Utility Class

Postby fishcakedev » Tue May 31, 2011 10:44 am

I changed the whole class to make use of index, using less vertex data. And I added icosphere! :D All thanks to this article. Check the wiki for update.

Note: The screen shots below are taken from a relatively more powerful PC than the one I was using. That's why the FPS is way higher.

screen04.png


Oh how could I forget about circles! It's not that optimized though, because the circle is being generated every time the draw function is called (cos and sin are expensive, no?).

screen05.png


Now I'm thinking of adding text. This might take a while.

For this message the author fishcakedev has received kudos
fishcakedev
Gnoblar
 
Posts: 24
Kudos: 10
Joined: 14 Mar 2011

Re: Debug Drawing Utility Class

Postby Beauty » Thu Jul 07, 2011 10:47 pm

Thanks fishcakedev for sharing this great class !!
And also for creation of the wiki page.

The linked article for creation of icosphere mesh by code is interesting.

By the way - user Tubulii did port it to Visual Basic (see here). So it's also usable for Mogre (.NET) users.
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
 
Posts: 766
Kudos: 40
Joined: 10 Oct 2007
Location: Germany

Re: Debug Drawing Utility Class

Postby Beauty » Fri Jul 08, 2011 2:34 pm

If you like to add tetrahedron generation, you can use my published code.
The advantage of tetrahedrons:
They just need 4 vertices and 4 triangles. So you should have a lesser CPU/GPU load than cubes.

My code is C#, but it should be similar to port it to C++.
http://www.ogre3d.org/tikiwiki/Create+T ... with+MOGRE
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
 
Posts: 766
Kudos: 40
Joined: 10 Oct 2007
Location: Germany

Re: Debug Drawing Utility Class

Postby happy_spike » Tue Jul 12, 2011 1:04 am

Great work, really handy and saves lines of messy code that's hard to track. Can I request a cylinder as a primitive? I'm writing a 3d interface and the carosel docks use cylinder bounding boxes so they would be SUPER handy! (until then I will just be using 2 of your handy circles!)
User avatar
happy_spike
Halfling
 
Posts: 43
Kudos: 5
Joined: 03 Mar 2010
Location: Australia

Re: Debug Drawing Utility Class

Postby Beauty » Tue Jul 12, 2011 11:16 am

The Mogre port now contains tetrahedron support.
If you want to add this feature to your C++ class, then just have a look to the Mogre port and you should have easy work.
The source is here:
http://www.ogre3d.org/addonforums/viewt ... 515#p81515
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.

For this message the author Beauty has received kudos
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
 
Posts: 766
Kudos: 40
Joined: 10 Oct 2007
Location: Germany

Re: Debug Drawing Utility Class

Postby fishcakedev » Fri Jul 15, 2011 2:39 am

Wow, it's great to hear that people are finding it useful! :D Well, honestly, I have kind of neglected this for a while due to college and assignments. Busy busy busy! I shall continue working on it. :)

[EDIT]
As requested, I added cylinder! :D The updated code is in my first post. I will update the code in the wiki soon.

Code: Select all
DebugDrawer::getSingleton().drawCylinder(Ogre::Vector3::ZERO, 10.0f, 16, 10.0f, Ogre::ColourValue::Red, true);
DebugDrawer::getSingleton().drawCylinder(Ogre::Vector3(0.0f, 10.0f, 0.0f), 10.0f, 16, 10.0f, Ogre::ColourValue::Blue, true);
DebugDrawer::getSingleton().drawCylinder(Ogre::Vector3(0.0f, 20.0f, 0.0f), 10.0f, 16, 10.0f, Ogre::ColourValue::Green, true);


screen03.png


Tetrahedron will be added next! :)

For this message the author fishcakedev has received 2 kudos
fishcakedev
Gnoblar
 
Posts: 24
Kudos: 10
Joined: 14 Mar 2011

Re: Debug Drawing Utility Class

Postby jacmoe » Fri Jul 15, 2011 6:50 am

Really, really nice! :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, Fueled by Passion.
Ogre AppWizards - Ogre project wizards for VC 8-10, Code::Blocks and KDevelop.
OgreAssimpConverter - command-line to convert models to Ogre format.
TwOgreGUI - wrapper for AntTweakBar GUI library.
I accept donations | Me on Google+
User avatar
jacmoe
OGRE Moderator
OGRE Moderator
 
Posts: 21024
Kudos: 161
Joined: 22 Jan 2004
Location: Denmark

Re: Debug Drawing Utility Class

Postby happy_spike » Fri Jul 15, 2011 7:56 am

Thank you UBER much thats awsome and now I will have an easy way of checking to see if my cylinder ray intersection code works as intended. Kudos this guy up he deserves it!
User avatar
happy_spike
Halfling
 
Posts: 43
Kudos: 5
Joined: 03 Mar 2010
Location: Australia

Re: Debug Drawing Utility Class

Postby fishcakedev » Sat Jul 16, 2011 7:41 am

Added tetrahedron primitive (based on Beauty's code). :)

Code: Select all
DebugDrawer::getSingleton().drawTetrahedron(Ogre::Vector3::ZERO, 20.0f, Ogre::ColourValue::Red, true);


screen04.png


The latest code is in my first post. The wiki is now updated too.

Note: DebugDrawer::initialise and DebugDrawer::shutdown are now private and called inside the constructor and destructor respectively. The reason for this change is to follow the RAII idiom.
fishcakedev
Gnoblar
 
Posts: 24
Kudos: 10
Joined: 14 Mar 2011

Re: Debug Drawing Utility Class

Postby happy_spike » Sat Jul 16, 2011 3:57 pm

Thought you might like to see your code in action, so here is a screenshot of the cylinders marking my 3d widget docks area. I have set them to switch on and of, however once they are drawn, even if a call clear they stay where they were last drawn. How would I wipe them so I can toggle them off again? I can't run them full time cause my frame rate goes to hell with all 12 cylinders drawing each cycle.

Image
User avatar
happy_spike
Halfling
 
Posts: 43
Kudos: 5
Joined: 03 Mar 2010
Location: Australia

Re: Debug Drawing Utility Class

Postby Beauty » Sat Jul 16, 2011 4:06 pm

Nice to see "my" tetrahedron figure in your debug class.
Now I know my code publishing was useful for others.

Also thanks for pointing to the RAII article.
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
 
Posts: 766
Kudos: 40
Joined: 10 Oct 2007
Location: Germany

Re: Debug Drawing Utility Class

Postby fishcakedev » Sat Jul 16, 2011 4:12 pm

As long as you're still calling DebugDrawer::draw* function, the respective primitive will be drawn. So just enclose the drawing code inside an if like this:

Code: Select all
if (isDebugDrawingOn) 
{
    // All the draw functions go inside here
}


Turning the debug drawing on and off is now simply setting the value of isDebugDrawingOn.
fishcakedev
Gnoblar
 
Posts: 24
Kudos: 10
Joined: 14 Mar 2011

Re: Debug Drawing Utility Class

Postby Beauty » Sat Jul 16, 2011 4:22 pm

fishcakedev wrote:After days and hours of struggle, I finally managed to implement my own debug drawing class! :D And it's quite optimized (I think). Credit goes to the author of this post, because my implementation is based on his.

Now I wrote a message to the author to tell him the benifit.
His code publication (2 years ago) didn't get any reply.
Now he can be happy, because his previous work became a basis for our new visual debugging tool.
And by my message he know about the success of his contribution.
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
 
Posts: 766
Kudos: 40
Joined: 10 Oct 2007
Location: Germany

Re: Debug Drawing Utility Class

Postby fishcakedev » Sat Jul 16, 2011 4:36 pm

Beauty wrote:
fishcakedev wrote:After days and hours of struggle, I finally managed to implement my own debug drawing class! :D And it's quite optimized (I think). Credit goes to the author of this post, because my implementation is based on his.

Now I wrote a message to the author to tell him the benifit.
His code publication (2 years ago) didn't get any reply.
Now he can be happy, because his previous work became a basis for our new visual debugging tool.
And by my message he know about the success of his contribution.


Yep, his code was really helpful. :) He had an earlier thread which was what I found first (currently no. 4 if you search for "ogre debug drawing" in google). I struggled to follow his initial implementation, which was using a separate SceneManager and Viewport. Then I searched through his list of started threads and found that thread. Thank goodness he posted his solution! :D
fishcakedev
Gnoblar
 
Posts: 24
Kudos: 10
Joined: 14 Mar 2011

Re: Debug Drawing Utility Class

Postby happy_spike » Sun Jul 17, 2011 12:24 am

fishcakedev wrote:As long as you're still calling DebugDrawer::draw* function, the respective primitive will be drawn. So just enclose the drawing code inside an if like this:

Code: Select all
if (isDebugDrawingOn) 
{
    // All the draw functions go inside here
}


Turning the debug drawing on and off is now simply setting the value of isDebugDrawingOn.


Yeah I was doing it exactly as you posted ( seemed perfectly logical to me) but it still retains the last drawn cylinders. Must be something else I'm doing wrong I'll have to investigate
User avatar
happy_spike
Halfling
 
Posts: 43
Kudos: 5
Joined: 03 Mar 2010
Location: Australia

Re: Debug Drawing Utility Class

Postby fishcakedev » Sun Jul 17, 2011 2:27 am

happy_spike wrote:Yeah I was doing it exactly as you posted ( seemed perfectly logical to me) but it still retains the last drawn cylinders. Must be something else I'm doing wrong I'll have to investigate


Ah, turns out it's something wrong with my code! You need to edit DebugDrawer::build function, moving the if statements so that it is in between beginUpdate and end:
Code: Select all
void DebugDrawer::build()
{
   manualObject->beginUpdate(0);
   if (lineVertices.size() > 0)
   {
      manualObject->estimateVertexCount(lineVertices.size());
      manualObject->estimateIndexCount(lineIndices.size());
      for (std::list<VertexPair>::iterator i = lineVertices.begin(); i != lineVertices.end(); i++)
      {
            manualObject->position(i->first);
            manualObject->colour(i->second);
      }
      for (std::list<int>::iterator i = lineIndices.begin(); i != lineIndices.end(); i++)
         manualObject->index(*i);
   }
   manualObject->end();
 
   manualObject->beginUpdate(1);
   if (triangleVertices.size() > 0)
   {
      manualObject->estimateVertexCount(triangleVertices.size());
      manualObject->estimateIndexCount(triangleIndices.size());
      for (std::list<VertexPair>::iterator i = triangleVertices.begin(); i != triangleVertices.end(); i++)
      {
            manualObject->position(i->first);
            manualObject->colour(i->second.r, i->second.g, i->second.b, fillAlpha);
      }
      for (std::list<int>::iterator i = triangleIndices.begin(); i != triangleIndices.end(); i++)
         manualObject->index(*i);
   }
   manualObject->end();
}


The call to beginUpdate will reset the manual object. Previously, it will be skipped if there are no vertices and indices. Silly me! :oops:
fishcakedev
Gnoblar
 
Posts: 24
Kudos: 10
Joined: 14 Mar 2011

Re: Debug Drawing Utility Class

Postby Beauty » Sun Jul 17, 2011 1:16 pm

Perhaps you could create a public repository for the utility class.
The you (or any helper) just need to commit the current version instead of updating the forum and wiki.
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
 
Posts: 766
Kudos: 40
Joined: 10 Oct 2007
Location: Germany

Re: Debug Drawing Utility Class

Postby fishcakedev » Mon Jul 18, 2011 8:41 am

Beauty wrote:Perhaps you could create a public repository for the utility class.
The you (or any helper) just need to commit the current version instead of updating the forum and wiki.


Okay, I created a public repository at Bitbucket. This is my first time setting up a public repository, so I don't really know how things are supposed to work. :oops:
fishcakedev
Gnoblar
 
Posts: 24
Kudos: 10
Joined: 14 Mar 2011

Re: Debug Drawing Utility Class

Postby Beauty » Mon Jul 18, 2011 10:46 am

Nice job (-:

Now I removed the source code from the wiki page.
Instead I creaded a section called "source code". There I refered to the repository.
Additionally I attached the source code as zip file snapshot to the wiki page.
This should improve the overview of the wiki page and reduce your publishing work when you update the script. (Now you just need to commit your file by TortoiseHG.)

It would be good if you add the material file to the repository, too.

If you allow shared write access with user Tubulii, you also could create a subdirectory called "Mogre port", which includes the VB script. Then both codes are available in your repository and also Tubulii could maintain it easily.
If you don't want to allow shared access, just say no.

To the overview page of your repository you could add these Links:
* Wiki page: http://ogre3d.org/tikiwiki/Debug+Drawing+Utility+Class
* This forum thread: viewtopic.php?f=5&t=64941
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
 
Posts: 766
Kudos: 40
Joined: 10 Oct 2007
Location: Germany

Next

Return to Using OGRE in practice

Who is online

Users browsing this forum: Yahoo [Bot] and 2 guests