Debug Drawing Utility Class for Mogre

Tubulii

06-07-2011 19:10:14

Hi, I converted the Debug Drawing Utility Class from the Wiki. It's a quite nice helper class.
Check out the official Debug Drawer-repository for the latest code
and the wiki article for a short overview and read this post for a short introduction
Thanks to Beauty and, of course, to the original author fishcakedev


How to use it:

0. (Recommend by me) Read the original article here

1. Download latest code (VB.Net or C#) and material file from repository and add it to your project.

2. Create a new instance of DebugDrawer (for example in 'CreateScene'):
DebugDrawer.Singleton.Initialise(mSceneMgr, 0.6))
mSceneMgr -> Your SceneManager
0.6 -> alpha (range 0 to 1; see screenshot below)
Note: The debug drawer is a singleton class.

3. Initialise it (for example in 'CreateScene'):
DebugDrawer.Singleton.initialise()

4. Update it every frame (in 'FrameStarted', see 5. ) or once:
DebugDrawer.Singleton.build()

5. (Optional, but recommend by original author) Clear it every frame (in 'FrameEnded'):
DebugDrawer.Singleton.clear()
(Please note, that if you clear Debugdrawer every frame, you need to draw it every frame again)

Example usage:

For i As Integer = 0 To 4
For j As Integer = 0 To 4
For k As Integer = 0 To 4
Dim box As AxisAlignedBox = New AxisAlignedBox(New Vector3(i * 10.0F + 2.0F, j * 10.0F + 2.0F, k * 10.0F + 2.0F), New Vector3((i + 1) * 10.0F - 2.0F, (j + 1) * 10.0F - 2.0F, (k + 1) * 10.0F - 2.0F))
DebugDrawer.Singleton.drawCuboid(box.getAllCorners(), New ColourValue(51.0F * i / 255.0F, 51.0F * j / 255.0F, 51.0F * k / 255.0F), True)
Next k
Next j
Next i




(from wiki)

And please note, that I only converted it! Nothing more.

Beauty

06-07-2011 23:55:53

Oh great!!

I didn't know this Ogre class. It's very new.
Thanks for porting it. It's very useful. :D

When I find some free time I will add it to the wiki.
Then it's not hidden somewhere in an inconspicuous forum thread and can be discovered quickly.

Update:
Now I added links to 7 related wiki pages. So the Ogre and Mogre version can be found more easy. More I can't do today.

Beauty

07-07-2011 23:15:39

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

Tubulii

08-07-2011 11:48:22

Thanks for sharing, I integrated it and it runs fine. I changed the code a bit to match with the rest of he code. And c# is not really a problem. It's very similar to vb.net (because of .Net) and the rest are only syntax differences.

Beauty

08-07-2011 14:33:26

