Exemple #1
0
        /// <summary>
        /// Creates a <see cref="VertexBuffer"/> filled with <see cref="VertexPositionNormal"/> vertices forming a cylinder.
        /// </summary>
        /// <remarks>
        /// Draw with an INDEXED TriangleList.  The values to use are as follows:
        /// Vertex Count    = slices * (stacks + 1) + 2
        /// Primitive Count = slices * (stacks + 1) * 2
        /// </remarks>
        /// <param name="device">The <see cref="GraphicsDevice"/> that is associated with the created cylinder.</param>
        /// <param name="bottomRadius">Radius at the negative Y end. Value should be greater than or equal to 0.0f.</param>
        /// <param name="topRadius">Radius at the positive Y end. Value should be greater than or equal to 0.0f.</param>
        /// <param name="length">Length of the cylinder along the Y-axis.</param>
        /// <param name="slices">Number of slices about the Y axis.</param>
        /// <param name="stacks">Number of stacks along the Y axis.</param>
        public static Shape3D CreateCylinder(GraphicsDevice device, float bottomRadius, float topRadius, float length, int slices, int stacks)
        {
            // if both the top and bottom have a radius of zero, just return null, because invalid
            if (bottomRadius <= 0 && topRadius <= 0)
            {
                return(null);
            }

            Shape3D shape         = new Shape3D();
            float   sliceStep     = MathHelper.TwoPi / slices;
            float   heightStep    = length / stacks;
            float   radiusStep    = (topRadius - bottomRadius) / stacks;
            float   currentHeight = -length / 2;
            int     vertexCount   = (stacks + 1) * slices + 2; //cone = stacks * slices + 1
            int     triangleCount = (stacks + 1) * slices * 2; //cone = stacks * slices * 2 + slices
            int     indexCount    = triangleCount * 3;
            float   currentRadius = bottomRadius;

            VertexPositionNormal[] vertices = new VertexPositionNormal[vertexCount];

            // Start at the bottom of the cylinder
            int currentVertex = 0;

            vertices[currentVertex++] = new VertexPositionNormal(new Vector3(0, currentHeight, 0), Vector3.Down);
            for (int i = 0; i <= stacks; i++)
            {
                float sliceAngle = 0;
                for (int j = 0; j < slices; j++)
                {
                    float x = currentRadius * (float)Math.Cos(sliceAngle);
                    float y = currentHeight;
                    float z = currentRadius * (float)Math.Sin(sliceAngle);

                    Vector3 position = new Vector3(x, y, z);
                    vertices[currentVertex++] = new VertexPositionNormal(position, Vector3.Normalize(position));

                    sliceAngle += sliceStep;
                }
                currentHeight += heightStep;
                currentRadius += radiusStep;
            }
            vertices[currentVertex++] = new VertexPositionNormal(new Vector3(0, length / 2, 0), Vector3.Up);

            // Create the actual vertex buffer object
            shape.VertexBuffer = new VertexBuffer(device, VertexPositionNormal.SizeInBytes * vertices.Length, BufferUsage.None);
            shape.VertexBuffer.SetData <VertexPositionNormal>(vertices);

            shape.IndexBuffer = CreateIndexBuffer(device, vertexCount, indexCount, slices);

            shape.VertexCount       = vertexCount;
            shape.TriangleCount     = triangleCount;
            shape.VertexDeclaration = new VertexDeclaration(device, VertexPositionNormal.VertexElements);
            shape.VertexSizeInBytes = VertexPositionNormal.SizeInBytes;

            return(shape);
        }
