Opentk/Source/Examples/Shapes/MengerSponge.cs
2009-10-24 10:07:43 +00:00

117 lines
3.7 KiB
C#

using System;
using System.Collections.Generic;
using OpenTK;
namespace Examples.Shapes
{
public sealed partial class MengerSponge: DrawableShape
{
public enum eSubdivisions
{
None = 0,
One = 1,
Two = 2,
Three = 3,
}
public MengerSponge( double scale, eSubdivisions subdivs, bool useDL )
: base( useDL )
{
List<MengerCube> Cubes;
switch ( subdivs )
{
case eSubdivisions.None:
CreateDefaultMengerSponge( scale, out Cubes );
break;
case eSubdivisions.One:
case eSubdivisions.Two:
case eSubdivisions.Three:
CreateDefaultMengerSponge( scale, out Cubes );
for ( int i = 0; i < (int)subdivs; i++ )
{
List<MengerCube> temp;
SubdivideMengerSponge( ref Cubes, out temp );
Cubes = temp;
}
break;
default: throw new ArgumentOutOfRangeException( "Subdivisions other than contained in the enum cause overflows and are not allowed." );
}
PrimitiveMode = OpenTK.Graphics.OpenGL.BeginMode.Triangles;
#region Get Array Dimensions
uint
VertexCount = 0,
IndexCount = 0;
foreach ( MengerCube c in Cubes )
{
uint t1, t2;
c.GetArraySizes( out t1, out t2 );
VertexCount += t1;
IndexCount += t2;
}
VertexArray = new VertexT2dN3dV3d[VertexCount];
IndexArray = new uint[IndexCount];
#endregion Get Array Dimensions
List<Chunk> AllChunks = new List<Chunk>();
#region Build a temporary List of all loose pieces
foreach ( MengerCube c in Cubes )
{
c.GetVboAndIbo( ref AllChunks );
}
#endregion Build a temporary List of all loose pieces
#region Assemble pieces into a single VBO and IBO
VertexCount = 0;
IndexCount = 0;
foreach ( Chunk ch in AllChunks )
{
for ( int i = 0; i < ch.Vertices.Length; i++ )
{
VertexArray[VertexCount + i] = ch.Vertices[i];
}
for ( int i = 0; i < ch.Indices.Length; i++ )
{
IndexArray[IndexCount + i] = ch.Indices[i] + VertexCount;
}
VertexCount += (uint)ch.Vertices.Length;
IndexCount += (uint)ch.Indices.Length;
}
#endregion Assemble pieces into a single VBO and IBO
AllChunks.Clear();
}
private void CreateDefaultMengerSponge( double halfwidth, out List<MengerCube> output )
{
output = new List<MengerCube>( 1 );
output.Add( new MengerCube( Vector3d.Zero, halfwidth, MengerCube.AllSides, MengerCube.AllSides ) );
}
private void SubdivideMengerSponge( ref List<MengerCube> input, out List<MengerCube> output )
{
output = new List<MengerCube>( input.Count * 20 );
foreach ( MengerCube InputCube in input )
{
MengerCube[] SubdividedCubes;
InputCube.Subdivide( out SubdividedCubes );
for ( int i = 0; i < SubdividedCubes.Length; i++ )
{
output.Add( SubdividedCubes[i] );
}
}
}
}
}