private static CustomMesh CreateBox(float xdim, float ydim, float zdim) { CustomMesh mesh = new CustomMesh(); VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[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; } // Assign texture coordinates using positional spherical mapping Vector3 v; for (int i = 0; i < vertices.Length; ++i) { v = vertices[i].Position; v.Normalize(); vertices[i].TextureCoordinate = new Vector2( (float)Math.Asin(v.X) / MathHelper.Pi + 0.5f, (float)Math.Asin(v.Y) / MathHelper.Pi + 0.5f); } mesh.VertexDeclaration = VertexPositionNormalTexture.VertexDeclaration; mesh.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormalTexture), 24, BufferUsage.None); mesh.VertexBuffer.SetData <VertexPositionNormalTexture>(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); }
/// <summary> /// A private constructor. /// </summary> private GenericInput() { panSpeed = 1; zoomSpeed = 1; rotateSpeed = 1; translation = new Vector3(); rotation = Quaternion.Identity; initialTranslation = new Vector3(); initialRotation = Quaternion.Identity; curMouseLocation = new Point(); prevMouseDragLocation = new Point(-1, -1); MouseInput.Instance.MouseWheelMoveEvent += delegate(int delta, int value) { Vector3 nearSource = Vector3Helper.Get(curMouseLocation.X, curMouseLocation.Y, 0); Vector3 farSource = Vector3Helper.Get(curMouseLocation.X, curMouseLocation.Y, 1); // Now convert the near and far source to actual near and far 3D points based on our eye location // and view frustum Vector3 nearPoint = State.Device.Viewport.Unproject(nearSource, State.ProjectionMatrix, State.ViewMatrix, Matrix.Identity); Vector3 farPoint = State.Device.Viewport.Unproject(farSource, State.ProjectionMatrix, State.ViewMatrix, Matrix.Identity); Vector3 zoomRay = farPoint - nearPoint; zoomRay.Normalize(); zoomRay *= zoomSpeed * delta / 100; translation += zoomRay; }; MouseInput.Instance.MouseDragEvent += delegate(int button, Point startLocation, Point currentLocation) { if (prevMouseDragLocation.X < 0) { prevMouseDragLocation = startLocation; } if (button == MouseInput.RightButton) { int deltaX = currentLocation.X - prevMouseDragLocation.X; int deltaY = currentLocation.Y - prevMouseDragLocation.Y; if (!(deltaX == 0 && deltaY == 0)) { Quaternion change = Quaternion.CreateFromYawPitchRoll ((float)(deltaX * rotateSpeed * Math.PI / 45), (float)(deltaY * rotateSpeed * Math.PI / 45), 0); rotation = Quaternion.Multiply(rotation, change); } } else if (button == MouseInput.MiddleButton) { translation += (currentLocation.Y - prevMouseDragLocation.Y) * panSpeed * baseTransform.Up; } else if (button == MouseInput.LeftButton) { Vector3 leftAxis = (currentLocation.X - prevMouseDragLocation.X) / 2.0f * panSpeed * baseTransform.Left; Vector3 forwardAxis = (currentLocation.Y - prevMouseDragLocation.Y) / 2.0f * panSpeed * baseTransform.Forward; Vector3 change = leftAxis + forwardAxis; translation += change; } prevMouseDragLocation = currentLocation; }; MouseInput.Instance.MouseMoveEvent += delegate(Point mouseLocation) { curMouseLocation = mouseLocation; }; MouseInput.Instance.MouseReleaseEvent += delegate(int button, Point mouseLocation) { prevMouseDragLocation.X = -1; }; isAvailable = true; }
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 <VertexPositionNormalTexture> vertices = new List <VertexPositionNormalTexture>(); 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++) { VertexPositionNormalTexture vert = new VertexPositionNormalTexture(); 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); vert.TextureCoordinate = new Vector2( (float)Math.Asin(vert.Normal.X) / MathHelper.Pi + 0.5f, (float)Math.Asin(vert.Normal.Y) / MathHelper.Pi + 0.5f); vertices.Add(vert); } } // Add north pole vertex vertices.Add(new VertexPositionNormalTexture(Vector3Helper.Get(0, radius, 0), Vector3Helper.Get(0, 1, 0), new Vector2( (float)Math.Asin(0) / MathHelper.Pi + 0.5f, (float)Math.Asin(1) / MathHelper.Pi + 0.5f))); // Add south pole vertex vertices.Add(new VertexPositionNormalTexture(Vector3Helper.Get(0, -radius, 0), Vector3Helper.Get(0, -1, 0), new Vector2( (float)Math.Asin(0) / MathHelper.Pi + 0.5f, (float)Math.Asin(-1) / MathHelper.Pi + 0.5f))); mesh.VertexDeclaration = VertexPositionNormalTexture.VertexDeclaration; mesh.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormalTexture), 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); }
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); }
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); }
private void CreatePlane(float xdim, float ydim, float texCoordX, float texCoordY, float texCoordWidth, float texCoordHeight) { customMesh = new CustomMesh(); VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[4]; Vector3 halfExtent = new Vector3(); halfExtent.X = xdim / 2; halfExtent.Y = ydim / 2; Vector3 v0 = Vector3Helper.Get(-halfExtent.X, 0, -halfExtent.Y); Vector3 v1 = Vector3Helper.Get(halfExtent.X, 0, -halfExtent.Y); Vector3 v2 = Vector3Helper.Get(-halfExtent.X, 0, halfExtent.Y); Vector3 v3 = Vector3Helper.Get(halfExtent.X, 0, halfExtent.Y); this.vertices.Add(v0); this.vertices.Add(v1); this.vertices.Add(v2); this.vertices.Add(v3); Vector3 pY = Vector3.UnitY; vertices[0].Position = v0; vertices[1].Position = v1; vertices[2].Position = v2; vertices[3].Position = v3; vertices[0].TextureCoordinate = new Vector2(texCoordX, texCoordY); vertices[1].TextureCoordinate = new Vector2(texCoordX + texCoordWidth, texCoordY); vertices[2].TextureCoordinate = new Vector2(texCoordX, texCoordY + texCoordHeight); vertices[3].TextureCoordinate = new Vector2(texCoordX + texCoordWidth, texCoordY + texCoordHeight); for (int i = 0; i < 4; i++) { vertices[i].Normal = pY; } customMesh.VertexDeclaration = VertexPositionNormalTexture.VertexDeclaration; customMesh.VertexBuffer = new VertexBuffer(State.Device, typeof(VertexPositionNormalTexture), 4, BufferUsage.None); customMesh.VertexBuffer.SetData <VertexPositionNormalTexture>(vertices); short[] indices = new short[6]; indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 2; indices[4] = 1; indices[5] = 3; for (int i = 0; i < indices.Length; ++i) { this.indices.Add(indices[i]); } customMesh.IndexBuffer = new IndexBuffer(State.Device, typeof(short), 6, BufferUsage.None); customMesh.IndexBuffer.SetData(indices); customMesh.NumberOfVertices = 4; customMesh.NumberOfPrimitives = 2; if (this.vertices.Count == 0) { throw new GoblinException("Corrupted model vertices. Failed to calculate MBB."); } else { boundingBox = BoundingBox.CreateFromPoints(this.vertices); boundingSphere = BoundingSphere.CreateFromPoints(this.vertices); if (offsetTransform.Equals(Matrix.Identity)) { offsetTransform.Translation = (boundingBox.Min + boundingBox.Max) / 2; } } }
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); }