예제 #1
0
        private static CustomMesh CreateTorus(float inner, float outer, int slices, int stacks)
        {
            if (slices < 5)
            {
                throw new ArgumentException("Cannot draw a torus with slices less than 5");
            }
            if (slices > 100)
            {
                throw new ArgumentException("Cannot draw a torus with slices greater than 100");
            }
            if (stacks < 5)
            {
                throw new ArgumentException("Cannot draw a torus with stacks less than 5");
            }
            if (stacks > 100)
            {
                throw new ArgumentException("Cannot draw a torus with stacks greater than 100");
            }
            if (inner < 0)
            {
                throw new ArgumentException("Inner radius has to be greater than or equal to 0");
            }
            if (outer <= 0)
            {
                throw new ArgumentException("Outer radius has to be greater than 0");
            }
            if (inner >= outer)
            {
                throw new ArgumentException("Inner radius has to be less than outer radius");
            }

            CustomMesh mesh = new CustomMesh();

            List <VertexPositionNormal> vertices = new List <VertexPositionNormal>();

            // Add the vertices
            double  thetaIncr = Math.PI * 2 / slices;
            double  thaiIncr = Math.PI * 2 / stacks;
            int     countA, countB = 0;
            double  theta, thai;
            float   c = (outer + inner) / 2;
            float   a = (outer - inner) / 2;
            double  common;
            Vector3 tubeCenter;

            for (countA = 0, theta = 0; countA < slices; theta += thetaIncr, countA++)
            {
                tubeCenter = Vector3Helper.Get((float)(c * Math.Cos(theta)), 0, (float)(c * Math.Sin(theta)));
                for (countB = 0, thai = 0; countB < stacks; thai += thaiIncr, countB++)
                {
                    VertexPositionNormal vert = new VertexPositionNormal();
                    common        = (c + a * Math.Cos(thai));
                    vert.Position = Vector3Helper.Get((float)(common * Math.Cos(theta)),
                                                      (float)(a * Math.Sin(thai)), (float)(common * Math.Sin(theta)));
                    vert.Normal = Vector3.Normalize(vert.Position - tubeCenter);
                    vertices.Add(vert);
                }
            }

            mesh.VertexDeclaration = VertexPositionNormal.VertexDeclaration;

            mesh.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormal),
                                                 vertices.Count, BufferUsage.None);
            mesh.VertexBuffer.SetData(vertices.ToArray());

            List <short> indices = new List <short>();

            for (int i = 0; i < slices - 1; i++)
            {
                for (int j = 0; j < stacks - 1; j++)
                {
                    indices.Add((short)(i * stacks + j));
                    indices.Add((short)((i + 1) * stacks + j));
                    indices.Add((short)(i * stacks + j + 1));

                    indices.Add((short)(i * stacks + j + 1));
                    indices.Add((short)((i + 1) * stacks + j));
                    indices.Add((short)((i + 1) * stacks + j + 1));
                }

                indices.Add((short)((i + 1) * stacks - 1));
                indices.Add((short)((i + 2) * stacks - 1));
                indices.Add((short)(i * stacks));

                indices.Add((short)(i * stacks));
                indices.Add((short)((i + 2) * stacks - 1));
                indices.Add((short)((i + 1) * stacks));
            }

            for (int j = 0; j < stacks - 1; j++)
            {
                indices.Add((short)((slices - 1) * stacks + j));
                indices.Add((short)j);
                indices.Add((short)((slices - 1) * stacks + j + 1));

                indices.Add((short)((slices - 1) * stacks + j + 1));
                indices.Add((short)j);
                indices.Add((short)(j + 1));
            }
            indices.Add((short)(slices * stacks - 1));
            indices.Add((short)(slices - 1));
            indices.Add((short)((slices - 1) * stacks));

            indices.Add((short)((slices - 1) * stacks));
            indices.Add((short)(slices - 1));
            indices.Add((short)0);

            mesh.IndexBuffer = new IndexBuffer(State.Device, typeof(short), indices.Count,
                                               BufferUsage.None);
            mesh.IndexBuffer.SetData(indices.ToArray());

            mesh.NumberOfVertices   = vertices.Count;
            mesh.NumberOfPrimitives = indices.Count / 3;

            return(mesh);
        }
예제 #2
0
        private static CustomMesh CreateTorus(float inner, float outer, int slices, int stacks)
        {
            if (slices < 5)
                throw new ArgumentException("Cannot draw a torus with slices less than 5");
            if (slices > 100)
                throw new ArgumentException("Cannot draw a torus with slices greater than 100");
            if (stacks < 5)
                throw new ArgumentException("Cannot draw a torus with stacks less than 5");
            if (stacks > 100)
                throw new ArgumentException("Cannot draw a torus with stacks greater than 100");
            if (inner < 0)
                throw new ArgumentException("Inner radius has to be greater than or equal to 0");
            if (outer <= 0)
                throw new ArgumentException("Outer radius has to be greater than 0");
            if (inner >= outer)
                throw new ArgumentException("Inner radius has to be less than outer radius");

            CustomMesh mesh = new CustomMesh();

            List<VertexPositionNormal> vertices = new List<VertexPositionNormal>();

            // Add the vertices
            double thetaIncr = Math.PI * 2 / slices;
            double thaiIncr = Math.PI * 2 / stacks;
            int countA, countB = 0;
            double theta, thai;
            float c = (outer + inner) / 2;
            float a = (outer - inner) / 2;
            double common;
            Vector3 tubeCenter;
            for (countA = 0, theta = 0; countA < slices; theta += thetaIncr, countA++)
            {
                tubeCenter = Vector3Helper.Get((float)(c * Math.Cos(theta)), 0, (float)(c * Math.Sin(theta)));
                for (countB = 0, thai = 0; countB < stacks; thai += thaiIncr, countB++)
                {
                    VertexPositionNormal vert = new VertexPositionNormal();
                    common = (c + a * Math.Cos(thai));
                    vert.Position = Vector3Helper.Get((float)(common * Math.Cos(theta)),
                        (float)(a * Math.Sin(thai)), (float)(common * Math.Sin(theta)));
                    vert.Normal = Vector3.Normalize(vert.Position - tubeCenter);
                    vertices.Add(vert);
                }
            }

            mesh.VertexDeclaration = VertexPositionNormal.VertexDeclaration;

            mesh.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormal),
                vertices.Count, BufferUsage.None);
            mesh.VertexBuffer.SetData(vertices.ToArray());

            List<short> indices = new List<short>();

            for (int i = 0; i < slices - 1; i++)
            {
                for (int j = 0; j < stacks - 1; j++)
                {
                    indices.Add((short)(i * stacks + j));
                    indices.Add((short)((i + 1) * stacks + j));
                    indices.Add((short)(i * stacks + j + 1));

                    indices.Add((short)(i * stacks + j + 1));
                    indices.Add((short)((i + 1) * stacks + j));
                    indices.Add((short)((i + 1) * stacks + j + 1));
                }

                indices.Add((short)((i + 1) * stacks - 1));
                indices.Add((short)((i + 2) * stacks - 1));
                indices.Add((short)(i * stacks));

                indices.Add((short)(i * stacks));
                indices.Add((short)((i + 2) * stacks - 1));
                indices.Add((short)((i + 1) * stacks));
            }

            for (int j = 0; j < stacks - 1; j++)
            {
                indices.Add((short)((slices - 1) * stacks + j));
                indices.Add((short)j);
                indices.Add((short)((slices - 1) * stacks + j + 1));

                indices.Add((short)((slices - 1) * stacks + j + 1));
                indices.Add((short)j);
                indices.Add((short)(j + 1));
            }
            indices.Add((short)(slices * stacks - 1));
            indices.Add((short)(slices - 1));
            indices.Add((short)((slices - 1) * stacks));

            indices.Add((short)((slices - 1) * stacks));
            indices.Add((short)(slices - 1));
            indices.Add((short)0);

            mesh.IndexBuffer = new IndexBuffer(State.Device, typeof(short), indices.Count,
                BufferUsage.None);
            mesh.IndexBuffer.SetData(indices.ToArray());

            mesh.NumberOfVertices = vertices.Count;
            mesh.NumberOfPrimitives = indices.Count / 3;

            return mesh;
        }
