/// <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" }); }