Oh, I see I posted it in the wrong forum topic.
I wanted to tell it to the author of the original debug class.
But nice to hear that you added it for Mogre (-;

Beauty

08-07-2011 14:37:31

By the way:
On yesterday I created a new wiki page for your Mogre port.
http://ogre3d.org/tikiwiki/Debug+Drawin ... +for+MOGRE

Later I want to add more details. (e.g. examples)
If you like you can upload the files to the wiki page. (see attach option at bottom)

Beauty

15-07-2011 19:28:31

Now the C++ class also contains generation of cylinders.
Look here for details:
http://www.ogre3d.org/forums/viewtopic. ... 31#p433531

Beauty

18-07-2011 10:09:32

Because of my suggestion the author of the C++ class created a public repository for his code. So it's more easy to maintain it.
We could ask him, if he create a subdirectory for your Mogre port and give you write access. So also the port can be maintained easily.

Here is the repository:
https://bitbucket.org/hasyimi/ogre-debu ... y/overview

Tubulii

18-07-2011 19:06:47

Why not, it's a great class.

Beauty

18-07-2011 21:28:10

I asked the C++ author and he agreed to my idea.
Just tell him your contact dates (Google account name??) and he will give you write acess to the repository.
Then for updates you just need to commit the current state of code by your explorer context menu and everybody have access to the current version.

Tubulii

19-07-2011 10:13:55

Ok, I have sent him a message and updated the source code and my first article. As soon as possible will upload it to bitbucket.

Later I want to add more details. (e.g. examples)
If you like you can upload the files to the wiki page. (see attach option at bottom)

Mm, this is a problem. I cannot login because *this* account is only valid for the addonforum. I don't know why the ogre and addonforum are separated. I have, let's say, a dummy account for the ogre forum. I could upload example files with the dummy account.

Beauty

19-07-2011 11:39:57

You should create a second account with the same username/password as you used for this forum.
Then you can log in to the wiki, too.

The reason is in the history.
Many years ago the Ogre user decided to have a second forum, just for add-ons.
I think there was no way to manage the login data for both in one database.
Later the Ogre maintainers wanted to merge the add-ons forum with the main forum, but this would cause much trouble. (e.g. dead links, redundant usage of topic-IDs, etc.)

I think it's not bad to have also an account in the main forum. It's a good place for common questions, which are not Ogre specific, because there are much more users who could help you.

By the way - when you have an account in the main forum, you can enable the function "suscribe topic" at the bottom of the Debug Drawing Utility Class. Then you get an e-mail for new replies. For example today somebody else improved the source code. (If you like, just add it.)
Additionaly you need the main forum account to get in contact with the author. You have to tell him your e-mail-address for repository access.

You see - an Ogre main forum account is no dummy account. :wink:

tafkag

19-07-2011 14:57:38

I tested this with my C#-project, using an auto-convert VB->C# with some minor manual edits where the converter failed.
I ended up with this which worked nicely:


using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using Mogre;


public class DebugDrawer : IDisposable
{

private static DebugDrawer DD;
public const int DEFAULT_ICOSPHERE_RECURSION_LEVEL = 0;
public static DebugDrawer Singleton
{
get { return DD; }
}
public static void SetDebugDrawer(DebugDrawer DD)
{
DebugDrawer.DD = DD;
}

private SceneManager sceneManager;
private ManualObject manualObject;
private float fillAlpha;

private IcoSphere _icoSphere = new IcoSphere();
private LinkedList<KeyValuePair<Vector3, ColourValue>> lineVertices = new LinkedList<KeyValuePair<Vector3, ColourValue>>();
private LinkedList<KeyValuePair<Vector3, ColourValue>> triangleVertices = new LinkedList<KeyValuePair<Vector3, ColourValue>>();
private LinkedList<int> lineIndices = new LinkedList<int>();

private LinkedList<int> triangleIndices = new LinkedList<int>();
private int linesIndex;

private int trianglesIndex;
public class IcoSphere
{
public IcoSphere()
{
index = 0;
}
public void Dispose()
{
}
public void create(int recursionLevel)
{
vertices.Clear();
_lineIndices.Clear();
_triangleIndices.Clear();
faces.Clear();
middlePointIndexCache.Clear();
index = 0;

float t = (1f + Mogre.Math.Sqrt(5f)) / 2f;

addVertex(new Vector3(-1f, t, 0f));
addVertex(new Vector3(1f, t, 0f));
addVertex(new Vector3(-1f, -t, 0f));
addVertex(new Vector3(1f, -t, 0f));

addVertex(new Vector3(0f, -1f, t));
addVertex(new Vector3(0f, 1f, t));
addVertex(new Vector3(0f, -1f, -t));
addVertex(new Vector3(0f, 1f, -t));

addVertex(new Vector3(t, 0f, -1f));
addVertex(new Vector3(t, 0f, 1f));
addVertex(new Vector3(-t, 0f, -1f));
addVertex(new Vector3(-t, 0f, 1f));

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 - 1; i++)
{
LinkedList<TriangleIndices> faces2 = new LinkedList<TriangleIndices>();

dynamic j = faces.GetEnumerator();
while (j.MoveNext())
{
TriangleIndices f = j.Current;
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.AddLast(new LinkedListNode<TriangleIndices>(new TriangleIndices(f.v1, a, c)));
faces2.AddLast(new LinkedListNode<TriangleIndices>(new TriangleIndices(f.v2, b, a)));
faces2.AddLast(new LinkedListNode<TriangleIndices>(new TriangleIndices(f.v3, c, b)));
faces2.AddLast(new LinkedListNode<TriangleIndices>(new TriangleIndices(a, b, c)));

addTriangleLines(f.v1, a, c);
addTriangleLines(f.v2, b, a);
addTriangleLines(f.v3, c, b);
}
j.Dispose();
faces = faces2;
}
}
public void addLineIndices(int index0, int index1)
{
_lineIndices.AddLast(new LinkedListNode<LineIndices>(new LineIndices(index0, index1)));
}
public void removeLineIndices(int index0, int index1)
{
dynamic result = _lineIndices.Find(new LineIndices(index0, index1));

if (result != null)
{
_lineIndices.Remove(result);
}
}
public void addTriangleLines(int index0, int index1, int index2)
{
addLineIndices(index0, index1);
addLineIndices(index1, index2);
addLineIndices(index2, index0);
}
public int addVertex(Vector3 vertex)
{
float length = vertex.Length;
vertices.Add(new Vector3(vertex.x / length, vertex.y / length, vertex.z / length));
index += 1;
return index;
}
public int getMiddlePoint(int index0, int index1)
{
bool isFirstSmaller = index0 < index1;
long smallerIndex = isFirstSmaller ? index0 : index1;
long largerIndex = isFirstSmaller ? index1 : index0;
long key = (smallerIndex << 32) | largerIndex;

if (middlePointIndexCache.ContainsKey(key) && middlePointIndexCache[key] != middlePointIndexCache.Keys.Count)
{
return middlePointIndexCache[key];
}

Vector3 point1 = vertices[index0];
Vector3 point2 = vertices[index1];
Vector3 middle = point1.MidPoint(point2);

int index = addVertex(middle);
if (middlePointIndexCache.ContainsKey(key) == false)
{
middlePointIndexCache.Add(key, index);
}
else
{
middlePointIndexCache[key] = index;

}
return index;
}
public void addFace(int index0, int index1, int index2)
{
faces.AddLast(new TriangleIndices(index0, index1, index2));
}
public void addToLineIndices(int baseIndex, LinkedList<int> target)
{
LinkedList<LineIndices>.Enumerator i = _lineIndices.GetEnumerator();
while (i.MoveNext())
{
target.AddLast(baseIndex + i.Current.v1);
target.AddLast(baseIndex + i.Current.v2);
}
i.Dispose();
}
public void addToTriangleIndices(int baseIndex, LinkedList<int> target)
{
LinkedList<TriangleIndices>.Enumerator i = faces.GetEnumerator();
while (i.MoveNext())
{
target.AddLast(baseIndex + i.Current.v1);
target.AddLast(baseIndex + i.Current.v2);
target.AddLast(baseIndex + i.Current.v3);
}
i.Dispose();
}
public int addToVertices(LinkedList<KeyValuePair<Vector3, ColourValue>> target, Vector3 position, ColourValue colour, float scale)
{
Matrix4 transform = Matrix4.IDENTITY;
transform.SetTrans(position);
transform.SetScale(new Vector3(scale, scale, scale));

for (int i = 0; i <= Convert.ToInt32(vertices.Count) - 1; i++)
{
target.AddLast(new KeyValuePair<Vector3, ColourValue>(transform * vertices, colour));
}

return vertices.Count;
}
public class TriangleIndices
{
public int v1;
public int v2;

public int v3;
public TriangleIndices(int _v1, int _v2, int _v3)
{
v1 = _v1;
v2 = _v2;
v3 = _v3;
}

public static bool operator <(TriangleIndices ImpliedObject, TriangleIndices o)
{
return ImpliedObject.v1 < o.v1 && ImpliedObject.v2 < o.v2 && ImpliedObject.v3 < o.v3;
}
public static bool operator >(TriangleIndices ImpliedObject, TriangleIndices o)
{
return ImpliedObject.v1 > o.v1 && ImpliedObject.v2 > o.v2 && ImpliedObject.v3 > o.v3;
}
}

public class LineIndices
{
public int v1;

public int v2;
public LineIndices(int _v1, int _v2)
{
v1 = _v1;
v2 = _v2;
}

//C++ TO VB CONVERTER WARNING: 'const' methods are not available in VB:
//ORIGINAL LINE: Boolean operator == (const LineIndices &o) const
public static bool operator ==(LineIndices ImpliedObject, LineIndices o)
{
return (ImpliedObject.v1 == o.v1 && ImpliedObject.v2 == o.v2) || (ImpliedObject.v1 == o.v2 && ImpliedObject.v2 == o.v1);
}
public static bool operator !=(LineIndices ImpliedObject, LineIndices o)
{
return (ImpliedObject.v1 != o.v1 && ImpliedObject.v2 != o.v2) || (ImpliedObject.v1 != o.v2 && ImpliedObject.v2 != o.v1);
}
}


private List<Vector3> vertices = new List<Vector3>();
private LinkedList<LineIndices> _lineIndices = new LinkedList<LineIndices>();
private LinkedList<int> _triangleIndices = new LinkedList<int>();
private LinkedList<TriangleIndices> faces = new LinkedList<TriangleIndices>();
private Dictionary<long, int> middlePointIndexCache = new Dictionary<long, int>();
private int index;
}


public DebugDrawer(SceneManager _sceneManager, float _fillAlpha)
{
sceneManager = _sceneManager;
fillAlpha = _fillAlpha;
manualObject = null;
linesIndex = 0;
trianglesIndex = 0;
}

public void Initialise()
{
manualObject = sceneManager.CreateManualObject("debug_object");
sceneManager.RootSceneNode.CreateChildSceneNode("debug_object").AttachObject(manualObject);
manualObject.Dynamic = true;

_icoSphere.create(DEFAULT_ICOSPHERE_RECURSION_LEVEL);

manualObject.Begin("debug_draw", RenderOperation.OperationTypes.OT_LINE_LIST);
manualObject.Position(Vector3.ZERO);
manualObject.Colour(ColourValue.ZERO);
manualObject.Index(0);
manualObject.End();
manualObject.Begin("debug_draw", RenderOperation.OperationTypes.OT_TRIANGLE_LIST);
manualObject.Position(Vector3.ZERO);
manualObject.Colour(ColourValue.ZERO);
manualObject.Index(0);
manualObject.End();

trianglesIndex = 0;
linesIndex = trianglesIndex;
}
public void SetIcoSphereRecursionLevel(int recursionLevel)
{
_icoSphere.create(recursionLevel);
}
private void Shutdown()
{
sceneManager.DestroySceneNode("debug_object");
sceneManager.DestroyManualObject(manualObject);
}
public void BuildLine(Vector3 start, Vector3 end, ColourValue colour, float alpha)
{
int i = AddLineVertex(start, new ColourValue(colour.r, colour.g, colour.b, alpha));
AddLineVertex(end, new ColourValue(colour.r, colour.g, colour.b, alpha));

AddLineIndices(i, i + 1);
}
public void BuildQuad(Vector3[] vertices, ColourValue colour, float alpha)
{
int index = AddLineVertex(vertices[0], new ColourValue(colour.r, colour.g, colour.b, alpha));
AddLineVertex(vertices[1], new ColourValue(colour.r, colour.g, colour.b, alpha));
AddLineVertex(vertices[2], new ColourValue(colour.r, colour.g, colour.b, alpha));
AddLineVertex(vertices[3], new ColourValue(colour.r, colour.g, colour.b, alpha));

for (int i = 0; i <= 3; i++)
{
AddLineIndices(index + i, index + ((i + 1) % 4));
}
}
public void BuildCircle(Vector3 centre, float radius, int segmentsCount, ColourValue colour, float alpha)
{
int index = linesIndex;
float increment = (float)(2 * Mogre.Math.PI / segmentsCount);
float angle = 0f;

for (int i = 0; i <= segmentsCount - 1; i++)
{
AddLineVertex(new Vector3(centre.x + radius * Mogre.Math.Cos(angle), centre.y, centre.z + radius * Mogre.Math.Sin(angle)), new ColourValue(colour.r, colour.g, colour.b, alpha));
angle += increment;
}

for (int i = 0; i <= segmentsCount - 1; i++)
{
AddLineIndices(index + i, i + 1 < segmentsCount ? index + i + 1 : index);
}
}
public void BuildFilledCircle(Vector3 centre, float radius, int segmentsCount, ColourValue colour, float alpha)
{
int index = trianglesIndex;
float increment = 2 * Mogre.Math.PI / segmentsCount;
float angle = 0f;

for (int i = 0; i <= segmentsCount - 1; i++)
{
AddTriangleVertex(new Vector3(centre.x + radius * Mogre.Math.Cos(angle), centre.y, centre.z + radius * Mogre.Math.Sin(angle)), new ColourValue(colour.r, colour.g, colour.b, alpha));
angle += increment;
}

AddTriangleVertex(centre, new ColourValue(colour.r, colour.g, colour.b, alpha));

for (int i = 0; i <= segmentsCount - 1; i++)
{
AddTriangleIndices(i + 1 < segmentsCount ? index + i + 1 : index, index + i, index + segmentsCount);
}
}
/// <summary>
/// Create a tetrahedron with point of origin in middle of volume.
/// It will be added to the SceneManager as ManualObject. The material must still exists.
/// (Tubulii: Thanks to Beauty for sharing this code| !Slightly modified!)
/// </summary>
/// <param name="position">Position in scene</param>
/// <param name="scale">Size of the tetrahedron</param>
/// <param name="Color">The color of the tetrahedron</param>
public void DrawTetrahedron(Vector3 position, Single scale, ColourValue Color, bool IsFilled)
{
//Dim manObTetra As ManualObject = sceneManager.CreateManualObject(name)
//manObTetra.CastShadows = False

//' render just before overlays (so all objects behind the transparent tetrahedron are visible)
//manObTetra.RenderQueueGroup = CByte(RenderQueueGroupID.RENDER_QUEUE_OVERLAY) - 1
// = 99
Vector3[] c = new Vector3[4];
// corners
// calculate corners of tetrahedron (with point of origin in middle of volume)
Single mbot = scale * 0.2f;
// distance middle to bottom
Single mtop = scale * 0.62f;
// distance middle to top
Single mf = scale * 0.289f;
// distance middle to front
Single mb = scale * 0.577f;
// distance middle to back
Single mlr = scale * 0.5f;
// distance middle to left right
// width / height / depth
c[0] = new Vector3(-mlr, -mbot, mf);
// left bottom front
c[1] = new Vector3(mlr, -mbot, mf);
// right bottom front
c[2] = new Vector3(0, -mbot, -mb);
// (middle) bottom back
c[3] = new Vector3(0, mtop, 0);
// (middle) top (middle)
// add position offset for all corners (move tetrahedron)
for (Int16 i = 0; i <= 3; i++)
{
c += position;
}

// create lines
// bottom
BuildLine(c[2], c[1], Color, 1);
BuildLine(c[1], c[0], Color, 1);
BuildLine(c[0], c[2], Color, 1);
// rest
BuildLine(c[2], c[3], Color, 1);
BuildLine(c[1], c[3], Color, 1);
BuildLine(c[0], c[3], Color, 1);

if (IsFilled)
{
// create bottom
BuildFilledTriangle(new Vector3[] {
c[2],
c[1],
c[0]
}, Color, fillAlpha);

// create right back side
BuildFilledTriangle(new Vector3[] {
c[1],
c[2],
c[3]
}, Color, fillAlpha);

// create left back side
BuildFilledTriangle(new Vector3[] {
c[3],
c[2],
c[0]
}, Color, fillAlpha);


// create front side
BuildFilledTriangle(new Vector3[] {
c[0],
c[1],
c[3]
}, Color, fillAlpha);
}




}

public void BuildCuboid(Vector3[] vertices, ColourValue colour, float alpha)
{
int index = AddLineVertex(vertices[0], new ColourValue(colour.r, colour.g, colour.b, alpha));
for (int i = 1; i <= 7; i++)
{
AddLineVertex(vertices, new ColourValue(colour.r, colour.g, colour.b, alpha));
}

for (int i = 0; i <= 3; i++)
{
AddLineIndices(index + i, index + ((i + 1) % 4));
}
for (int i = 4; i <= 7; 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);
}
public void BuildFilledCuboid(Vector3[] vertices, ColourValue colour, float alpha)
{
int index = AddTriangleVertex(vertices[0], new ColourValue(colour.r, colour.g, colour.b, alpha));
for (int i = 1; i <= 7; i++)
{
AddTriangleVertex(vertices, new 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);
}
public void BuildFilledQuad(Vector3[] vertices, ColourValue colour, float alpha)
{
int index = AddTriangleVertex(vertices[0], new ColourValue(colour.r, colour.g, colour.b, alpha));
AddTriangleVertex(vertices[1], new ColourValue(colour.r, colour.g, colour.b, alpha));
AddTriangleVertex(vertices[2], new ColourValue(colour.r, colour.g, colour.b, alpha));
AddTriangleVertex(vertices[3], new ColourValue(colour.r, colour.g, colour.b, alpha));

AddQuadIndices(index, index + 1, index + 2, index + 3);
}
public void BuildFilledTriangle(Vector3[] vertices, ColourValue colour, float alpha)
{
int index = AddTriangleVertex(vertices[0], new ColourValue(colour.r, colour.g, colour.b, alpha));
AddTriangleVertex(vertices[1], new ColourValue(colour.r, colour.g, colour.b, alpha));
AddTriangleVertex(vertices[2], new ColourValue(colour.r, colour.g, colour.b, alpha));

AddTriangleIndices(index, index + 1, index + 2);
}
public void DrawLine(Vector3 start, Vector3 end, ColourValue colour)
{
BuildLine(start, end, colour, 1);
}
public void drawCircle(Vector3 centre, float radius, int segmentsCount, ColourValue colour, bool isFilled)
{
BuildCircle(centre, radius, segmentsCount, colour, 1);
if (isFilled)
{
BuildFilledCircle(centre, radius, segmentsCount, colour, fillAlpha);
}
}
public void DrawQuad(Vector3[] vertices, ColourValue colour, bool isFilled)
{
BuildQuad(vertices, colour, 1);
if (isFilled)
{
BuildFilledQuad(vertices, colour, fillAlpha);
}
}
public void DrawCuboid(Vector3[] vertices, ColourValue colour, bool isFilled)
{
BuildCuboid(vertices, colour, fillAlpha);
if (isFilled)
{
BuildFilledCuboid(vertices, colour, fillAlpha);
}
}
public void DrawSphere(Vector3 centre, float radius, 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, new ColourValue(colour.r, colour.g, colour.b, fillAlpha), radius);
_icoSphere.addToTriangleIndices(baseIndex, triangleIndices);
}
}