예제 #3
0
        private static CustomMesh CreateCapsule(float radius, float height, int slices)
        {
            if (slices < 5)
            {
                throw new ArgumentException("Cannot draw a capsule with slices less than 5");
            }
            if (slices > 100)
            {
                throw new ArgumentException("Cannot draw a capsule with slices greater than 100");
            }
            if (radius <= 0)
            {
                throw new ArgumentException("radius should be greater than zero");
            }
            if (height <= 0)
            {
                throw new ArgumentException("height should be greater than zero");
            }

            if (height < radius * 2)
            {
                height = radius * 2;
            }

            CustomMesh mesh = new CustomMesh();

            List <VertexPositionNormal> vertices = new List <VertexPositionNormal>();

            float   cylinderHeight = height - radius * 2;
            Vector3 topCenter      = Vector3Helper.Get(0, cylinderHeight / 2, 0);
            Vector3 bottomCenter   = Vector3Helper.Get(0, -cylinderHeight / 2, 0);

            double thai = 0, theta = 0;
            double thaiIncr = Math.PI / slices;
            double thetaIncr = Math.PI * 2 / slices;
            int    countB, countA;

            // Add top hemisphere vertices
            for (countA = 0, thai = thaiIncr; thai < Math.PI / 2; thai += thaiIncr, countA++)
            {
                for (countB = 0, theta = 0; countB < slices; theta += thetaIncr, countB++)
                {
                    VertexPositionNormal vert = new VertexPositionNormal();
                    vert.Position = Vector3Helper.Get((float)(radius * Math.Sin(thai) * Math.Cos(theta)),
                                                      (float)(radius * Math.Cos(thai)) + cylinderHeight / 2,
                                                      (float)(radius * Math.Sin(thai) * Math.Sin(theta)));
                    vert.Normal = Vector3.Normalize(vert.Position - topCenter);
                    vertices.Add(vert);
                }
            }

            // Add bottom hemisphere vertices
            for (thai = Math.PI / 2; thai < Math.PI - thaiIncr / 2; thai += thaiIncr, countA++)
            {
                for (countB = 0, theta = 0; countB < slices; theta += thetaIncr, countB++)
                {
                    VertexPositionNormal vert = new VertexPositionNormal();
                    vert.Position = Vector3Helper.Get((float)(radius * Math.Sin(thai) * Math.Cos(theta)),
                                                      (float)(radius * Math.Cos(thai)) - cylinderHeight / 2,
                                                      (float)(radius * Math.Sin(thai) * Math.Sin(theta)));
                    vert.Normal = Vector3.Normalize(vert.Position - bottomCenter);
                    vertices.Add(vert);
                }
            }

            // Add north pole vertex
            vertices.Add(new VertexPositionNormal(Vector3Helper.Get(0, radius + cylinderHeight / 2, 0),
                                                  Vector3Helper.Get(0, 1, 0)));
            // Add south pole vertex
            vertices.Add(new VertexPositionNormal(Vector3Helper.Get(0, -radius - cylinderHeight / 2, 0),
                                                  Vector3Helper.Get(0, -1, 0)));

            mesh.VertexDeclaration = VertexPositionNormal.VertexDeclaration;

            mesh.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormal),
                                                 vertices.Count, BufferUsage.None);
            mesh.VertexBuffer.SetData(vertices.ToArray());

            List <short> indices = new List <short>();

            // Create the north and south pole area mesh
            for (int i = 0, j = (countA - 1) * slices; i < slices - 1; i++, j++)
            {
                indices.Add((short)(vertices.Count - 2));
                indices.Add((short)i);
                indices.Add((short)(i + 1));

                indices.Add((short)(vertices.Count - 1));
                indices.Add((short)(j + 1));
                indices.Add((short)j);
            }
            indices.Add((short)(vertices.Count - 2));
            indices.Add((short)(slices - 1));
            indices.Add((short)0);

            indices.Add((short)(vertices.Count - 1));
            indices.Add((short)((countA - 1) * slices));
            indices.Add((short)(vertices.Count - 3));

            // Create side of the hemispheres
            for (int i = 0; i < countA - 1; i++)
            {
                for (int j = 0; j < slices - 1; j++)
                {
                    indices.Add((short)(i * slices + j));
                    indices.Add((short)((i + 1) * slices + j));
                    indices.Add((short)((i + 1) * slices + j + 1));

                    indices.Add((short)(i * slices + j));
                    indices.Add((short)((i + 1) * slices + j + 1));
                    indices.Add((short)(i * slices + j + 1));
                }

                indices.Add((short)((i + 1) * slices - 1));
                indices.Add((short)((i + 2) * slices - 1));
                indices.Add((short)((i + 1) * slices));

                indices.Add((short)((i + 1) * slices - 1));
                indices.Add((short)((i + 1) * slices));
                indices.Add((short)(i * slices));
            }

            mesh.IndexBuffer = new IndexBuffer(State.Device, typeof(short), indices.Count,
                                               BufferUsage.None);
            mesh.IndexBuffer.SetData(indices.ToArray());

            mesh.NumberOfVertices   = vertices.Count;
            mesh.NumberOfPrimitives = indices.Count / 3;

            return(mesh);
        }
