Debug Drawing Utility Class

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
fishcakedev
Gnoblar
Posts: 24
Joined: Mon Mar 14, 2011 3:23 pm
x 10

Debug Drawing Utility Class

Post by fishcakedev »

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.
User avatar
spacegaier
OGRE Team Member
OGRE Team Member
Posts: 4304
Joined: Mon Feb 04, 2008 2:02 pm
Location: Germany
x 135
Contact:

Re: Debug Drawing Utility Class

Post by spacegaier »

Could you perhaps post a screenshot to illustrate it? And maybe even put it in the wiki?
Ogre Admin [Admin, Dev, PR, Finance, Wiki, etc.] | BasicOgreFramework | AdvancedOgreFramework
Don't know what to do in your spare time? Help the Ogre wiki grow! Or squash a bug...
fishcakedev
Gnoblar
Posts: 24
Joined: Mon Mar 14, 2011 3:23 pm
x 10

Re: Debug Drawing Utility Class

Post by fishcakedev »

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.
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
x 218
Contact:

Re: Debug Drawing Utility Class

Post by Jabberwocky »

Looks useful, and very pretty for a debug utility. :)
Image
User avatar
spacegaier
OGRE Team Member
OGRE Team Member
Posts: 4304
Joined: Mon Feb 04, 2008 2:02 pm
Location: Germany
x 135
Contact:

Re: Debug Drawing Utility Class

Post by spacegaier »

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 [Admin, Dev, PR, Finance, Wiki, etc.] | BasicOgreFramework | AdvancedOgreFramework
Don't know what to do in your spare time? Help the Ogre wiki grow! Or squash a bug...
fishcakedev
Gnoblar
Posts: 24
Joined: Mon Mar 14, 2011 3:23 pm
x 10

Re: Debug Drawing Utility Class

Post by fishcakedev »

fishcakedev
Gnoblar
Posts: 24
Joined: Mon Mar 14, 2011 3:23 pm
x 10

Re: Debug Drawing Utility Class

Post by fishcakedev »

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.
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
Posts: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39
Contact:

Re: Debug Drawing Utility Class

Post by Beauty »

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: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39
Contact:

Re: Debug Drawing Utility Class

Post by Beauty »

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
happy_spike
Halfling
Posts: 44
Joined: Wed Mar 03, 2010 3:05 am
Location: Australia
x 5

Re: Debug Drawing Utility Class

Post by happy_spike »

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
Beauty
OGRE Community Helper
OGRE Community Helper
Posts: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39
Contact:

Re: Debug Drawing Utility Class

Post by Beauty »

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.
fishcakedev
Gnoblar
Posts: 24
Joined: Mon Mar 14, 2011 3:23 pm
x 10

Re: Debug Drawing Utility Class

Post by fishcakedev »

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! :)
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: Debug Drawing Utility Class

Post by jacmoe »

Really, really nice! :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
happy_spike
Halfling
Posts: 44
Joined: Wed Mar 03, 2010 3:05 am
Location: Australia
x 5

Re: Debug Drawing Utility Class

Post by happy_spike »

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!
fishcakedev
Gnoblar
Posts: 24
Joined: Mon Mar 14, 2011 3:23 pm
x 10

Re: Debug Drawing Utility Class

Post by fishcakedev »

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.
User avatar
happy_spike
Halfling
Posts: 44
Joined: Wed Mar 03, 2010 3:05 am
Location: Australia
x 5

Re: Debug Drawing Utility Class

Post by happy_spike »

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
Beauty
OGRE Community Helper
OGRE Community Helper
Posts: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39
Contact:

Re: Debug Drawing Utility Class

Post by Beauty »

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.
fishcakedev
Gnoblar
Posts: 24
Joined: Mon Mar 14, 2011 3:23 pm
x 10

Re: Debug Drawing Utility Class

Post by fishcakedev »

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.
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
Posts: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39
Contact:

Re: Debug Drawing Utility Class

Post by Beauty »

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.
fishcakedev
Gnoblar
Posts: 24
Joined: Mon Mar 14, 2011 3:23 pm
x 10

Re: Debug Drawing Utility Class

Post by fishcakedev »

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
User avatar
happy_spike
Halfling
Posts: 44
Joined: Wed Mar 03, 2010 3:05 am
Location: Australia
x 5

Re: Debug Drawing Utility Class

Post by happy_spike »

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
fishcakedev
Gnoblar
Posts: 24
Joined: Mon Mar 14, 2011 3:23 pm
x 10

Re: Debug Drawing Utility Class

Post by fishcakedev »

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:
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
Posts: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39
Contact:

Re: Debug Drawing Utility Class

Post by Beauty »

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.
fishcakedev
Gnoblar
Posts: 24
Joined: Mon Mar 14, 2011 3:23 pm
x 10

Re: Debug Drawing Utility Class

Post by fishcakedev »

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:
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
Posts: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39
Contact:

Re: Debug Drawing Utility Class

Post by Beauty »

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: http://www.ogre3d.org/forums/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.
Post Reply