public void Build()
{

if (lineVertices.Count > 0)
{
manualObject.BeginUpdate(0);
manualObject.EstimateVertexCount((uint)lineVertices.Count + 1);
manualObject.EstimateIndexCount((uint)lineIndices.Count + 1);
dynamic i = lineVertices.GetEnumerator();
while (i.MoveNext())
{
manualObject.Position(i.Current.Key);
manualObject.Colour(i.Current.Value);
}
i.Dispose();
LinkedList<int>.Enumerator i2 = lineIndices.GetEnumerator();
while (i2.MoveNext())
{
manualObject.Index((uint)i2.Current);
}
i2.Dispose();
manualObject.End();

}

if (triangleVertices.Count > 0)
{
manualObject.BeginUpdate(1);
manualObject.EstimateVertexCount((uint)triangleVertices.Count + 1);
manualObject.EstimateIndexCount((uint)triangleIndices.Count + 1);
dynamic i = triangleVertices.GetEnumerator();
while (i.MoveNext())
{
manualObject.Position(i.Current.Key);
manualObject.Colour(i.Current.Value.r, i.Current.Value.g, i.Current.Value.b, fillAlpha);
}
i.Dispose();
LinkedList<int>.Enumerator i2 = triangleIndices.GetEnumerator();
while (i2.MoveNext())
{
manualObject.Index((uint)i2.Current);
}
i2.Dispose();
manualObject.End();
}
}
public void Clear()
{
lineVertices.Clear();
triangleVertices.Clear();
lineIndices.Clear();
triangleIndices.Clear();
trianglesIndex = 0;
linesIndex = trianglesIndex;
}
public int AddLineVertex(Vector3 vertex, ColourValue colour)
{
lineVertices.AddLast(new KeyValuePair<Vector3, ColourValue>(vertex, colour));

linesIndex += 1;
return linesIndex - 1;
}
public void AddLineIndices(int index1, int index2)
{
lineIndices.AddLast(index1);
lineIndices.AddLast(index2);
}
public int AddTriangleVertex(Vector3 vertex, ColourValue colour)
{
triangleVertices.AddLast(new KeyValuePair<Vector3, ColourValue>(vertex, colour));

trianglesIndex += 1;
return trianglesIndex - 1;
}
public void AddTriangleIndices(int index1, int index2, int index3)
{
triangleIndices.AddLast(index1);
triangleIndices.AddLast(index2);
triangleIndices.AddLast(index3);
}
public void AddQuadIndices(int index1, int index2, int index3, int index4)
{
triangleIndices.AddLast(index1);
triangleIndices.AddLast(index2);
triangleIndices.AddLast(index3);

triangleIndices.AddLast(index1);
triangleIndices.AddLast(index3);
triangleIndices.AddLast(index4);
}