예제 #4
0
        private static CustomMesh CreateChamferCylinder(float radius, float height, int slices)
        {
            if(slices < 5)
                throw new ArgumentException("Cannot draw a capsule with slices less than 5");
            if (slices > 100)
                throw new ArgumentException("Cannot draw a capsule with slices greater than 100");
            if (radius <= 0)
                throw new ArgumentException("radius should be greater than zero");
            if (height <= 0)
                throw new ArgumentException("height should be greater than zero");

            CustomMesh mesh = new CustomMesh();

            List<VertexPositionNormal> vertices = new List<VertexPositionNormal>();

            float halfH = height / 2;
            Vector3 topCenter = Vector3Helper.Get(0, halfH, 0);
            Vector3 bottomCenter = Vector3Helper.Get(0, -halfH, 0);

            double thai = 0, theta = 0;
            double thaiIncr = Math.PI / slices;
            double thetaIncr = Math.PI * 2 / slices;
            int countB, countA;

            // Add side vertices
            for (countA = 0, thai = 0; thai <= Math.PI; thai += thaiIncr, countA++)
            {
                for (countB = 0, theta = 0; countB < slices; theta += thetaIncr, countB++)
                {
                    VertexPositionNormal vert = new VertexPositionNormal();
                    vert.Position = Vector3Helper.Get((float)(halfH * Math.Sin(thai) * Math.Cos(theta) + radius * Math.Cos(theta)),
                        (float)(halfH * Math.Cos(thai)), 
                        (float)(halfH * Math.Sin(thai) * Math.Sin(theta) + radius * Math.Sin(theta)));
                    vert.Normal = Vector3.Normalize(vert.Position);
                    vertices.Add(vert);
                }
            }

            // Add north pole vertex
            vertices.Add(new VertexPositionNormal(topCenter, new Vector3(0, 1, 0)));
            // Add south pole vertex
            vertices.Add(new VertexPositionNormal(bottomCenter, new Vector3(0, -1, 0)));

            mesh.VertexDeclaration = VertexPositionNormal.VertexDeclaration;

            mesh.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormal),
                vertices.Count, BufferUsage.None);
            mesh.VertexBuffer.SetData(vertices.ToArray());

            List<short> indices = new List<short>();

            // Create side of the hemispheres
            for (int i = 0; i < countA - 1; i++)
            {
                for (int j = 0; j < slices - 1; j++)
                {
                    indices.Add((short)(i * slices + j));
                    indices.Add((short)((i + 1) * slices + j));
                    indices.Add((short)((i + 1) * slices + j + 1));

                    indices.Add((short)(i * slices + j));
                    indices.Add((short)((i + 1) * slices + j + 1));
                    indices.Add((short)(i * slices + j + 1));
                }

                indices.Add((short)((i + 1) * slices - 1));
                indices.Add((short)((i + 2) * slices - 1));
                indices.Add((short)((i + 1) * slices));

                indices.Add((short)((i + 1) * slices - 1));
                indices.Add((short)((i + 1) * slices));
                indices.Add((short)(i * slices ));
            }

            // Create the north and south pole area mesh
            for (int i = 0, j = (countA - 1) * slices; i < slices - 1; i++, j++)
            {
                indices.Add((short)(vertices.Count - 2));
                indices.Add((short)i);
                indices.Add((short)(i + 1));

                indices.Add((short)(vertices.Count - 1));
                indices.Add((short)(j + 1));
                indices.Add((short)j);
            }
            indices.Add((short)(vertices.Count - 2));
            indices.Add((short)(slices - 1));
            indices.Add(0);

            indices.Add((short)(vertices.Count - 1));
            indices.Add((short)((countA - 1) * slices));
            indices.Add((short)(vertices.Count - 3));

            mesh.IndexBuffer = new IndexBuffer(State.Device, typeof(short), indices.Count,
                BufferUsage.None);
            mesh.IndexBuffer.SetData(indices.ToArray());

            mesh.NumberOfVertices = vertices.Count;
            mesh.NumberOfPrimitives = indices.Count / 3;

            return mesh;
        }
