//разбор примитива void ParsePrimitive (Parser::Iterator primitive_iter, Mesh& mesh) { static const char* METHOD_NAME = "media::geometry::XmlMeshLibraryLoader::ParsePrimitive"; const char* type_string = get<const char*> (*primitive_iter, "type"); PrimitiveType type = get_primitive_type (type_string); const char* material = get<const char*> (*primitive_iter, "material", ""); unsigned int vertex_buffer_index = get<unsigned int> (*primitive_iter, "vertex_buffer"), first = get<unsigned int> (*primitive_iter, "first"), count = get<unsigned int> (*primitive_iter, "count"), base_vertex = get<unsigned int> (*primitive_iter, "base_vertex", 0u); if (type >= PrimitiveType_Num) throw xtl::make_argument_exception (METHOD_NAME, "type", type_string); if (vertex_buffer_index >= mesh.VertexBuffersCount ()) throw xtl::make_range_exception (METHOD_NAME, "vertex_buffer", vertex_buffer_index, mesh.VertexBuffersCount ()); const VertexBuffer& vertex_buffer = mesh.VertexBuffer (vertex_buffer_index); unsigned int vertices_count = vertex_buffer.VerticesCount (), indices_count = mesh.IndexBuffer ().Size (), max_primitives_count = 0, max_count = indices_count ? indices_count : vertices_count; if (first > max_count) throw xtl::make_range_exception (METHOD_NAME, "first", first, max_count); max_count -= first; switch (type) { case PrimitiveType_LineList: max_primitives_count = max_count / 2; break; case media::geometry::PrimitiveType_LineStrip: max_primitives_count = max_count > 1 ? max_count - 1 : 0; break; case media::geometry::PrimitiveType_TriangleList: max_primitives_count = max_count / 3; break; case media::geometry::PrimitiveType_TriangleStrip: max_primitives_count = max_count > 2 ? max_count - 2 : 0; break; case media::geometry::PrimitiveType_TriangleFan: max_primitives_count = max_count > 2 ? max_count - 2 : 0; break; default: break; } if (count > max_primitives_count) throw xtl::make_range_exception (METHOD_NAME, "count", count, max_primitives_count + 1); if (base_vertex >= vertices_count) throw xtl::make_range_exception (METHOD_NAME, "base_vertex", base_vertex, vertices_count); if (!count) { primitive_iter->Log ().Warning (*primitive_iter, "Empty primitive"); return; } mesh.AddPrimitive (type, vertex_buffer_index, first, count, base_vertex, material); }