#region "IDisposable Support"
// So ermitteln Sie überflüssige Aufrufe
private bool disposedValue;

// IDisposable
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
// TODO: Verwalteten Zustand löschen (verwaltete Objekte).
}
Shutdown();
// TODO: Nicht verwaltete Ressourcen (nicht verwaltete Objekte) freigeben und Finalize() unten überschreiben.
// TODO: Große Felder auf NULL festlegen.
}
this.disposedValue = true;
}

// TODO: Finalize() nur überschreiben, wenn Dispose(ByVal disposing As Boolean) oben über Code zum Freigeben von nicht verwalteten Ressourcen verfügt.
//Protected Overrides Sub Finalize()
// ' Ändern Sie diesen Code nicht. Fügen Sie oben in Dispose(ByVal disposing As Boolean) Bereinigungscode ein.
// Dispose(False)
// MyBase.Finalize()
//End Sub

// Dieser Code wird von Visual Basic hinzugefügt, um das Dispose-Muster richtig zu implementieren.
public void Dispose()
{
// Ändern Sie diesen Code nicht. Fügen Sie oben in Dispose(ByVal disposing As Boolean) Bereinigungscode ein.
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion

}

Tubulii

19-07-2011 15:12:28

Thanks for converting. I guess most of the people in this forum uses C#, and converting c#<-> VB.Net is always annoying :D.