예제 #5
0
        private static CustomMesh CreateBox(float xdim, float ydim, float zdim)
        {
            CustomMesh mesh = new CustomMesh();

            VertexPositionNormal[] vertices = new VertexPositionNormal[24];
            Vector3 halfExtent = new Vector3();

            halfExtent.X = xdim / 2;
            halfExtent.Y = ydim / 2;
            halfExtent.Z = zdim / 2;

            Vector3 v0 = Vector3Helper.Get(-halfExtent.X, -halfExtent.Y, -halfExtent.Z);
            Vector3 v1 = Vector3Helper.Get(halfExtent.X, -halfExtent.Y, -halfExtent.Z);
            Vector3 v2 = Vector3Helper.Get(-halfExtent.X, halfExtent.Y, -halfExtent.Z);
            Vector3 v3 = Vector3Helper.Get(halfExtent.X, halfExtent.Y, -halfExtent.Z);
            Vector3 v4 = Vector3Helper.Get(halfExtent.X, halfExtent.Y, halfExtent.Z);
            Vector3 v5 = Vector3Helper.Get(-halfExtent.X, halfExtent.Y, halfExtent.Z);
            Vector3 v6 = Vector3Helper.Get(halfExtent.X, -halfExtent.Y, halfExtent.Z);
            Vector3 v7 = Vector3Helper.Get(-halfExtent.X, -halfExtent.Y, halfExtent.Z);

            Vector3 nZ = -Vector3.UnitZ;
            Vector3 pZ = Vector3.UnitZ;
            Vector3 nX = -Vector3.UnitX;
            Vector3 pX = Vector3.UnitX;
            Vector3 nY = -Vector3.UnitY;
            Vector3 pY = Vector3.UnitY;

            vertices[0].Position = v0; vertices[1].Position = v1;
            vertices[2].Position = v2; vertices[3].Position = v3;

            vertices[4].Position = v0; vertices[5].Position = v7;
            vertices[6].Position = v2; vertices[7].Position = v5;

            vertices[8].Position  = v4; vertices[9].Position = v5;
            vertices[10].Position = v7; vertices[11].Position = v6;

            vertices[12].Position = v4; vertices[13].Position = v3;
            vertices[14].Position = v1; vertices[15].Position = v6;

            vertices[16].Position = v2; vertices[17].Position = v4;
            vertices[18].Position = v5; vertices[19].Position = v3;

            vertices[20].Position = v0; vertices[21].Position = v1;
            vertices[22].Position = v6; vertices[23].Position = v7;

            for (int i = 0; i < 4; i++)
            {
                vertices[i].Normal = nZ;
            }
            for (int i = 4; i < 8; i++)
            {
                vertices[i].Normal = nX;
            }
            for (int i = 8; i < 12; i++)
            {
                vertices[i].Normal = pZ;
            }
            for (int i = 12; i < 16; i++)
            {
                vertices[i].Normal = pX;
            }
            for (int i = 16; i < 20; i++)
            {
                vertices[i].Normal = pY;
            }
            for (int i = 20; i < 24; i++)
            {
                vertices[i].Normal = nY;
            }

            mesh.VertexDeclaration = VertexPositionNormal.VertexDeclaration;

            mesh.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormal),
                                                 24, BufferUsage.None);
            mesh.VertexBuffer.SetData <VertexPositionNormal>(vertices);

            short [] indices = new short[36];

            indices[0]  = 0; indices[1] = 1; indices[2] = 2;
            indices[3]  = 2; indices[4] = 1; indices[5] = 3;
            indices[6]  = 4; indices[7] = 6; indices[8] = 5;
            indices[9]  = 6; indices[10] = 7; indices[11] = 5;
            indices[12] = 11; indices[13] = 10; indices[14] = 9;
            indices[15] = 11; indices[16] = 9; indices[17] = 8;
            indices[18] = 14; indices[19] = 15; indices[20] = 13;
            indices[21] = 15; indices[22] = 12; indices[23] = 13;
            indices[24] = 19; indices[25] = 17; indices[26] = 18;
            indices[27] = 19; indices[28] = 18; indices[29] = 16;
            indices[30] = 21; indices[31] = 20; indices[32] = 23;
            indices[33] = 21; indices[34] = 23; indices[35] = 22;

            mesh.IndexBuffer = new IndexBuffer(State.Device, typeof(short), 36,
                                               BufferUsage.None);
            mesh.IndexBuffer.SetData(indices);

            mesh.NumberOfVertices   = 24;
            mesh.NumberOfPrimitives = 12;

            return(mesh);
        }
예제 #6
0
        private static CustomMesh CreateShape(float xDim, float yDim, float zDim)
        {
            // Create a primitive mesh for creating our custom pyramid shape
            CustomMesh pyramid = new CustomMesh();

            // Even though we really need 5 vertices to create a pyramid shape, since
            // we want to assign different normals for points with same position to have
            // more accurate lighting effect, we will use 16 vertices.
            VertexPositionNormal[] verts = new VertexPositionNormal[16];

            Vector3 vBase0 = new Vector3(-xDim / 2, 0, zDim / 2);
            Vector3 vBase1 = new Vector3(xDim / 2, 0, zDim / 2);
            Vector3 vBase2 = new Vector3(xDim / 2, 0, -zDim / 2);
            Vector3 vBase3 = new Vector3(-xDim / 2, 0, -zDim / 2);
            Vector3 vTop = new Vector3(0, yDim, 0);

            verts[0].Position = vTop;
            verts[1].Position = vBase1;
            verts[2].Position = vBase0;

            verts[3].Position = vTop;
            verts[4].Position = vBase2;
            verts[5].Position = vBase1;

            verts[6].Position = vTop;
            verts[7].Position = vBase3;
            verts[8].Position = vBase2;

            verts[9].Position = vTop;
            verts[10].Position = vBase0;
            verts[11].Position = vBase3;

            verts[12].Position = vBase0;
            verts[13].Position = vBase1;
            verts[14].Position = vBase2;
            verts[15].Position = vBase3;

            verts[0].Normal = verts[1].Normal = verts[2].Normal = CalcNormal(vTop, vBase1, vBase0);
            verts[3].Normal = verts[4].Normal = verts[5].Normal = CalcNormal(vTop, vBase2, vBase1);
            verts[6].Normal = verts[7].Normal = verts[8].Normal = CalcNormal(vTop, vBase3, vBase2);
            verts[9].Normal = verts[10].Normal = verts[11].Normal = CalcNormal(vTop, vBase0, vBase3);
            verts[12].Normal = verts[13].Normal = verts[14].Normal = verts[15].Normal = CalcNormal(vBase0,
                vBase1, vBase3);

            pyramid.VertexBuffer = new VertexBuffer(State.Device,
                typeof(VertexPositionNormal), 16, BufferUsage.None);
            pyramid.VertexDeclaration = VertexPositionNormal.VertexDeclaration;
            pyramid.VertexBuffer.SetData(verts);
            pyramid.NumberOfVertices = 16;

            short[] indices = new short[18];

            indices[0] = 0;
            indices[1] = 1;
            indices[2] = 2;

            indices[3] = 3;
            indices[4] = 4;
            indices[5] = 5;

            indices[6] = 6;
            indices[7] = 7;
            indices[8] = 8;

            indices[9] = 9;
            indices[10] = 10;
            indices[11] = 11;

            indices[12] = 12;
            indices[13] = 13;
            indices[14] = 15;

            indices[15] = 13;
            indices[16] = 14;
            indices[17] = 15;

            pyramid.IndexBuffer = new IndexBuffer(State.Device, typeof(short), 18,
                BufferUsage.WriteOnly);
            pyramid.IndexBuffer.SetData(indices);

            pyramid.PrimitiveType = PrimitiveType.TriangleList;
            pyramid.NumberOfPrimitives = 6;

            return pyramid;
        }
