using System; using System.Collections.Generic; using System.Text; using OpenTK; namespace Examples.Shapes { public sealed class SlicedSphere: DrawableShape { public enum eSubdivisions { Zero = 0, One = 1, Two = 2, Three = 3, Four = 4, Five=5, Six=6, Seven=7, Eight=8, } public enum eDir { All, FrontTopRight, FrontBottomRight, FrontBottomLeft, FrontTopLeft, BackTopRight, BackBottomRight, BackBottomLeft, BackTopLeft, } public SlicedSphere( double radius, Vector3d offset, eSubdivisions subdivs, eDir[] sides, bool useDL ) : base( useDL ) { double Diameter = radius; PrimitiveMode = OpenTK.Graphics.OpenGL.PrimitiveType.Triangles; if ( sides[0] == eDir.All ) { sides = new eDir[] { eDir.FrontTopRight, eDir.FrontBottomRight, eDir.FrontBottomLeft, eDir.FrontTopLeft, eDir.BackTopRight, eDir.BackBottomRight, eDir.BackBottomLeft, eDir.BackTopLeft,}; } VertexArray = new VertexT2dN3dV3d[sides.Length * 3]; IndexArray = new uint[sides.Length * 3]; uint counter = 0; foreach ( eDir s in sides ) { GetDefaultVertices( s, Diameter, out VertexArray[counter + 0], out VertexArray[counter + 1], out VertexArray[counter + 2] ); IndexArray[counter + 0] = counter + 0; IndexArray[counter + 1] = counter + 1; IndexArray[counter + 2] = counter + 2; counter += 3; } if ( subdivs != eSubdivisions.Zero ) { for ( int s = 0; s < (int)subdivs; s++ ) { #region Assemble Chunks and convert to Arrays List<Chunk> AllChunks = new List<Chunk>(); for ( uint i = 0; i < IndexArray.Length; i += 3 ) { Chunk chu; Subdivide( Diameter, ref VertexArray[IndexArray[i + 0]], ref VertexArray[IndexArray[i + 1]], ref VertexArray[IndexArray[i + 2]], out chu ); AllChunks.Add( chu ); } Chunk.GetArray( ref AllChunks, out VertexArray, out IndexArray ); AllChunks.Clear(); #endregion Assemble Chunks and convert to Arrays } } for (int i=0; i<VertexArray.Length;i++) { Vector3d.Add(ref VertexArray[i].Position, ref offset, out VertexArray[i].Position); } } private void GetDefaultVertices( eDir s, double scale, out VertexT2dN3dV3d first, out VertexT2dN3dV3d second, out VertexT2dN3dV3d third ) { VertexT2dN3dV3d t1 = new VertexT2dN3dV3d(), t2 = new VertexT2dN3dV3d(), t3 = new VertexT2dN3dV3d(); switch ( s ) { case eDir.FrontTopRight: t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), Vector3d.UnitY, Vector3d.UnitY * scale ); t2 = new VertexT2dN3dV3d( new Vector2d( 0.0, 0.0 ), Vector3d.UnitZ, Vector3d.UnitZ * scale ); t3 = new VertexT2dN3dV3d( new Vector2d( 0.5, 0.0 ), Vector3d.UnitX, Vector3d.UnitX * scale ); break; case eDir.FrontBottomRight: t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 0.0 ), Vector3d.UnitX, Vector3d.UnitX * scale ); t2 = new VertexT2dN3dV3d( new Vector2d( 0.0, 0.0 ), Vector3d.UnitZ, Vector3d.UnitZ * scale ); t3 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), -Vector3d.UnitY, -Vector3d.UnitY * scale ); break; case eDir.FrontBottomLeft: t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 0.0 ), Vector3d.UnitX, Vector3d.UnitX * scale ); t2 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), -Vector3d.UnitY, -Vector3d.UnitY * scale ); t3 = new VertexT2dN3dV3d( new Vector2d( 1.0, 0.0 ), -Vector3d.UnitZ, -Vector3d.UnitZ * scale ); break; case eDir.FrontTopLeft: t1 = new VertexT2dN3dV3d( new Vector2d( 1.0, 0.0 ), -Vector3d.UnitZ, -Vector3d.UnitZ * scale ); t2 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), Vector3d.UnitY, Vector3d.UnitY * scale ); t3 = new VertexT2dN3dV3d( new Vector2d( 0.5, 0.0 ), Vector3d.UnitX, Vector3d.UnitX * scale ); break; case eDir.BackTopRight: t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), Vector3d.UnitY, Vector3d.UnitY * scale ); t2 = new VertexT2dN3dV3d( new Vector2d( 0.0, 1.0 ), -Vector3d.UnitX, -Vector3d.UnitX * scale ); t3 = new VertexT2dN3dV3d( new Vector2d( 0.0, 0.0 ), Vector3d.UnitZ, Vector3d.UnitZ * scale ); break; case eDir.BackBottomRight: t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), -Vector3d.UnitY, -Vector3d.UnitY * scale ); t2 = new VertexT2dN3dV3d( new Vector2d( 0.0, 0.0 ), Vector3d.UnitZ, Vector3d.UnitZ * scale ); t3 = new VertexT2dN3dV3d( new Vector2d( 0.0, 1.0 ), -Vector3d.UnitX, -Vector3d.UnitX * scale ); break; case eDir.BackBottomLeft: t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), -Vector3d.UnitY, -Vector3d.UnitY * scale ); t2 = new VertexT2dN3dV3d( new Vector2d( 1.0, 1.0 ), -Vector3d.UnitX, -Vector3d.UnitX * scale ); t3 = new VertexT2dN3dV3d( new Vector2d( 1.0, 0.0 ), -Vector3d.UnitZ, -Vector3d.UnitZ * scale ); break; case eDir.BackTopLeft: t1 = new VertexT2dN3dV3d( new Vector2d( 0.5, 1.0 ), Vector3d.UnitY, Vector3d.UnitY * scale ); t2 = new VertexT2dN3dV3d( new Vector2d( 1.0, 0.0 ), -Vector3d.UnitZ, -Vector3d.UnitZ * scale ); t3 = new VertexT2dN3dV3d( new Vector2d( 1.0, 1.0 ), -Vector3d.UnitX, -Vector3d.UnitX * scale ); break; } first = t1; second = t2; third = t3; } private void Subdivide( double Scale, ref VertexT2dN3dV3d first, ref VertexT2dN3dV3d second, ref VertexT2dN3dV3d third, out Chunk c ) { c = new Chunk(6, 12); c.Vertices[0] = first; Vector3d.Lerp(ref first.Position, ref second.Position, 0.5,out c.Vertices[1].Normal ); c.Vertices[1].Normal.Normalize(); c.Vertices[1].Position = c.Vertices[1].Normal * Scale; Vector2d.Lerp( ref first.TexCoord, ref second.TexCoord, 0.5, out c.Vertices[1].TexCoord ); Vector3d.Lerp( ref third.Position, ref first.Position, 0.5, out c.Vertices[2].Normal ); c.Vertices[2].Normal.Normalize(); c.Vertices[2].Position = c.Vertices[2].Normal * Scale; Vector2d.Lerp( ref third.TexCoord, ref first.TexCoord, 0.5, out c.Vertices[2].TexCoord ); c.Vertices[3] = second; Vector3d.Lerp( ref second.Position, ref third.Position, 0.5, out c.Vertices[4].Normal ); c.Vertices[4].Normal.Normalize(); c.Vertices[4].Position = c.Vertices[4].Normal * Scale; Vector2d.Lerp( ref second.TexCoord, ref third.TexCoord, 0.5, out c.Vertices[4].TexCoord ); c.Vertices[5] = third; #region Indices c.Indices[0]=0; c.Indices[1]=1; c.Indices[2]=2; c.Indices[3]=2; c.Indices[4]=1; c.Indices[5]=4; c.Indices[6]=1; c.Indices[7]=3; c.Indices[8]=4; c.Indices[9]=2; c.Indices[10]=4; c.Indices[11]=5; #endregion Indices } } }