/// <summary>
            /// Creates a cube with six faces each one pointing in a different direction.
            /// </summary>
            /// <param name="size">The size.</param>
            /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param>
            /// <returns>A cube.</returns>
            public static GeometricMeshData <VertexPositionNormalTangentMultiTexture> New(float size = 1.0f, bool toLeftHanded = false)
            {
                var vertices = new VertexPositionNormalTangentMultiTexture[CubeFaceCount * 4];
                var indices  = new int[CubeFaceCount * 6];

                size /= 2.0f;

                int vertexCount = 0;
                int indexCount  = 0;

                // Create each face in turn.
                for (int i = 0; i < CubeFaceCount; i++)
                {
                    Vector3 normal = faceNormals[i];

                    // Get two vectors perpendicular both to the face normal and to each other.
                    Vector3 basis = (i >= 4) ? Vector3.UnitZ : Vector3.UnitY;

                    Vector3 side1;
                    Vector3.Cross(ref normal, ref basis, out side1);

                    Vector3 side2;
                    Vector3.Cross(ref normal, ref side1, out side2);

                    // Six indices (two triangles) per face.
                    int vbase = i * 4;
                    indices[indexCount++] = (vbase + 0);
                    indices[indexCount++] = (vbase + 1);
                    indices[indexCount++] = (vbase + 2);

                    indices[indexCount++] = (vbase + 0);
                    indices[indexCount++] = (vbase + 2);
                    indices[indexCount++] = (vbase + 3);

                    // Four vertices per face.
                    vertices[vertexCount++] = new VertexPositionNormalTangentMultiTexture((normal - side1 - side2) * size, normal, new Vector4(-side1, 0), textureCoordinates[0]);
                    vertices[vertexCount++] = new VertexPositionNormalTangentMultiTexture((normal - side1 + side2) * size, normal, new Vector4(-side1, 0), textureCoordinates[1]);
                    vertices[vertexCount++] = new VertexPositionNormalTangentMultiTexture((normal + side1 + side2) * size, normal, new Vector4(-side1, 0), textureCoordinates[2]);
                    vertices[vertexCount++] = new VertexPositionNormalTangentMultiTexture((normal + side1 - side2) * size, normal, new Vector4(-side1, 0), textureCoordinates[3]);
                }

                // Create the primitive object.
                return(new GeometricMeshData <VertexPositionNormalTangentMultiTexture>(vertices, indices, toLeftHanded)
                {
                    Name = "Cube"
                });
            }
            /// <summary>
            /// Creates a sphere primitive.
            /// </summary>
            /// <param name="diameter">The diameter.</param>
            /// <param name="tessellation">The tessellation.</param>
            /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param>
            /// <returns>A sphere primitive.</returns>
            /// <exception cref="System.ArgumentOutOfRangeException">tessellation;Must be >= 3</exception>
            public static GeometricMeshData <VertexPositionNormalTangentMultiTexture> New(float diameter = 1.0f, int tessellation = 16, bool toLeftHanded = false)
            {
                if (tessellation < 3)
                {
                    throw new ArgumentOutOfRangeException("tessellation", "Must be >= 3");
                }

                int verticalSegments   = tessellation;
                int horizontalSegments = tessellation * 2;

                var vertices = new VertexPositionNormalTangentMultiTexture[(verticalSegments + 1) * (horizontalSegments + 1)];
                var indices  = new int[(verticalSegments) * (horizontalSegments + 1) * 6];

                float radius = diameter / 2;

                int vertexCount = 0;

                // Create rings of vertices at progressively higher latitudes.
                for (int i = 0; i <= verticalSegments; i++)
                {
                    float v = 1.0f - (float)i / verticalSegments;

                    var latitude = (float)((i * Math.PI / verticalSegments) - Math.PI / 2.0);
                    var dy       = (float)Math.Sin(latitude);
                    var dxz      = (float)Math.Cos(latitude);

                    // Create a single ring of vertices at this latitude.
                    for (int j = 0; j <= horizontalSegments; j++)
                    {
                        float u = (float)j / horizontalSegments;

                        var longitude = (float)(j * 2.0 * Math.PI / horizontalSegments);
                        var dx        = (float)Math.Sin(longitude);
                        var dz        = (float)Math.Cos(longitude);

                        dx *= dxz;
                        dz *= dxz;

                        var normal            = new Vector3(dx, dy, dz);
                        var textureCoordinate = new Vector2(u, v);

                        var tangent = new Vector4(normal.Z, 0, -normal.X, 0); // Y ^ normal
                        vertices[vertexCount++] = new VertexPositionNormalTangentMultiTexture(normal * radius, normal, tangent, textureCoordinate);
                    }
                }

                // Fill the index buffer with triangles joining each pair of latitude rings.
                int stride = horizontalSegments + 1;

                int indexCount = 0;

                for (int i = 0; i < verticalSegments; i++)
                {
                    for (int j = 0; j <= horizontalSegments; j++)
                    {
                        int nextI = i + 1;
                        int nextJ = (j + 1) % stride;

                        indices[indexCount++] = (i * stride + j);
                        indices[indexCount++] = (nextI * stride + j);
                        indices[indexCount++] = (i * stride + nextJ);

                        indices[indexCount++] = (i * stride + nextJ);
                        indices[indexCount++] = (nextI * stride + j);
                        indices[indexCount++] = (nextI * stride + nextJ);
                    }
                }

                // Create the primitive object.
                // Create the primitive object.
                return(new GeometricMeshData <VertexPositionNormalTangentMultiTexture>(vertices, indices, toLeftHanded)
                {
                    Name = "Sphere"
                });
            }