예제 #7
0
파일: Disk.cs 프로젝트: NinjaSteph/SureShot
        private static CustomMesh CreateDisk(float inner, float outer, int slices, 
            double start, double sweep, bool twoSided)
        {
            if (slices < 3)
                throw new ArgumentException("Cannot draw a disk with slices less than 3");
            if (inner < 0)
                throw new ArgumentException("Inner radius has to be greater than or equal to 0");
            if (outer <= 0)
                throw new ArgumentException("Outer radius has to be greater than 0");
            if (inner >= outer)
                throw new ArgumentException("Inner radius has to be less than outer radius");

            CustomMesh mesh = new CustomMesh();

            List<VertexPositionNormal> vertices = new List<VertexPositionNormal>();

            double angle = start;
            double incr = sweep / slices;
            float cos, sin;
            bool hasInner = (inner > 0);
            // Add top & bottom side vertices
            if (!hasInner)
            {
                VertexPositionNormal front = new VertexPositionNormal();
                front.Position = Vector3Helper.Get(0, 0, 0);
                front.Normal = Vector3Helper.Get(0, 1, 0);
                vertices.Add(front);

                if (twoSided)
                {
                    VertexPositionNormal back = new VertexPositionNormal();
                    back.Position = Vector3Helper.Get(0, 0, 0);
                    back.Normal = Vector3Helper.Get(0, -1, 0);
                    vertices.Add(back);
                }
            }

            // Add inner & outer vertices
            for (int i = 0; i <= slices; i++, angle += incr)
            {
                cos = (float)Math.Cos(angle);
                sin = (float)Math.Sin(angle);

                if (hasInner)
                {
                    VertexPositionNormal inside = new VertexPositionNormal();
                    inside.Position = Vector3Helper.Get(cos * inner, 0, sin * inner);
                    inside.Normal = Vector3Helper.Get(0, 1, 0);
                    vertices.Add(inside);

                    if (twoSided)
                        vertices.Add(new VertexPositionNormal(inside.Position, Vector3Helper.Get(0, -1, 0)));
                }

                VertexPositionNormal outside = new VertexPositionNormal();
                outside.Position = Vector3Helper.Get(cos * outer, 0, sin * outer);
                outside.Normal = Vector3Helper.Get(0, 1, 0);
                vertices.Add(outside);

                if (twoSided)
                    vertices.Add(new VertexPositionNormal(outside.Position, Vector3Helper.Get(0, -1, 0)));
            }

            mesh.VertexDeclaration = VertexPositionNormal.VertexDeclaration;

            mesh.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormal),
                vertices.Count, BufferUsage.None);
            mesh.VertexBuffer.SetData(vertices.ToArray());

            List<short> indices = new List<short>();

            // Create front side
            if (twoSided)
            {
                if (hasInner)
                {
                    for (int i = 0; i < vertices.Count - 2; i++)
                    {
                        indices.Add((short)(2 * i));
                        indices.Add((short)(2 * (i + 2 - (i+1)%2)));
                        indices.Add((short)(2 * (i + 2 - i%2)));

                        indices.Add((short)(2 * i - 1));
                        indices.Add((short)(2 * (i + 2 - (i + 1) % 2) - 1));
                        indices.Add((short)(2 * (i + 2 - i % 2) - 1));
                    }
                }
                else
                {
                    for (int i = 1; i < vertices.Count - 1; i++)
                    {
                        indices.Add((short)0);
                        indices.Add((short)(2 * i));
                        indices.Add((short)(2 * (i + 1)));

                        indices.Add((short)0);
                        indices.Add((short)(i + 3));
                        indices.Add((short)(i + 1));
                    }
                }
            }
            else
            {
                if (hasInner)
                {
                    for (int i = 0; i < vertices.Count - 2; i++)
                    {
                        indices.Add((short)i);
                        indices.Add((short)(i + 2 - (i+1)%2));
                        indices.Add((short)(i + 2 - i%2));
                    }
                }
                else
                {
                    for (int i = 1; i < vertices.Count - 1; i++)
                    {
                        indices.Add((short)0);
                        indices.Add((short)(i));
                        indices.Add((short)(i + 1));
                    }
                }
            }

            mesh.IndexBuffer = new IndexBuffer(State.Device, typeof(short), indices.Count,
                BufferUsage.None);
            mesh.IndexBuffer.SetData(indices.ToArray());

            mesh.NumberOfVertices = vertices.Count;
            mesh.NumberOfPrimitives = indices.Count / 3;

            return mesh;
        }
