private static async Task <IReadOnlyList <Primitive> > ReadPrimitives(BufferedReader reader, int materialsCount, int vertexCount) { var primitives = new List <Primitive>(); while (true) { var token = await reader.ReadInt16().ConfigureAwait(false); if (token == (short)Token.EndMesh) { return(primitives); } var primitiveType = (PrimitiveType)token; if (!Enum.IsDefined(primitiveType)) { throw new CmodException("Unknown primitive type"); } var materialIndex = await reader.ReadInt32().ConfigureAwait(false); if (materialIndex < 0 || materialIndex >= materialsCount) { throw new CmodException("Material index out of range"); } var indexCount = await reader.ReadInt32().ConfigureAwait(false); if (indexCount <= 0) { throw new CmodException("Index count out of range"); } var primitive = new Primitive(primitiveType, materialIndex, indexCount); for (var i = 0; i < indexCount; ++i) { var index = await reader.ReadInt32().ConfigureAwait(false); if (index < 0 || index >= vertexCount) { throw new CmodException("Index out of range"); } primitive.Indices.Add(index); } primitives.Add(primitive); } }
private static async Task <IReadOnlyList <VertexAttribute> > ReadVertexDescription(BufferedReader reader) { if (await reader.ReadToken().ConfigureAwait(false) != Token.VertexDesc) { throw new CmodException("Expected vertex description"); } var attributes = new List <VertexAttribute>(); while (true) { var token = await reader.ReadInt16().ConfigureAwait(false); if (token == (short)Token.EndVertexDesc) { return(attributes); } var attribute = (AttributeType)token; if (!Enum.IsDefined(attribute)) { throw new CmodException("Unknown vertex attribute"); } if (attributes.Any(a => a.AttributeType == attribute)) { throw new CmodException("Duplicate vertex attribute"); } var format = await reader.ReadAttributeFormat().ConfigureAwait(false); if (!Enum.IsDefined(format)) { throw new CmodException("Invalid attribute format"); } attributes.Add(VertexAttribute.Create(attribute, format)); } }