Exemplo n.º 1
0
      //разбор примитива
    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);
    }