예제 #8
0
        private static CustomMesh CreateCylinder(float bottom, float top, float height, int slices)
        {
            if (slices < 3)
            {
                throw new ArgumentException("Cannot draw a cylinder with slices less than 3");
            }
            if (top < 0)
            {
                throw new ArgumentException("Top has to be a positive natural number");
            }
            if (bottom <= 0)
            {
                throw new ArgumentException("Bottom has to be greater than zero");
            }
            if (height <= 0)
            {
                throw new ArgumentException("Height should be greater than zero");
            }

            CustomMesh mesh = new CustomMesh();

            List <VertexPositionNormal> vertices = new List <VertexPositionNormal>();

            // Add top center vertex
            VertexPositionNormal topCenter = new VertexPositionNormal();

            topCenter.Position = Vector3Helper.Get(0, height / 2, 0);
            topCenter.Normal   = Vector3Helper.Get(0, 1, 0);

            vertices.Add(topCenter);

            // Add bottom center vertex
            VertexPositionNormal bottomCenter = new VertexPositionNormal();

            bottomCenter.Position = Vector3Helper.Get(0, -height / 2, 0);
            bottomCenter.Normal   = Vector3Helper.Get(0, -1, 0);

            vertices.Add(bottomCenter);

            double  angle = 0;
            double  incr = Math.PI * 2 / slices;
            float   cos, sin;
            bool    hasTop = (top > 0);
            Vector3 u, v;
            Matrix  mat;
            bool    tilted   = (top != bottom);
            float   rotAngle = (float)Math.Atan(bottom / height);
            Vector3 down     = -Vector3.UnitY;

            if (hasTop)
            {
                // Add top & bottom side vertices
                for (int i = 0; i <= slices; i++, angle += incr)
                {
                    cos = (float)Math.Cos(angle);
                    sin = (float)Math.Sin(angle);

                    VertexPositionNormal topSide = new VertexPositionNormal();
                    topSide.Position = Vector3Helper.Get(cos * top, height / 2, sin * top);
                    topSide.Normal   = Vector3.Normalize(topSide.Position - topCenter.Position);

                    VertexPositionNormal topSide2 = new VertexPositionNormal();
                    topSide2.Position = Vector3Helper.Get(cos * top, height / 2, sin * top);
                    topSide2.Normal   = topCenter.Normal;

                    // Add bottom side vertices
                    VertexPositionNormal bottomSide = new VertexPositionNormal();
                    bottomSide.Position = Vector3Helper.Get(cos * bottom, -height / 2, sin * bottom);
                    bottomSide.Normal   = Vector3.Normalize(bottomSide.Position - bottomCenter.Position);

                    VertexPositionNormal bottomSide2 = new VertexPositionNormal();
                    bottomSide2.Position = Vector3Helper.Get(cos * bottom, -height / 2, sin * bottom);
                    bottomSide2.Normal   = bottomCenter.Normal;

                    if (tilted)
                    {
                        v              = topSide.Normal;
                        u              = Vector3.Cross(v, down);
                        mat            = Matrix.CreateTranslation(v) * Matrix.CreateFromAxisAngle(u, -rotAngle);
                        topSide.Normal = bottomSide.Normal = Vector3.Normalize(mat.Translation);
                    }

                    vertices.Add(topSide);
                    vertices.Add(topSide2);
                    vertices.Add(bottomSide);
                    vertices.Add(bottomSide2);
                }
            }
            else
            {
                // Add top & bottom side vertices
                for (int i = 0; i <= slices; i++, angle += incr)
                {
                    cos = (float)Math.Cos(angle);
                    sin = (float)Math.Sin(angle);

                    VertexPositionNormal topSide = new VertexPositionNormal();
                    topSide.Position = topCenter.Position;

                    // Add bottom side vertices
                    VertexPositionNormal bottomSide = new VertexPositionNormal();
                    bottomSide.Position = Vector3Helper.Get(cos * bottom, -height / 2, sin * bottom);
                    bottomSide.Normal   = Vector3.Normalize(bottomSide.Position - bottomCenter.Position);

                    VertexPositionNormal bottomSide2 = new VertexPositionNormal();
                    bottomSide2.Position = Vector3Helper.Get(cos * bottom, -height / 2, sin * bottom);
                    bottomSide2.Normal   = bottomCenter.Normal;

                    v              = bottomSide.Normal;
                    u              = Vector3.Cross(v, down);
                    mat            = Matrix.CreateTranslation(v) * Matrix.CreateFromAxisAngle(u, rotAngle);
                    topSide.Normal = bottomSide.Normal = Vector3.Normalize(mat.Translation);

                    vertices.Add(topSide);
                    vertices.Add(bottomSide);
                    vertices.Add(bottomSide2);
                }
            }

            mesh.VertexDeclaration = VertexPositionNormal.VertexDeclaration;

            mesh.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormal),
                                                 vertices.Count, BufferUsage.None);
            mesh.VertexBuffer.SetData(vertices.ToArray());

            List <short> indices = new List <short>();

            if (hasTop)
            {
                // Create top & bottom circle
                for (int i = 2; i < vertices.Count - 7; i += 4)
                {
                    indices.Add(0);
                    indices.Add((short)(i + 1));
                    indices.Add((short)(i + 5));

                    indices.Add(1);
                    indices.Add((short)(i + 7));
                    indices.Add((short)(i + 3));
                }

                // Create side
                for (int i = 2; i < vertices.Count - 7; i += 4)
                {
                    indices.Add((short)i);
                    indices.Add((short)(i + 2));
                    indices.Add((short)(i + 4));

                    indices.Add((short)(i + 4));
                    indices.Add((short)(i + 2));
                    indices.Add((short)(i + 6));
                }
            }
            else
            {
                // Create bottom circle
                for (int i = 2; i < vertices.Count - 5; i += 3)
                {
                    indices.Add(1);
                    indices.Add((short)(i + 5));
                    indices.Add((short)(i + 2));
                }

                // Create side
                for (int i = 2; i < vertices.Count - 5; i += 3)
                {
                    indices.Add((short)i);
                    indices.Add((short)(i + 1));
                    indices.Add((short)(i + 4));
                }
            }

            mesh.IndexBuffer = new IndexBuffer(State.Device, typeof(short), indices.Count,
                                               BufferUsage.None);
            mesh.IndexBuffer.SetData(indices.ToArray());

            mesh.NumberOfVertices   = vertices.Count;
            mesh.NumberOfPrimitives = indices.Count / 3;

            return(mesh);
        }
