2013-10-11 01:58:54 +02:00
|
|
|
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] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|