Exemple #2
0
        /// <summary>
        /// Creates a <see cref="VertexBuffer"/> filled with <see cref="VertexPositionNormal"/> vertices forming a sphere.
        /// </summary>
        /// <remarks>
        /// Draw with an INDEXED TriangleList.  The values to use are as follows:
        /// Vertex Count    = slices * (stacks - 1) + 2
        /// Primitive Count = slices * (stacks - 1) * 2
        /// </remarks>
        /// <param name="device">The <see cref="GraphicsDevice"/> that is associated with the created sphere.</param>
        /// <param name="radius">Radius of the sphere. This value should be greater than or equal to 0.0f.</param>
        /// <param name="slices">Number of slices about the Y axis.</param>
        /// <param name="stacks">Number of stacks along the Y axis. Should be 2 or greater. (stack of 1 is just a cylinder)</param>
        public static Shape3D CreateSphere(GraphicsDevice device, float radius, int slices, int stacks)
        {
            Shape3D shape         = new Shape3D();
            float   sliceStep     = MathHelper.TwoPi / slices;
            float   stackStep     = MathHelper.Pi / stacks;
            int     vertexCount   = slices * (stacks - 1) + 2;
            int     triangleCount = slices * (stacks - 1) * 2;
            int     indexCount    = triangleCount * 3;

            VertexPositionNormal[] sphereVertices = new VertexPositionNormal[vertexCount];

            int currentVertex = 0;

            sphereVertices[currentVertex++] = new VertexPositionNormal(new Vector3(0, -radius, 0), Vector3.Down);
            float stackAngle = MathHelper.Pi - stackStep;

            for (int i = 0; i < stacks - 1; i++)
            {
                float sliceAngle = 0;
                for (int j = 0; j < slices; j++)
                {
                    //NOTE: y and z were switched from normal spherical coordinates because the sphere is "oriented" along the Y axis as opposed to the Z axis
                    float x = (float)(radius * Math.Sin(stackAngle) * Math.Cos(sliceAngle));
                    float y = (float)(radius * Math.Cos(stackAngle));
                    float z = (float)(radius * Math.Sin(stackAngle) * Math.Sin(sliceAngle));

                    Vector3 position = new Vector3(x, y, z);
                    sphereVertices[currentVertex++] = new VertexPositionNormal(position, Vector3.Normalize(position));

                    sliceAngle += sliceStep;
                }
                stackAngle -= stackStep;
            }
            sphereVertices[currentVertex++] = new VertexPositionNormal(new Vector3(0, radius, 0), Vector3.Up);

            // Create the actual vertex buffer
            shape.VertexBuffer = new VertexBuffer(device, VertexPositionNormal.SizeInBytes * sphereVertices.Length, BufferUsage.None);
            shape.VertexBuffer.SetData <VertexPositionNormal>(sphereVertices);

            shape.IndexBuffer = CreateIndexBuffer(device, vertexCount, indexCount, slices);

            shape.VertexCount       = vertexCount;
            shape.TriangleCount     = triangleCount;
            shape.VertexDeclaration = new VertexDeclaration(device, VertexPositionNormal.VertexElements);
            shape.VertexSizeInBytes = VertexPositionNormal.SizeInBytes;

            return(shape);
        }