예제 #9
0
        private static CustomMesh CreateCylinder(float bottom, float top, float height, int slices)
        {
            if(slices < 3)
                throw new ArgumentException("Cannot draw a cylinder with slices less than 3");
            if (top < 0)
                throw new ArgumentException("Top has to be a positive natural number");
            if (bottom <= 0)
                throw new ArgumentException("Bottom has to be greater than zero");
            if (height <= 0)
                throw new ArgumentException("Height should be greater than zero");

            CustomMesh mesh = new CustomMesh();

            List<VertexPositionNormal> vertices = new List<VertexPositionNormal>();

            // Add top center vertex
            VertexPositionNormal topCenter = new VertexPositionNormal();
            topCenter.Position = Vector3Helper.Get(0, height / 2, 0);
            topCenter.Normal = Vector3Helper.Get(0, 1, 0);

            vertices.Add(topCenter);

            // Add bottom center vertex
            VertexPositionNormal bottomCenter = new VertexPositionNormal();
            bottomCenter.Position = Vector3Helper.Get(0, -height / 2, 0);
            bottomCenter.Normal = Vector3Helper.Get(0, -1, 0);

            vertices.Add(bottomCenter);

            double angle = 0;
            double incr = Math.PI * 2 / slices;
            float cos, sin;
            bool hasTop = (top > 0);
            Vector3 u, v;
            Matrix mat;
            bool tilted = (top != bottom);
            float rotAngle = (float)Math.Atan(bottom / height);
            Vector3 down = -Vector3.UnitY;
            if (hasTop)
            {
                // Add top & bottom side vertices
                for (int i = 0; i <= slices; i++, angle += incr)
                {
                    cos = (float)Math.Cos(angle);
                    sin = (float)Math.Sin(angle);

                    VertexPositionNormal topSide = new VertexPositionNormal();
                    topSide.Position = Vector3Helper.Get(cos * top, height / 2, sin * top);
                    topSide.Normal = Vector3.Normalize(topSide.Position - topCenter.Position);

                    VertexPositionNormal topSide2 = new VertexPositionNormal();
                    topSide2.Position = Vector3Helper.Get(cos * top, height / 2, sin * top);
                    topSide2.Normal = topCenter.Normal;

                    // Add bottom side vertices
                    VertexPositionNormal bottomSide = new VertexPositionNormal();
                    bottomSide.Position = Vector3Helper.Get(cos * bottom, -height / 2, sin * bottom);
                    bottomSide.Normal = Vector3.Normalize(bottomSide.Position - bottomCenter.Position);

                    VertexPositionNormal bottomSide2 = new VertexPositionNormal();
                    bottomSide2.Position = Vector3Helper.Get(cos * bottom, -height / 2, sin * bottom);
                    bottomSide2.Normal = bottomCenter.Normal;

                    if (tilted)
                    {
                        v = topSide.Normal;
                        u = Vector3.Cross(v, down);
                        mat = Matrix.CreateTranslation(v) * Matrix.CreateFromAxisAngle(u, -rotAngle);
                        topSide.Normal = bottomSide.Normal = Vector3.Normalize(mat.Translation);
                    }

                    vertices.Add(topSide);
                    vertices.Add(topSide2);
                    vertices.Add(bottomSide);
                    vertices.Add(bottomSide2);
                }
            }
            else
            {
                // Add top & bottom side vertices
                for (int i = 0; i <= slices; i++, angle += incr)
                {
                    cos = (float)Math.Cos(angle);
                    sin = (float)Math.Sin(angle);

                    VertexPositionNormal topSide = new VertexPositionNormal();
                    topSide.Position = topCenter.Position;

                    // Add bottom side vertices
                    VertexPositionNormal bottomSide = new VertexPositionNormal();
                    bottomSide.Position = Vector3Helper.Get(cos * bottom, -height / 2, sin * bottom);
                    bottomSide.Normal = Vector3.Normalize(bottomSide.Position - bottomCenter.Position);

                    VertexPositionNormal bottomSide2 = new VertexPositionNormal();
                    bottomSide2.Position = Vector3Helper.Get(cos * bottom, -height / 2, sin * bottom);
                    bottomSide2.Normal = bottomCenter.Normal;

                    v = bottomSide.Normal;
                    u = Vector3.Cross(v, down);
                    mat = Matrix.CreateTranslation(v) * Matrix.CreateFromAxisAngle(u, rotAngle);
                    topSide.Normal = bottomSide.Normal = Vector3.Normalize(mat.Translation);

                    vertices.Add(topSide);
                    vertices.Add(bottomSide);
                    vertices.Add(bottomSide2);
                }
            }

            mesh.VertexDeclaration = VertexPositionNormal.VertexDeclaration;

            mesh.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormal),
                vertices.Count, BufferUsage.None);
            mesh.VertexBuffer.SetData(vertices.ToArray());

            List<short> indices = new List<short>();

            if (hasTop)
            {
                // Create top & bottom circle 
                for (int i = 2; i < vertices.Count - 7; i += 4)
                {
                    indices.Add(0);
                    indices.Add((short)(i + 1));
                    indices.Add((short)(i + 5));

                    indices.Add(1);
                    indices.Add((short)(i + 7));
                    indices.Add((short)(i + 3));
                }

                // Create side
                for (int i = 2; i < vertices.Count - 7; i += 4)
                {
                    indices.Add((short)i);
                    indices.Add((short)(i + 2));
                    indices.Add((short)(i + 4));

                    indices.Add((short)(i + 4));
                    indices.Add((short)(i + 2));
                    indices.Add((short)(i + 6));
                }
            }
            else
            {
                // Create bottom circle 
                for (int i = 2; i < vertices.Count - 5; i += 3)
                {
                    indices.Add(1);
                    indices.Add((short)(i + 5));
                    indices.Add((short)(i + 2));
                }

                // Create side
                for (int i = 2; i < vertices.Count - 5; i += 3)
                {
                    indices.Add((short)i);
                    indices.Add((short)(i + 1));
                    indices.Add((short)(i + 4));
                }
            }

            mesh.IndexBuffer = new IndexBuffer(State.Device, typeof(short), indices.Count,
                BufferUsage.None);
            mesh.IndexBuffer.SetData(indices.ToArray());

            mesh.NumberOfVertices = vertices.Count;
            mesh.NumberOfPrimitives = indices.Count / 3;

            return mesh;
        }
예제 #10
0
        private static CustomMesh CreateSphere(float radius, int slices, int stacks)
        {
            if (slices < 5)
            {
                throw new ArgumentException("Cannot draw a sphere with slices less than 5");
            }
            if (slices > 100)
            {
                throw new ArgumentException("Cannot draw a sphere with slices greater than 100");
            }
            if (stacks < 5)
            {
                throw new ArgumentException("Cannot draw a sphere with stacks less than 5");
            }
            if (stacks > 100)
            {
                throw new ArgumentException("Cannot draw a sphere with stacks greater than 100");
            }
            if (radius <= 0)
            {
                throw new ArgumentException("Radius has to be greater than 0");
            }

            CustomMesh mesh = new CustomMesh();

            List <VertexPositionNormal> vertices = new List <VertexPositionNormal>();

            double thai = 0, theta = 0;
            double thaiIncr = Math.PI / stacks;
            double thetaIncr = Math.PI * 2 / slices;
            int    countB, countA;

            // Add sphere vertices
            for (countA = 0, thai = thaiIncr; thai < Math.PI - thaiIncr / 2; thai += thaiIncr, countA++)
            {
                for (countB = 0, theta = 0; countB < slices; theta += thetaIncr, countB++)
                {
                    VertexPositionNormal vert = new VertexPositionNormal();
                    vert.Position = Vector3Helper.Get((float)(radius * Math.Sin(thai) * Math.Cos(theta)),
                                                      (float)(radius * Math.Cos(thai)), (float)(radius * Math.Sin(thai) * Math.Sin(theta)));
                    vert.Normal = Vector3.Normalize(vert.Position);
                    vertices.Add(vert);
                }
            }

            // Add north pole vertex
            vertices.Add(new VertexPositionNormal(Vector3Helper.Get(0, radius, 0), Vector3Helper.Get(0, 1, 0)));
            // Add south pole vertex
            vertices.Add(new VertexPositionNormal(Vector3Helper.Get(0, -radius, 0), Vector3Helper.Get(0, -1, 0)));

            mesh.VertexDeclaration = VertexPositionNormal.VertexDeclaration;

            mesh.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormal),
                                                 vertices.Count, BufferUsage.None);
            mesh.VertexBuffer.SetData(vertices.ToArray());

            List <short> indices = new List <short>();

            // Create the north and south pole area mesh
            for (int i = 0, j = (countA - 1) * slices; i < slices - 1; i++, j++)
            {
                indices.Add((short)(vertices.Count - 2));
                indices.Add((short)i);
                indices.Add((short)(i + 1));

                indices.Add((short)(vertices.Count - 1));
                indices.Add((short)(j + 1));
                indices.Add((short)j);
            }
            indices.Add((short)(vertices.Count - 2));
            indices.Add((short)(slices - 1));
            indices.Add(0);

            indices.Add((short)(vertices.Count - 1));
            indices.Add((short)((countA - 1) * slices));
            indices.Add((short)(vertices.Count - 3));

            // Create side of the sphere
            for (int i = 0; i < countA - 1; i++)
            {
                for (int j = 0; j < slices - 1; j++)
                {
                    indices.Add((short)(i * slices + j));
                    indices.Add((short)((i + 1) * slices + j));
                    indices.Add((short)((i + 1) * slices + j + 1));

                    indices.Add((short)(i * slices + j));
                    indices.Add((short)((i + 1) * slices + j + 1));
                    indices.Add((short)(i * slices + j + 1));
                }

                indices.Add((short)((i + 1) * slices - 1));
                indices.Add((short)((i + 2) * slices - 1));
                indices.Add((short)((i + 1) * slices));

                indices.Add((short)((i + 1) * slices - 1));
                indices.Add((short)((i + 1) * slices));
                indices.Add((short)(i * slices));
            }

            mesh.IndexBuffer = new IndexBuffer(State.Device, typeof(short), indices.Count,
                                               BufferUsage.None);
            mesh.IndexBuffer.SetData(indices.ToArray());

            mesh.NumberOfVertices   = vertices.Count;
            mesh.NumberOfPrimitives = indices.Count / 3;

            return(mesh);
        }