Soon the port will be part of the official repository (my conversion in this forum is already outdated). Maybe I release .dll for 'qick and dirty'-integrating. Take a look at the repository in the next days for the latest version.

Beauty

20-07-2011 00:18:05

There are different converters. So perhaps there is one which convert it without problems.

The C# code we also could add to the repository. (Although this increased the maintain effort.)
If you/we always create the C# version by converter, we should add a note with a date to the top. Then a user can see if it's the current state.

For both, the VS and the C# version we could add a tiny history at the top of the code. It's also fine to see the state of the art.

Maybe I release .dll for 'qick and dirty'-integrating.
I think this is no good idea, because it works only for that version of Mogre, which is used for compiling. I'm not shure, but maybe there is even a difference for Mogre 1.7.1 and 1.7.2 binaries.
For common C# projects it's also available to integrate VS files as code.

Tubulii

20-07-2011 11:21:53

I have now access to the rep and added the port (both c#(untested) and VB.Net). Most of the conversion errors are 'can't convert int to unit' (...). A few changes in the Vb.net code should fix these problems in further versions. Until now I only converted the code and then fixed it.

I updated my first post. The source code is now on bitbucket.

Aralox

15-01-2012 01:20:47

Thanks for porting this to .NET, its awesome!
I found a few errors: floats need to have 'f' at the end, and there is an ambiguity between System.Math and Mogre.Math,
so I just put in "using Math = Mogre.Math" at the top.

Also, it would be great if the instructions to get it working were put on the wiki, just for completeness (rather than people having to check here to find out how to use it)

Thanks again,
Aralox

Tubulii

15-01-2012 14:02:43

floats need to have 'f' at the end, and there is an ambiguity between System.Math and Mogre.Math,
Oh, yes, you are right.

Also, it would be great if the instructions to get it working were put on the wiki, just for completeness (rather than people having to check here to find out how to use it)

There are instructions in the original wiki article and in the first (now updated) post.