public static void GetArray( ref List<Chunk> c, out VertexT2dN3dV3d[] vbo, out uint[] ibo ) { uint VertexCounter = 0; uint IndexCounter = 0; foreach ( Chunk ch in c ) { VertexCounter += ch.VertexCount; IndexCounter += ch.IndexCount; } vbo = new VertexT2dN3dV3d[VertexCounter]; ibo = new uint[IndexCounter]; VertexCounter = 0; IndexCounter = 0; foreach ( Chunk ch in c ) { for ( int i = 0; i < ch.Vertices.Length; i++ ) { vbo[VertexCounter + i] = ch.Vertices[i]; } for ( int i = 0; i < ch.Indices.Length; i++ ) { ibo[IndexCounter + i] = ch.Indices[i] + VertexCounter; } VertexCounter += (uint)ch.VertexCount; IndexCounter += (uint)ch.IndexCount; } }
public static void GetArray(ref List <Chunk> c, out VertexT2dN3dV3d[] vbo, out uint[] ibo) { uint VertexCounter = 0; uint IndexCounter = 0; foreach (Chunk ch in c) { VertexCounter += ch.VertexCount; IndexCounter += ch.IndexCount; } vbo = new VertexT2dN3dV3d[VertexCounter]; ibo = new uint[IndexCounter]; VertexCounter = 0; IndexCounter = 0; foreach (Chunk ch in c) { for (int i = 0; i < ch.Vertices.Length; i++) { vbo[VertexCounter + i] = ch.Vertices[i]; } for (int i = 0; i < ch.Indices.Length; i++) { ibo[IndexCounter + i] = ch.Indices[i] + VertexCounter; } VertexCounter += (uint)ch.VertexCount; IndexCounter += (uint)ch.IndexCount; } }
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 OpenTK.Vector2d(0.5, 1.0), Vector3d.UnitY, Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.0, 0.0), Vector3d.UnitZ, Vector3d.UnitZ * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 0.0), Vector3d.UnitX, Vector3d.UnitX * scale); break; case eDir.FrontBottomRight: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 0.0), Vector3d.UnitX, Vector3d.UnitX * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.0, 0.0), Vector3d.UnitZ, Vector3d.UnitZ * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), -Vector3d.UnitY, -Vector3d.UnitY * scale); break; case eDir.FrontBottomLeft: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 0.0), Vector3d.UnitX, Vector3d.UnitX * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), -Vector3d.UnitY, -Vector3d.UnitY * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(1.0, 0.0), -Vector3d.UnitZ, -Vector3d.UnitZ * scale); break; case eDir.FrontTopLeft: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(1.0, 0.0), -Vector3d.UnitZ, -Vector3d.UnitZ * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), Vector3d.UnitY, Vector3d.UnitY * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 0.0), Vector3d.UnitX, Vector3d.UnitX * scale); break; case eDir.BackTopRight: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), Vector3d.UnitY, Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.0, 1.0), -Vector3d.UnitX, -Vector3d.UnitX * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.0, 0.0), Vector3d.UnitZ, Vector3d.UnitZ * scale); break; case eDir.BackBottomRight: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), -Vector3d.UnitY, -Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.0, 0.0), Vector3d.UnitZ, Vector3d.UnitZ * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.0, 1.0), -Vector3d.UnitX, -Vector3d.UnitX * scale); break; case eDir.BackBottomLeft: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), -Vector3d.UnitY, -Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(1.0, 1.0), -Vector3d.UnitX, -Vector3d.UnitX * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(1.0, 0.0), -Vector3d.UnitZ, -Vector3d.UnitZ * scale); break; case eDir.BackTopLeft: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), Vector3d.UnitY, Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(1.0, 0.0), -Vector3d.UnitZ, -Vector3d.UnitZ * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(1.0, 1.0), -Vector3d.UnitX, -Vector3d.UnitX * scale); break; } first = t1; second = t2; third = t3; }
internal static void GetVertexArray( ref TetrahedronFace[] input, out VertexT2dN3dV3d[] output ) { output = new VertexT2dN3dV3d[input.Length * 3]; int counter = 0; for ( int i = 0; i < input.Length; i++ ) { input[i].GetVertices( out output[counter + 0], out output[counter + 1], out output[counter + 2] ); counter += 3; } }
internal static void GetVertexArray(ref TetrahedronFace[] input, out VertexT2dN3dV3d[] output) { output = new VertexT2dN3dV3d[input.Length * 3]; int counter = 0; for (int i = 0; i < input.Length; i++) { input[i].GetVertices(out output[counter + 0], out output[counter + 1], out output[counter + 2]); counter += 3; } }
public Chunk( ref VertexT2dN3dV3d[] vbo, ref uint[] ibo ) { Vertices = new VertexT2dN3dV3d[vbo.Length]; for ( int i = 0; i < Vertices.Length; i++ ) { Vertices[i] = vbo[i]; } Indices = new uint[ibo.Length]; for ( int i = 0; i < Indices.Length; i++ ) { Indices[i] = ibo[i]; } }
public void GetArraysforVBO(out BeginMode primitives, out VertexT2dN3dV3d[] vertices, out uint[] indices) { primitives = PrimitiveMode; vertices = new VertexT2dN3dV3d[VertexArray.Length]; for (uint i = 0; i < VertexArray.Length; i++) { vertices[i].TexCoord = VertexArray[i].TexCoord; vertices[i].Normal = VertexArray[i].Normal; vertices[i].Position = VertexArray[i].Position; } indices = IndexArray; }
/// <summary>Returns 3 Vertices which form a CCW triangle.</summary> public void GetVertices(out VertexT2dN3dV3d first, out VertexT2dN3dV3d second, out VertexT2dN3dV3d third) { first.TexCoord = this.ATexCoord; first.Normal = this.Normal; first.Position = this.APosition; second.TexCoord = this.BTexCoord; second.Normal = this.Normal; second.Position = this.BPosition; third.TexCoord = this.CTexCoord; third.Normal = this.Normal; third.Position = this.CPosition; }
public VboShape(ref OpenTK.Graphics.OpenGL.BeginMode primitives, ref VertexT2dN3dV3d[] vertices, ref uint[] indices) : base( ) { PrimitiveMode = primitives; VertexArray = new VertexT2dN3dV3d[vertices.Length]; for (uint i = 0; i < vertices.Length; i++) { VertexArray[i] = vertices[i]; } IndexArray = new uint[indices.Length]; for (uint i = 0; i < indices.Length; i++) { IndexArray[i] = indices[i]; } }
public VboShape( ref OpenTK.Graphics.OpenGL.BeginMode primitives, ref VertexT2dN3dV3d[] vertices, ref uint[] indices ) : base( ) { PrimitiveMode = primitives; VertexArray = new VertexT2dN3dV3d[vertices.Length]; for ( uint i = 0; i < vertices.Length; i++ ) { VertexArray[i] = vertices[i]; } IndexArray = new uint[indices.Length]; for ( uint i = 0; i < indices.Length; i++ ) { IndexArray[i] = indices[i]; } }
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; OpenTK.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; OpenTK.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; OpenTK.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 }
public TorusKnot( int pathsteps, int shapevertices, double radius, int p, int q, int TexCount ) : base( ) { Trace.Assert( pathsteps >= MINPathSteps, "A Path must have at least " + MINPathSteps + " Steps to form a volume." ); Trace.Assert( shapevertices >= MINShapeVertices, "A Shape must contain at least " + MINShapeVertices + " Vertices to be considered valid and create a volume." ); Trace.Assert( TexCount > 1, "at least 1 Texture set is required." ); PrimitiveMode = OpenTK.Graphics.OpenGL.BeginMode.TriangleStrip; Vector3d[] PathPositions = new Vector3d[pathsteps]; #region Find the center Points for each step on the path for ( int i = 0; i < pathsteps; i++ ) { double Angle = ( i / (double)pathsteps ) * TwoPi; double AngleTimesP = Angle * p; double AngleTimesQ = Angle * q; double r = ( 0.5 * ( 2.0 + System.Math.Sin( AngleTimesQ ) ) ); PathPositions[i] = new Vector3d( ( r * System.Math.Cos( AngleTimesP ) ), ( r * System.Math.Cos( AngleTimesQ ) ), ( r * System.Math.Sin( AngleTimesP ) ) ); } #endregion Find the center Points for each step on the path #region Find the Torus length Vector3d result; double[] Lengths = new double[pathsteps]; Vector3d.Subtract( ref PathPositions[pathsteps - 1], ref PathPositions[0], out result ); Lengths[0] = result.Length; double TotalLength = result.Length; for ( int i = 1; i < pathsteps; i++ ) // skipping { Vector3d.Subtract( ref PathPositions[i - 1], ref PathPositions[i], out result ); Lengths[i] = result.Length; TotalLength += result.Length; } Trace.WriteLine( "the TorusKnot's length is: " + TotalLength + " " ); #endregion Find the Torus length VertexArray = new VertexT2dN3dV3d[pathsteps * shapevertices]; #region Loft a circle Shape along the path double TwoPiThroughVert = TwoPi / shapevertices; // precalc for reuse for ( uint i = 0; i < pathsteps; i++ ) { Vector3d last, next, normal, tangent; if ( i == pathsteps - 1 ) next = PathPositions[0]; else next = PathPositions[i + 1]; if ( i == 0 ) last = PathPositions[pathsteps - 1]; else last = PathPositions[i - 1]; Vector3d.Subtract( ref next, ref last, out tangent ); // Guesstimate tangent tangent.Normalize(); Vector3d.Add( ref next, ref last, out normal ); // Approximate N normal.Normalize(); Vector3d.Multiply( ref normal, radius, out normal );// scale the shape to desired radius for ( uint j = 0; j < shapevertices; j++ ) { uint index = i * (uint)shapevertices + j; // Create a point on the plane and rotate it OpenTK.Matrix4d RotationMatrix = OpenTK.Matrix4d.Rotate(tangent, -(j * TwoPiThroughVert)); OpenTK.Vector3d point = OpenTK.Vector3d.TransformVector(normal, RotationMatrix); OpenTK.Vector3d.Add(ref PathPositions[i], ref point, out VertexArray[index].Position); // Since the used shape is a circle, the Vertex normal's heading is easy to find OpenTK.Vector3d.Subtract(ref VertexArray[index].Position, ref PathPositions[i], out VertexArray[index].Normal); VertexArray[index].Normal.Normalize(); // just generate some semi-useful UVs to fill blanks VertexArray[index].TexCoord = new OpenTK.Vector2d((double)(i / TotalLength / TexCount), j / (shapevertices - 1.0)); } } #endregion Loft a circle Shape along the path PathPositions = null; // not needed anymore uint currentindex = 0; #region Build a Triangle strip from the Vertices IndexArray = new uint[pathsteps * ( shapevertices * 2 + 2 )]; // 2 triangles per vertex, +2 due to added degenerate triangles for ( uint i = 0; i < pathsteps; i++ ) { uint RowCurrent = i * (uint)shapevertices; uint RowBelow; if ( i == pathsteps - 1 ) RowBelow = 0; // for the last row, the first row is the following else RowBelow = ( i + 1 ) * (uint)shapevertices; // new ring begins here for ( uint j = 0; j < shapevertices; j++ ) { IndexArray[currentindex++] = RowCurrent + j; IndexArray[currentindex++] = RowBelow + j; } // ring ends here, repeat first 2 vertices to insert 2 degenerate triangles to reach following ring IndexArray[currentindex++] = RowCurrent; IndexArray[currentindex++] = RowBelow; } #endregion Build a Triangle strip from the Vertices }
public SlicedHose(eSide side, uint subdivs, double scale, Vector3d offset1, Vector3d offset2) : base( ) { PrimitiveMode = OpenTK.Graphics.OpenGL.BeginMode.Triangles; Vector3d start = Vector3d.Zero, end = Vector3d.Zero; double TexCoordStart = 0f, TexCoordEnd = 0f; switch (side) { #region Around X Axis case eSide.BottomRight: start = -Vector3d.UnitY; end = Vector3d.UnitZ; TexCoordStart = 0.0; TexCoordEnd = 0.25; break; case eSide.TopRight: start = Vector3d.UnitZ; end = Vector3d.UnitY; TexCoordStart = 0.25; TexCoordEnd = 0.5; break; case eSide.TopLeft: start = Vector3d.UnitY; end = -Vector3d.UnitZ; TexCoordStart = 0.5; TexCoordEnd = 0.75; break; case eSide.BottomLeft: start = -Vector3d.UnitZ; end = -Vector3d.UnitY; TexCoordStart = 0.75; TexCoordEnd = 1.0; break; #endregion Around X Axis #region Around Y Axis case eSide.FrontRight: start = Vector3d.UnitX; end = Vector3d.UnitZ; TexCoordStart = 0.0; TexCoordEnd = 0.25; break; case eSide.BackRight: start = Vector3d.UnitZ; end = -Vector3d.UnitX; TexCoordStart = 0.25; TexCoordEnd = 0.5; break; case eSide.BackLeft: start = -Vector3d.UnitX; end = -Vector3d.UnitZ; TexCoordStart = 0.5; TexCoordEnd = 0.75; break; case eSide.FrontLeft: start = -Vector3d.UnitZ; end = Vector3d.UnitX; TexCoordStart = 0.75; TexCoordEnd = 1.0; break; #endregion Around Y Axis #region Around Z Axis case eSide.FrontBottom: start = -Vector3d.UnitY; end = Vector3d.UnitX; TexCoordStart = 0.0; TexCoordEnd = 0.25; break; case eSide.BackBottom: start = -Vector3d.UnitX; end = -Vector3d.UnitY; TexCoordStart = 0.25; TexCoordEnd = 0.5; break; case eSide.BackTop: start = Vector3d.UnitY; end = -Vector3d.UnitX; TexCoordStart = 0.5; TexCoordEnd = 0.75; break; case eSide.FrontTop: start = Vector3d.UnitX; end = Vector3d.UnitY; TexCoordStart = 0.75; TexCoordEnd = 1.0; break; #endregion Around Z Axis } VertexT2dN3dV3d[] temp = new VertexT2dN3dV3d[2 + subdivs]; double divisor = 1.0 / ((double)temp.Length - 1.0); for (int i = 0; i < temp.Length; i++) { float Multiplier = (float)(i * divisor); temp[i].TexCoord.X = TexCoordStart * Multiplier + TexCoordEnd * (1.0f - Multiplier); Slerp(ref start, ref end, Multiplier, out temp[i].Normal); temp[i].Normal.Normalize(); temp[i].Position = temp[i].Normal; temp[i].Position *= scale; } VertexArray = new VertexT2dN3dV3d[temp.Length * 2]; IndexArray = new uint[(temp.Length - 1) * 2 * 3]; uint VertexCounter = 0, IndexCounter = 0, QuadCounter = 0; for (int i = 0; i < temp.Length; i++) { VertexArray[VertexCounter + 0].TexCoord.X = temp[i].TexCoord.X; VertexArray[VertexCounter + 0].TexCoord.Y = 0.0; VertexArray[VertexCounter + 0].Normal = temp[i].Normal; VertexArray[VertexCounter + 0].Position = temp[i].Position + offset1; VertexArray[VertexCounter + 1].TexCoord.X = temp[i].TexCoord.X; VertexArray[VertexCounter + 1].TexCoord.Y = 1.0; VertexArray[VertexCounter + 1].Normal = temp[i].Normal; VertexArray[VertexCounter + 1].Position = temp[i].Position + offset2; VertexCounter += 2; if (i < temp.Length - 1) { IndexArray[IndexCounter + 0] = QuadCounter + 0; IndexArray[IndexCounter + 1] = QuadCounter + 1; IndexArray[IndexCounter + 2] = QuadCounter + 2; IndexArray[IndexCounter + 3] = QuadCounter + 2; IndexArray[IndexCounter + 4] = QuadCounter + 1; IndexArray[IndexCounter + 5] = QuadCounter + 3; IndexCounter += 6; QuadCounter += 2; } } }
/// <summary>Returns 3 Vertices which form a CCW triangle.</summary> public void GetVertices( out VertexT2dN3dV3d first, out VertexT2dN3dV3d second, out VertexT2dN3dV3d third ) { first.TexCoord = this.ATexCoord; first.Normal = this.Normal; first.Position = this.APosition; second.TexCoord = this.BTexCoord; second.Normal = this.Normal; second.Position = this.BPosition; third.TexCoord = this.CTexCoord; third.Normal = this.Normal; third.Position = this.CPosition; }
public SlicedHose( eSide side, uint subdivs, double scale, Vector3d offset1, Vector3d offset2 ) : base( ) { PrimitiveMode = OpenTK.Graphics.OpenGL.BeginMode.Triangles; Vector3d start = Vector3d.Zero, end = Vector3d.Zero; double TexCoordStart=0f, TexCoordEnd=0f; switch ( side ) { #region Around X Axis case eSide.BottomRight: start = -Vector3d.UnitY; end = Vector3d.UnitZ; TexCoordStart = 0.0; TexCoordEnd = 0.25; break; case eSide.TopRight: start = Vector3d.UnitZ; end = Vector3d.UnitY; TexCoordStart = 0.25; TexCoordEnd = 0.5; break; case eSide.TopLeft: start = Vector3d.UnitY; end = -Vector3d.UnitZ; TexCoordStart = 0.5; TexCoordEnd = 0.75; break; case eSide.BottomLeft: start = -Vector3d.UnitZ; end = -Vector3d.UnitY; TexCoordStart = 0.75; TexCoordEnd = 1.0; break; #endregion Around X Axis #region Around Y Axis case eSide.FrontRight: start = Vector3d.UnitX; end = Vector3d.UnitZ; TexCoordStart = 0.0; TexCoordEnd = 0.25; break; case eSide.BackRight: start = Vector3d.UnitZ; end = -Vector3d.UnitX; TexCoordStart = 0.25; TexCoordEnd = 0.5; break; case eSide.BackLeft: start = -Vector3d.UnitX; end = -Vector3d.UnitZ; TexCoordStart = 0.5; TexCoordEnd = 0.75; break; case eSide.FrontLeft: start = -Vector3d.UnitZ; end = Vector3d.UnitX; TexCoordStart = 0.75; TexCoordEnd = 1.0; break; #endregion Around Y Axis #region Around Z Axis case eSide.FrontBottom: start = -Vector3d.UnitY; end = Vector3d.UnitX; TexCoordStart = 0.0; TexCoordEnd = 0.25; break; case eSide.BackBottom: start = -Vector3d.UnitX; end = -Vector3d.UnitY; TexCoordStart = 0.25; TexCoordEnd = 0.5; break; case eSide.BackTop: start = Vector3d.UnitY; end = -Vector3d.UnitX; TexCoordStart = 0.5; TexCoordEnd = 0.75; break; case eSide.FrontTop: start = Vector3d.UnitX; end = Vector3d.UnitY; TexCoordStart = 0.75; TexCoordEnd = 1.0; break; #endregion Around Z Axis } VertexT2dN3dV3d[] temp = new VertexT2dN3dV3d[2 + subdivs]; double divisor = 1.0/ ((double)temp.Length-1.0); for ( int i = 0; i < temp.Length; i++ ) { float Multiplier = (float)( i * divisor ); temp[i].TexCoord.X = TexCoordStart * Multiplier + TexCoordEnd * ( 1.0f- Multiplier); Slerp( ref start, ref end, Multiplier, out temp[i].Normal ); temp[i].Normal.Normalize(); temp[i].Position = temp[i].Normal; temp[i].Position *= scale; } VertexArray = new VertexT2dN3dV3d[temp.Length * 2]; IndexArray = new uint[( temp.Length - 1 ) * 2 * 3]; uint VertexCounter = 0, IndexCounter = 0, QuadCounter = 0; for ( int i = 0; i < temp.Length; i++ ) { VertexArray[VertexCounter + 0].TexCoord.X = temp[i].TexCoord.X; VertexArray[VertexCounter + 0].TexCoord.Y = 0.0; VertexArray[VertexCounter + 0].Normal = temp[i].Normal; VertexArray[VertexCounter + 0].Position = temp[i].Position + offset1; VertexArray[VertexCounter + 1].TexCoord.X = temp[i].TexCoord.X; VertexArray[VertexCounter + 1].TexCoord.Y = 1.0; VertexArray[VertexCounter + 1].Normal = temp[i].Normal; VertexArray[VertexCounter + 1].Position = temp[i].Position + offset2; VertexCounter += 2; if ( i < temp.Length - 1 ) { IndexArray[IndexCounter + 0] = QuadCounter + 0; IndexArray[IndexCounter + 1] = QuadCounter + 1; IndexArray[IndexCounter + 2] = QuadCounter + 2; IndexArray[IndexCounter + 3] = QuadCounter + 2; IndexArray[IndexCounter + 4] = QuadCounter + 1; IndexArray[IndexCounter + 5] = QuadCounter + 3; IndexCounter += 6; QuadCounter += 2; } } }
public MengerSponge(double scale, eSubdivisions subdivs) : base( ) { 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 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 OpenTK.Vector2d(0.5, 1.0), Vector3d.UnitY, Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.0, 0.0), Vector3d.UnitZ, Vector3d.UnitZ * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 0.0), Vector3d.UnitX, Vector3d.UnitX * scale); break; case eDir.FrontBottomRight: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 0.0), Vector3d.UnitX, Vector3d.UnitX * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.0, 0.0), Vector3d.UnitZ, Vector3d.UnitZ * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), -Vector3d.UnitY, -Vector3d.UnitY * scale); break; case eDir.FrontBottomLeft: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 0.0), Vector3d.UnitX, Vector3d.UnitX * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), -Vector3d.UnitY, -Vector3d.UnitY * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(1.0, 0.0), -Vector3d.UnitZ, -Vector3d.UnitZ * scale); break; case eDir.FrontTopLeft: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(1.0, 0.0), -Vector3d.UnitZ, -Vector3d.UnitZ * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), Vector3d.UnitY, Vector3d.UnitY * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 0.0), Vector3d.UnitX, Vector3d.UnitX * scale); break; case eDir.BackTopRight: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), Vector3d.UnitY, Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.0, 1.0), -Vector3d.UnitX, -Vector3d.UnitX * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.0, 0.0), Vector3d.UnitZ, Vector3d.UnitZ * scale); break; case eDir.BackBottomRight: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), -Vector3d.UnitY, -Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.0, 0.0), Vector3d.UnitZ, Vector3d.UnitZ * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.0, 1.0), -Vector3d.UnitX, -Vector3d.UnitX * scale); break; case eDir.BackBottomLeft: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), -Vector3d.UnitY, -Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(1.0, 1.0), -Vector3d.UnitX, -Vector3d.UnitX * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(1.0, 0.0), -Vector3d.UnitZ, -Vector3d.UnitZ * scale); break; case eDir.BackTopLeft: t1 = new VertexT2dN3dV3d(new OpenTK.Vector2d(0.5, 1.0), Vector3d.UnitY, Vector3d.UnitY * scale); t2 = new VertexT2dN3dV3d(new OpenTK.Vector2d(1.0, 0.0), -Vector3d.UnitZ, -Vector3d.UnitZ * scale); t3 = new VertexT2dN3dV3d(new OpenTK.Vector2d(1.0, 1.0), -Vector3d.UnitX, -Vector3d.UnitX * scale); break; } first = t1; second = t2; third = t3; }
public SlicedSphere( double radius, Vector3d offset, eSubdivisions subdivs, eDir[] sides ) : base( ) { double Diameter = radius; PrimitiveMode = OpenTK.Graphics.OpenGL.BeginMode.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); } }
public ChamferCube(double Width, double Height, double Length, SubDivs subdivs, double radius) : base( ) { SlicedSphere.eSubdivisions sphereSubDivs = SlicedSphere.eSubdivisions.Zero; uint hoseSubDivs = 0; switch (subdivs) { case SubDivs.Zero: sphereSubDivs = SlicedSphere.eSubdivisions.Zero; hoseSubDivs = 0; break; case SubDivs.One: sphereSubDivs = SlicedSphere.eSubdivisions.One; hoseSubDivs = 1; break; case SubDivs.Two: sphereSubDivs = SlicedSphere.eSubdivisions.Two; hoseSubDivs = 3; break; case SubDivs.Three: sphereSubDivs = SlicedSphere.eSubdivisions.Three; hoseSubDivs = 7; break; case SubDivs.Four: sphereSubDivs = SlicedSphere.eSubdivisions.Four; hoseSubDivs = 15; break; } #region Temporary Storage List <Chunk> AllChunks = new List <Chunk>(); OpenTK.Graphics.OpenGL.BeginMode TemporaryMode; VertexT2dN3dV3d[] TemporaryVBO; uint[] TemporaryIBO; #endregion Temporary Storage Vector3d FrontTopRightEdge = new Vector3d(+Width - radius, +Height - radius, +Length - radius); Vector3d FrontTopLeftEdge = new Vector3d(+Width - radius, +Height - radius, -Length + radius); Vector3d FrontBottomRightEdge = new Vector3d(+Width - radius, -Height + radius, +Length - radius); Vector3d FrontBottomLeftEdge = new Vector3d(+Width - radius, -Height + radius, -Length + radius); Vector3d BackTopRightEdge = new Vector3d(-Width + radius, +Height - radius, +Length - radius); Vector3d BackTopLeftEdge = new Vector3d(-Width + radius, +Height - radius, -Length + radius); Vector3d BackBottomRightEdge = new Vector3d(-Width + radius, -Height + radius, +Length - radius); Vector3d BackBottomLeftEdge = new Vector3d(-Width + radius, -Height + radius, -Length + radius); #region 8 sliced Spheres SlicedSphere tempSphere; Vector3d tempVector = Vector3d.Zero; SlicedSphere.eDir[] tempEdge = new SlicedSphere.eDir[1]; for (int i = 0; i < 8; i++) { switch (i) { case 0: tempVector = FrontTopRightEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.FrontTopRight }; break; case 1: tempVector = FrontTopLeftEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.FrontTopLeft }; break; case 2: tempVector = FrontBottomRightEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.FrontBottomRight }; break; case 3: tempVector = FrontBottomLeftEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.FrontBottomLeft }; break; case 4: tempVector = BackBottomRightEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.BackBottomRight }; break; case 5: tempVector = BackBottomLeftEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.BackBottomLeft }; break; case 6: tempVector = BackTopRightEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.BackTopRight }; break; case 7: tempVector = BackTopLeftEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.BackTopLeft }; break; } tempSphere = new SlicedSphere(radius, tempVector, sphereSubDivs, tempEdge); tempSphere.GetArraysforVBO(out TemporaryMode, out TemporaryVBO, out TemporaryIBO); tempSphere.Dispose(); AllChunks.Add(new Chunk(ref TemporaryVBO, ref TemporaryIBO)); } #endregion 8 sliced Spheres #region 12 sliced Hoses SlicedHose tempHose; SlicedHose.eSide tempSide = SlicedHose.eSide.BackBottom; Vector3d tempHoseStart = Vector3d.Zero; Vector3d tempHoseEnd = Vector3d.Zero; for (int i = 0; i < 12; i++) { switch (i) { #region Around X Axis case 0: tempSide = SlicedHose.eSide.BottomRight; tempHoseStart = BackBottomRightEdge; tempHoseEnd = FrontBottomRightEdge; break; case 1: tempSide = SlicedHose.eSide.TopRight; tempHoseStart = BackTopRightEdge; tempHoseEnd = FrontTopRightEdge; break; case 2: tempSide = SlicedHose.eSide.TopLeft; tempHoseStart = BackTopLeftEdge; tempHoseEnd = FrontTopLeftEdge; break; case 3: tempSide = SlicedHose.eSide.BottomLeft; tempHoseStart = BackBottomLeftEdge; tempHoseEnd = FrontBottomLeftEdge; break; #endregion Around X Axis #region Around Y Axis case 4: tempSide = SlicedHose.eSide.FrontRight; tempHoseStart = FrontBottomRightEdge; tempHoseEnd = FrontTopRightEdge; break; case 5: tempSide = SlicedHose.eSide.BackRight; tempHoseStart = BackBottomRightEdge; tempHoseEnd = BackTopRightEdge; break; case 6: tempSide = SlicedHose.eSide.BackLeft; tempHoseStart = BackBottomLeftEdge; tempHoseEnd = BackTopLeftEdge; break; case 7: tempSide = SlicedHose.eSide.FrontLeft; tempHoseStart = FrontBottomLeftEdge; tempHoseEnd = FrontTopLeftEdge; break; #endregion Around Y Axis #region Around Z Axis case 8: tempSide = SlicedHose.eSide.FrontTop; tempHoseStart = FrontTopRightEdge; tempHoseEnd = FrontTopLeftEdge; break; case 9: tempSide = SlicedHose.eSide.BackTop; tempHoseStart = BackTopRightEdge; tempHoseEnd = BackTopLeftEdge; break; case 10: tempSide = SlicedHose.eSide.BackBottom; tempHoseStart = BackBottomRightEdge; tempHoseEnd = BackBottomLeftEdge; break; case 11: tempSide = SlicedHose.eSide.FrontBottom; tempHoseStart = FrontBottomRightEdge; tempHoseEnd = FrontBottomLeftEdge; break; #endregion Around Z Axis } tempHose = new SlicedHose(tempSide, hoseSubDivs, radius, tempHoseStart, tempHoseEnd); tempHose.GetArraysforVBO(out TemporaryMode, out TemporaryVBO, out TemporaryIBO); tempHose.Dispose(); AllChunks.Add(new Chunk(ref TemporaryVBO, ref TemporaryIBO)); } #endregion 12 sliced Hoses #region 6 quads for the sides VertexT2dN3dV3d[] tempVBO = new VertexT2dN3dV3d[4]; uint[] tempIBO = new uint[6] { 0, 1, 2, 0, 2, 3 }; // all quads share this IBO // all quads use the same texcoords tempVBO[0].TexCoord = new OpenTK.Vector2d(0.0, 1.0); tempVBO[1].TexCoord = new OpenTK.Vector2d(0.0, 0.0); tempVBO[2].TexCoord = new OpenTK.Vector2d(1.0, 0.0); tempVBO[3].TexCoord = new OpenTK.Vector2d(1.0, 1.0); // front face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = Vector3d.UnitX; tempVBO[0].Position = FrontTopRightEdge + new Vector3d(radius, 0.0, 0.0); tempVBO[1].Position = FrontBottomRightEdge + new Vector3d(radius, 0.0, 0.0); tempVBO[2].Position = FrontBottomLeftEdge + new Vector3d(radius, 0.0, 0.0); tempVBO[3].Position = FrontTopLeftEdge + new Vector3d(radius, 0.0, 0.0); AllChunks.Add(new Chunk(ref tempVBO, ref tempIBO)); // back face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = -Vector3d.UnitX; tempVBO[0].Position = BackTopLeftEdge - new Vector3d(radius, 0.0, 0.0); tempVBO[1].Position = BackBottomLeftEdge - new Vector3d(radius, 0.0, 0.0); tempVBO[2].Position = BackBottomRightEdge - new Vector3d(radius, 0.0, 0.0); tempVBO[3].Position = BackTopRightEdge - new Vector3d(radius, 0.0, 0.0); AllChunks.Add(new Chunk(ref tempVBO, ref tempIBO)); // top face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = Vector3d.UnitY; tempVBO[0].Position = BackTopRightEdge + new Vector3d(0.0, radius, 0.0); tempVBO[1].Position = FrontTopRightEdge + new Vector3d(0.0, radius, 0.0); tempVBO[2].Position = FrontTopLeftEdge + new Vector3d(0.0, radius, 0.0); tempVBO[3].Position = BackTopLeftEdge + new Vector3d(0.0, radius, 0.0); AllChunks.Add(new Chunk(ref tempVBO, ref tempIBO)); // bottom face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = -Vector3d.UnitY; tempVBO[0].Position = BackBottomLeftEdge - new Vector3d(0.0, radius, 0.0); tempVBO[1].Position = FrontBottomLeftEdge - new Vector3d(0.0, radius, 0.0); tempVBO[2].Position = FrontBottomRightEdge - new Vector3d(0.0, radius, 0.0); tempVBO[3].Position = BackBottomRightEdge - new Vector3d(0.0, radius, 0.0); AllChunks.Add(new Chunk(ref tempVBO, ref tempIBO)); // right face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = Vector3d.UnitZ; tempVBO[0].Position = BackTopRightEdge + new Vector3d(0.0, 0.0, radius); tempVBO[1].Position = BackBottomRightEdge + new Vector3d(0.0, 0.0, radius); tempVBO[2].Position = FrontBottomRightEdge + new Vector3d(0.0, 0.0, radius); tempVBO[3].Position = FrontTopRightEdge + new Vector3d(0.0, 0.0, radius); AllChunks.Add(new Chunk(ref tempVBO, ref tempIBO)); // left face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = -Vector3d.UnitZ; tempVBO[0].Position = FrontTopLeftEdge - new Vector3d(0.0, 0.0, radius); tempVBO[1].Position = FrontBottomLeftEdge - new Vector3d(0.0, 0.0, radius); tempVBO[2].Position = BackBottomLeftEdge - new Vector3d(0.0, 0.0, radius); tempVBO[3].Position = BackTopLeftEdge - new Vector3d(0.0, 0.0, radius); AllChunks.Add(new Chunk(ref tempVBO, ref tempIBO)); #endregion 6 quads for the sides #region Final Assembly of Chunks PrimitiveMode = OpenTK.Graphics.OpenGL.BeginMode.Triangles; Chunk.GetArray(ref AllChunks, out VertexArray, out IndexArray); AllChunks.Clear(); #endregion Final Assembly of Chunks }
public ChamferCube( double Width, double Height, double Length, SubDivs subdivs, double radius ) : base( ) { SlicedSphere.eSubdivisions sphereSubDivs = SlicedSphere.eSubdivisions.Zero; uint hoseSubDivs = 0; switch ( subdivs ) { case SubDivs.Zero: sphereSubDivs = SlicedSphere.eSubdivisions.Zero; hoseSubDivs = 0; break; case SubDivs.One: sphereSubDivs = SlicedSphere.eSubdivisions.One; hoseSubDivs = 1; break; case SubDivs.Two: sphereSubDivs = SlicedSphere.eSubdivisions.Two; hoseSubDivs = 3; break; case SubDivs.Three: sphereSubDivs = SlicedSphere.eSubdivisions.Three; hoseSubDivs = 7; break; case SubDivs.Four: sphereSubDivs = SlicedSphere.eSubdivisions.Four; hoseSubDivs = 15; break; } #region Temporary Storage List<Chunk> AllChunks = new List<Chunk>(); OpenTK.Graphics.OpenGL.BeginMode TemporaryMode; VertexT2dN3dV3d[] TemporaryVBO; uint[] TemporaryIBO; #endregion Temporary Storage Vector3d FrontTopRightEdge = new Vector3d( +Width - radius, +Height - radius, +Length - radius ); Vector3d FrontTopLeftEdge = new Vector3d( +Width - radius, +Height - radius, -Length + radius ); Vector3d FrontBottomRightEdge = new Vector3d( +Width - radius, -Height + radius, +Length - radius ); Vector3d FrontBottomLeftEdge = new Vector3d( +Width - radius, -Height + radius, -Length + radius ); Vector3d BackTopRightEdge = new Vector3d( -Width + radius, +Height - radius, +Length - radius ); Vector3d BackTopLeftEdge = new Vector3d( -Width + radius, +Height - radius, -Length + radius ); Vector3d BackBottomRightEdge = new Vector3d( -Width + radius, -Height + radius, +Length - radius ); Vector3d BackBottomLeftEdge = new Vector3d( -Width + radius, -Height + radius, -Length + radius ); #region 8 sliced Spheres SlicedSphere tempSphere; Vector3d tempVector = Vector3d.Zero; SlicedSphere.eDir[] tempEdge = new SlicedSphere.eDir[1]; for ( int i = 0; i < 8; i++ ) { switch ( i ) { case 0: tempVector = FrontTopRightEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.FrontTopRight }; break; case 1: tempVector = FrontTopLeftEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.FrontTopLeft }; break; case 2: tempVector = FrontBottomRightEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.FrontBottomRight }; break; case 3: tempVector = FrontBottomLeftEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.FrontBottomLeft }; break; case 4: tempVector = BackBottomRightEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.BackBottomRight }; break; case 5: tempVector = BackBottomLeftEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.BackBottomLeft }; break; case 6: tempVector = BackTopRightEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.BackTopRight }; break; case 7: tempVector = BackTopLeftEdge; tempEdge = new SlicedSphere.eDir[] { SlicedSphere.eDir.BackTopLeft }; break; } tempSphere = new SlicedSphere( radius, tempVector, sphereSubDivs, tempEdge ); tempSphere.GetArraysforVBO( out TemporaryMode, out TemporaryVBO, out TemporaryIBO ); tempSphere.Dispose(); AllChunks.Add( new Chunk( ref TemporaryVBO, ref TemporaryIBO ) ); } #endregion 8 sliced Spheres #region 12 sliced Hoses SlicedHose tempHose; SlicedHose.eSide tempSide = SlicedHose.eSide.BackBottom; Vector3d tempHoseStart = Vector3d.Zero; Vector3d tempHoseEnd = Vector3d.Zero; for ( int i = 0; i < 12; i++ ) { switch ( i ) { #region Around X Axis case 0: tempSide = SlicedHose.eSide.BottomRight; tempHoseStart = BackBottomRightEdge; tempHoseEnd = FrontBottomRightEdge; break; case 1: tempSide = SlicedHose.eSide.TopRight; tempHoseStart = BackTopRightEdge; tempHoseEnd = FrontTopRightEdge; break; case 2: tempSide = SlicedHose.eSide.TopLeft; tempHoseStart = BackTopLeftEdge; tempHoseEnd = FrontTopLeftEdge; break; case 3: tempSide = SlicedHose.eSide.BottomLeft; tempHoseStart = BackBottomLeftEdge; tempHoseEnd = FrontBottomLeftEdge; break; #endregion Around X Axis #region Around Y Axis case 4: tempSide = SlicedHose.eSide.FrontRight; tempHoseStart = FrontBottomRightEdge; tempHoseEnd = FrontTopRightEdge; break; case 5: tempSide = SlicedHose.eSide.BackRight; tempHoseStart = BackBottomRightEdge; tempHoseEnd = BackTopRightEdge; break; case 6: tempSide = SlicedHose.eSide.BackLeft; tempHoseStart = BackBottomLeftEdge; tempHoseEnd = BackTopLeftEdge; break; case 7: tempSide = SlicedHose.eSide.FrontLeft; tempHoseStart = FrontBottomLeftEdge; tempHoseEnd = FrontTopLeftEdge; break; #endregion Around Y Axis #region Around Z Axis case 8: tempSide = SlicedHose.eSide.FrontTop; tempHoseStart = FrontTopRightEdge; tempHoseEnd = FrontTopLeftEdge; break; case 9: tempSide = SlicedHose.eSide.BackTop; tempHoseStart = BackTopRightEdge; tempHoseEnd = BackTopLeftEdge; break; case 10: tempSide = SlicedHose.eSide.BackBottom; tempHoseStart = BackBottomRightEdge; tempHoseEnd = BackBottomLeftEdge; break; case 11: tempSide = SlicedHose.eSide.FrontBottom; tempHoseStart = FrontBottomRightEdge; tempHoseEnd = FrontBottomLeftEdge; break; #endregion Around Z Axis } tempHose = new SlicedHose( tempSide, hoseSubDivs, radius, tempHoseStart, tempHoseEnd ); tempHose.GetArraysforVBO( out TemporaryMode, out TemporaryVBO, out TemporaryIBO ); tempHose.Dispose(); AllChunks.Add( new Chunk( ref TemporaryVBO, ref TemporaryIBO ) ); } #endregion 12 sliced Hoses #region 6 quads for the sides VertexT2dN3dV3d[] tempVBO = new VertexT2dN3dV3d[4]; uint[] tempIBO = new uint[6] { 0, 1, 2, 0, 2, 3 }; // all quads share this IBO // all quads use the same texcoords tempVBO[0].TexCoord = new OpenTK.Vector2d(0.0, 1.0); tempVBO[1].TexCoord = new OpenTK.Vector2d(0.0, 0.0); tempVBO[2].TexCoord = new OpenTK.Vector2d(1.0, 0.0); tempVBO[3].TexCoord = new OpenTK.Vector2d(1.0, 1.0); // front face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = Vector3d.UnitX; tempVBO[0].Position = FrontTopRightEdge + new Vector3d( radius, 0.0, 0.0 ); tempVBO[1].Position = FrontBottomRightEdge + new Vector3d( radius, 0.0, 0.0 ); tempVBO[2].Position = FrontBottomLeftEdge + new Vector3d( radius, 0.0, 0.0 ); tempVBO[3].Position = FrontTopLeftEdge + new Vector3d( radius, 0.0, 0.0 ); AllChunks.Add( new Chunk( ref tempVBO, ref tempIBO ) ); // back face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = -Vector3d.UnitX; tempVBO[0].Position = BackTopLeftEdge - new Vector3d( radius, 0.0, 0.0 ); tempVBO[1].Position = BackBottomLeftEdge - new Vector3d( radius, 0.0, 0.0 ); tempVBO[2].Position = BackBottomRightEdge - new Vector3d( radius, 0.0, 0.0 ); tempVBO[3].Position = BackTopRightEdge - new Vector3d( radius, 0.0, 0.0 ); AllChunks.Add( new Chunk( ref tempVBO, ref tempIBO ) ); // top face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = Vector3d.UnitY; tempVBO[0].Position = BackTopRightEdge + new Vector3d( 0.0, radius, 0.0 ); tempVBO[1].Position = FrontTopRightEdge + new Vector3d( 0.0, radius, 0.0 ); tempVBO[2].Position = FrontTopLeftEdge + new Vector3d( 0.0, radius, 0.0 ); tempVBO[3].Position = BackTopLeftEdge + new Vector3d( 0.0, radius, 0.0 ); AllChunks.Add( new Chunk( ref tempVBO, ref tempIBO ) ); // bottom face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = -Vector3d.UnitY; tempVBO[0].Position = BackBottomLeftEdge - new Vector3d( 0.0, radius, 0.0 ); tempVBO[1].Position = FrontBottomLeftEdge - new Vector3d( 0.0, radius, 0.0 ); tempVBO[2].Position = FrontBottomRightEdge - new Vector3d( 0.0, radius, 0.0 ); tempVBO[3].Position = BackBottomRightEdge - new Vector3d( 0.0, radius, 0.0 ); AllChunks.Add( new Chunk( ref tempVBO, ref tempIBO ) ); // right face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = Vector3d.UnitZ; tempVBO[0].Position = BackTopRightEdge + new Vector3d( 0.0, 0.0, radius ); tempVBO[1].Position = BackBottomRightEdge + new Vector3d( 0.0, 0.0, radius ); tempVBO[2].Position = FrontBottomRightEdge + new Vector3d( 0.0, 0.0, radius ); tempVBO[3].Position = FrontTopRightEdge + new Vector3d( 0.0, 0.0, radius ); AllChunks.Add( new Chunk( ref tempVBO, ref tempIBO ) ); // left face tempVBO[0].Normal = tempVBO[1].Normal = tempVBO[2].Normal = tempVBO[3].Normal = -Vector3d.UnitZ; tempVBO[0].Position = FrontTopLeftEdge - new Vector3d( 0.0, 0.0, radius ); tempVBO[1].Position = FrontBottomLeftEdge - new Vector3d( 0.0, 0.0, radius ); tempVBO[2].Position = BackBottomLeftEdge - new Vector3d( 0.0, 0.0, radius ); tempVBO[3].Position = BackTopLeftEdge - new Vector3d( 0.0, 0.0, radius ); AllChunks.Add( new Chunk( ref tempVBO, ref tempIBO ) ); #endregion 6 quads for the sides #region Final Assembly of Chunks PrimitiveMode = OpenTK.Graphics.OpenGL.BeginMode.Triangles; Chunk.GetArray( ref AllChunks, out VertexArray, out IndexArray ); AllChunks.Clear(); #endregion Final Assembly of Chunks }
public SlicedSphere(double radius, Vector3d offset, eSubdivisions subdivs, eDir[] sides) : base( ) { double Diameter = radius; PrimitiveMode = OpenTK.Graphics.OpenGL.BeginMode.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); } }
public MengerSponge( double scale, eSubdivisions subdivs ) : base( ) { 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(); }
public TorusKnot(int pathsteps, int shapevertices, double radius, int p, int q, int TexCount) : base( ) { Trace.Assert(pathsteps >= MINPathSteps, "A Path must have at least " + MINPathSteps + " Steps to form a volume."); Trace.Assert(shapevertices >= MINShapeVertices, "A Shape must contain at least " + MINShapeVertices + " Vertices to be considered valid and create a volume."); Trace.Assert(TexCount > 1, "at least 1 Texture set is required."); PrimitiveMode = OpenTK.Graphics.OpenGL.BeginMode.TriangleStrip; Vector3d[] PathPositions = new Vector3d[pathsteps]; #region Find the center Points for each step on the path for (int i = 0; i < pathsteps; i++) { double Angle = (i / (double)pathsteps) * TwoPi; double AngleTimesP = Angle * p; double AngleTimesQ = Angle * q; double r = (0.5 * (2.0 + System.Math.Sin(AngleTimesQ))); PathPositions[i] = new Vector3d((r * System.Math.Cos(AngleTimesP)), (r * System.Math.Cos(AngleTimesQ)), (r * System.Math.Sin(AngleTimesP))); } #endregion Find the center Points for each step on the path #region Find the Torus length Vector3d result; double[] Lengths = new double[pathsteps]; Vector3d.Subtract(ref PathPositions[pathsteps - 1], ref PathPositions[0], out result); Lengths[0] = result.Length; double TotalLength = result.Length; for (int i = 1; i < pathsteps; i++) // skipping { Vector3d.Subtract(ref PathPositions[i - 1], ref PathPositions[i], out result); Lengths[i] = result.Length; TotalLength += result.Length; } Trace.WriteLine("the TorusKnot's length is: " + TotalLength + " "); #endregion Find the Torus length VertexArray = new VertexT2dN3dV3d[pathsteps * shapevertices]; #region Loft a circle Shape along the path double TwoPiThroughVert = TwoPi / shapevertices; // precalc for reuse for (uint i = 0; i < pathsteps; i++) { Vector3d last, next, normal, tangent; if (i == pathsteps - 1) { next = PathPositions[0]; } else { next = PathPositions[i + 1]; } if (i == 0) { last = PathPositions[pathsteps - 1]; } else { last = PathPositions[i - 1]; } Vector3d.Subtract(ref next, ref last, out tangent); // Guesstimate tangent tangent.Normalize(); Vector3d.Add(ref next, ref last, out normal); // Approximate N normal.Normalize(); Vector3d.Multiply(ref normal, radius, out normal); // scale the shape to desired radius for (uint j = 0; j < shapevertices; j++) { uint index = i * (uint)shapevertices + j; // Create a point on the plane and rotate it OpenTK.Matrix4d RotationMatrix = OpenTK.Matrix4d.Rotate(tangent, -(j * TwoPiThroughVert)); OpenTK.Vector3d point = OpenTK.Vector3d.TransformVector(normal, RotationMatrix); OpenTK.Vector3d.Add(ref PathPositions[i], ref point, out VertexArray[index].Position); // Since the used shape is a circle, the Vertex normal's heading is easy to find OpenTK.Vector3d.Subtract(ref VertexArray[index].Position, ref PathPositions[i], out VertexArray[index].Normal); VertexArray[index].Normal.Normalize(); // just generate some semi-useful UVs to fill blanks VertexArray[index].TexCoord = new OpenTK.Vector2d((double)(i / TotalLength / TexCount), j / (shapevertices - 1.0)); } } #endregion Loft a circle Shape along the path PathPositions = null; // not needed anymore uint currentindex = 0; #region Build a Triangle strip from the Vertices IndexArray = new uint[pathsteps * (shapevertices * 2 + 2)]; // 2 triangles per vertex, +2 due to added degenerate triangles for (uint i = 0; i < pathsteps; i++) { uint RowCurrent = i * (uint)shapevertices; uint RowBelow; if (i == pathsteps - 1) { RowBelow = 0; // for the last row, the first row is the following } else { RowBelow = (i + 1) * (uint)shapevertices; } // new ring begins here for (uint j = 0; j < shapevertices; j++) { IndexArray[currentindex++] = RowCurrent + j; IndexArray[currentindex++] = RowBelow + j; } // ring ends here, repeat first 2 vertices to insert 2 degenerate triangles to reach following ring IndexArray[currentindex++] = RowCurrent; IndexArray[currentindex++] = RowBelow; } #endregion Build a Triangle strip from the Vertices }
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; OpenTK.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; OpenTK.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; OpenTK.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 }