예제 #11
0
        private static CustomMesh CreateDisk(float inner, float outer, int slices,
                                             double start, double sweep, bool twoSided)
        {
            if (slices < 3)
            {
                throw new ArgumentException("Cannot draw a disk with slices less than 3");
            }
            if (inner < 0)
            {
                throw new ArgumentException("Inner radius has to be greater than or equal to 0");
            }
            if (outer <= 0)
            {
                throw new ArgumentException("Outer radius has to be greater than 0");
            }
            if (inner >= outer)
            {
                throw new ArgumentException("Inner radius has to be less than outer radius");
            }

            CustomMesh mesh = new CustomMesh();

            List <VertexPositionNormal> vertices = new List <VertexPositionNormal>();

            double angle = start;
            double incr = sweep / slices;
            float  cos, sin;
            bool   hasInner = (inner > 0);

            // Add top & bottom side vertices
            if (!hasInner)
            {
                VertexPositionNormal front = new VertexPositionNormal();
                front.Position = Vector3Helper.Get(0, 0, 0);
                front.Normal   = Vector3Helper.Get(0, 1, 0);
                vertices.Add(front);

                if (twoSided)
                {
                    VertexPositionNormal back = new VertexPositionNormal();
                    back.Position = Vector3Helper.Get(0, 0, 0);
                    back.Normal   = Vector3Helper.Get(0, -1, 0);
                    vertices.Add(back);
                }
            }

            // Add inner & outer vertices
            for (int i = 0; i <= slices; i++, angle += incr)
            {
                cos = (float)Math.Cos(angle);
                sin = (float)Math.Sin(angle);

                if (hasInner)
                {
                    VertexPositionNormal inside = new VertexPositionNormal();
                    inside.Position = Vector3Helper.Get(cos * inner, 0, sin * inner);
                    inside.Normal   = Vector3Helper.Get(0, 1, 0);
                    vertices.Add(inside);

                    if (twoSided)
                    {
                        vertices.Add(new VertexPositionNormal(inside.Position, Vector3Helper.Get(0, -1, 0)));
                    }
                }

                VertexPositionNormal outside = new VertexPositionNormal();
                outside.Position = Vector3Helper.Get(cos * outer, 0, sin * outer);
                outside.Normal   = Vector3Helper.Get(0, 1, 0);
                vertices.Add(outside);

                if (twoSided)
                {
                    vertices.Add(new VertexPositionNormal(outside.Position, Vector3Helper.Get(0, -1, 0)));
                }
            }

            mesh.VertexDeclaration = VertexPositionNormal.VertexDeclaration;

            mesh.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormal),
                                                 vertices.Count, BufferUsage.None);
            mesh.VertexBuffer.SetData(vertices.ToArray());

            List <short> indices = new List <short>();

            // Create front side
            if (twoSided)
            {
                if (hasInner)
                {
                    for (int i = 0; i < vertices.Count - 2; i++)
                    {
                        indices.Add((short)(2 * i));
                        indices.Add((short)(2 * (i + 2 - (i + 1) % 2)));
                        indices.Add((short)(2 * (i + 2 - i % 2)));

                        indices.Add((short)(2 * i - 1));
                        indices.Add((short)(2 * (i + 2 - (i + 1) % 2) - 1));
                        indices.Add((short)(2 * (i + 2 - i % 2) - 1));
                    }
                }
                else
                {
                    for (int i = 1; i < vertices.Count - 1; i++)
                    {
                        indices.Add((short)0);
                        indices.Add((short)(2 * i));
                        indices.Add((short)(2 * (i + 1)));

                        indices.Add((short)0);
                        indices.Add((short)(i + 3));
                        indices.Add((short)(i + 1));
                    }
                }
            }
            else
            {
                if (hasInner)
                {
                    for (int i = 0; i < vertices.Count - 2; i++)
                    {
                        indices.Add((short)i);
                        indices.Add((short)(i + 2 - (i + 1) % 2));
                        indices.Add((short)(i + 2 - i % 2));
                    }
                }
                else
                {
                    for (int i = 1; i < vertices.Count - 1; i++)
                    {
                        indices.Add((short)0);
                        indices.Add((short)(i));
                        indices.Add((short)(i + 1));
                    }
                }
            }

            mesh.IndexBuffer = new IndexBuffer(State.Device, typeof(short), indices.Count,
                                               BufferUsage.None);
            mesh.IndexBuffer.SetData(indices.ToArray());

            mesh.NumberOfVertices   = vertices.Count;
            mesh.NumberOfPrimitives = indices.Count / 3;

            return(mesh);
        }