Exemple #3
0
        /// <summary>
        /// Creates a <see cref="VertexBuffer"/> filled with <see cref="VertexPositionNormal"/> vertices forming a box.
        /// </summary>
        /// <remarks>Always draw using a non-indexed TriangleList of 12 primitives.</remarks>
        /// <param name="device">The <see cref="GraphicsDevice"/> that is associated with the created box.</param>
        /// <param name="width">Width of the box, along the x-axis.</param>
        /// <param name="height">Height of the box, along the y-axis.</param>
        /// <param name="depth">Depth of the box, along the z-axis.</param>
        public static Shape3D CreateBox(GraphicsDevice device, float width, float height, float depth)
        {
            Shape3D shape = new Shape3D();

            // Because the box is centered at the origin, need to divide by two to find the + and - offsets
            width  = width / 2.0f;
            height = height / 2.0f;
            depth  = depth / 2.0f;

            VertexPositionNormal[] cubeVertices = new VertexPositionNormal[36];

            Vector3 topLeftFront     = new Vector3(-width, height, depth);
            Vector3 bottomLeftFront  = new Vector3(-width, -height, depth);
            Vector3 topRightFront    = new Vector3(width, height, depth);
            Vector3 bottomRightFront = new Vector3(width, -height, depth);
            Vector3 topLeftBack      = new Vector3(-width, height, -depth);
            Vector3 topRightBack     = new Vector3(width, height, -depth);
            Vector3 bottomLeftBack   = new Vector3(-width, -height, -depth);
            Vector3 bottomRightBack  = new Vector3(width, -height, -depth);

            Vector3 frontNormal  = new Vector3(0.0f, 0.0f, 1.0f);
            Vector3 backNormal   = new Vector3(0.0f, 0.0f, -1.0f);
            Vector3 topNormal    = new Vector3(0.0f, 1.0f, 0.0f);
            Vector3 bottomNormal = new Vector3(0.0f, -1.0f, 0.0f);
            Vector3 leftNormal   = new Vector3(-1.0f, 0.0f, 0.0f);
            Vector3 rightNormal  = new Vector3(1.0f, 0.0f, 0.0f);

            // Front face.
            cubeVertices[1] = new VertexPositionNormal(topLeftFront, frontNormal);
            cubeVertices[0] = new VertexPositionNormal(bottomLeftFront, frontNormal);
            cubeVertices[2] = new VertexPositionNormal(topRightFront, frontNormal);
            cubeVertices[4] = new VertexPositionNormal(bottomLeftFront, frontNormal);
            cubeVertices[3] = new VertexPositionNormal(bottomRightFront, frontNormal);
            cubeVertices[5] = new VertexPositionNormal(topRightFront, frontNormal);

            // Back face.
            cubeVertices[7]  = new VertexPositionNormal(topLeftBack, backNormal);
            cubeVertices[6]  = new VertexPositionNormal(topRightBack, backNormal);
            cubeVertices[8]  = new VertexPositionNormal(bottomLeftBack, backNormal);
            cubeVertices[10] = new VertexPositionNormal(bottomLeftBack, backNormal);
            cubeVertices[9]  = new VertexPositionNormal(topRightBack, backNormal);
            cubeVertices[11] = new VertexPositionNormal(bottomRightBack, backNormal);

            // Top face.
            cubeVertices[13] = new VertexPositionNormal(topLeftFront, topNormal);
            cubeVertices[12] = new VertexPositionNormal(topRightBack, topNormal);
            cubeVertices[14] = new VertexPositionNormal(topLeftBack, topNormal);
            cubeVertices[16] = new VertexPositionNormal(topLeftFront, topNormal);
            cubeVertices[15] = new VertexPositionNormal(topRightFront, topNormal);
            cubeVertices[17] = new VertexPositionNormal(topRightBack, topNormal);

            // Bottom face.
            cubeVertices[19] = new VertexPositionNormal(bottomLeftFront, bottomNormal);
            cubeVertices[18] = new VertexPositionNormal(bottomLeftBack, bottomNormal);
            cubeVertices[20] = new VertexPositionNormal(bottomRightBack, bottomNormal);
            cubeVertices[22] = new VertexPositionNormal(bottomLeftFront, bottomNormal);
            cubeVertices[21] = new VertexPositionNormal(bottomRightBack, bottomNormal);
            cubeVertices[23] = new VertexPositionNormal(bottomRightFront, bottomNormal);

            // Left face.
            cubeVertices[25] = new VertexPositionNormal(topLeftFront, leftNormal);
            cubeVertices[24] = new VertexPositionNormal(bottomLeftBack, leftNormal);
            cubeVertices[26] = new VertexPositionNormal(bottomLeftFront, leftNormal);
            cubeVertices[28] = new VertexPositionNormal(topLeftBack, leftNormal);
            cubeVertices[27] = new VertexPositionNormal(bottomLeftBack, leftNormal);
            cubeVertices[29] = new VertexPositionNormal(topLeftFront, leftNormal);

            // Right face.
            cubeVertices[31] = new VertexPositionNormal(topRightFront, rightNormal);
            cubeVertices[30] = new VertexPositionNormal(bottomRightFront, rightNormal);
            cubeVertices[32] = new VertexPositionNormal(bottomRightBack, rightNormal);
            cubeVertices[34] = new VertexPositionNormal(topRightBack, rightNormal);
            cubeVertices[33] = new VertexPositionNormal(topRightFront, rightNormal);
            cubeVertices[35] = new VertexPositionNormal(bottomRightBack, rightNormal);

            // Create the actual vertex buffer
            shape.VertexBuffer = new VertexBuffer(device, VertexPositionNormal.SizeInBytes * cubeVertices.Length, BufferUsage.None);
            shape.VertexBuffer.SetData <VertexPositionNormal>(cubeVertices);

            shape.VertexCount       = 36;
            shape.TriangleCount     = 12;
            shape.VertexDeclaration = new VertexDeclaration(device, VertexPositionNormal.VertexElements);
            shape.VertexSizeInBytes = VertexPositionNormal.SizeInBytes;

            return(shape);
        }