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
}