263 StdMeshXML xml(filename ? filename :
"<unknown>", xml_data);
265 std::unique_ptr<StdMesh> mesh(
new StdMesh);
267 TiXmlElement* mesh_elem = xml.RequireFirstChild(
nullptr,
"mesh");
270 TiXmlElement* sharedgeometry_elem = mesh_elem->FirstChildElement(
"sharedgeometry");
271 if(sharedgeometry_elem !=
nullptr)
272 xml.LoadGeometry(*mesh, mesh->SharedVertices, sharedgeometry_elem);
274 TiXmlElement* submeshes_elem = xml.RequireFirstChild(mesh_elem,
"submeshes");
276 TiXmlElement* submesh_elem_base = xml.RequireFirstChild(submeshes_elem,
"submesh");
277 for (TiXmlElement* submesh_elem = submesh_elem_base; submesh_elem !=
nullptr; submesh_elem = submesh_elem->NextSiblingElement(
"submesh"))
282 const char* material = xml.RequireStrAttribute(submesh_elem,
"material");
283 submesh.Material = manager.GetMaterial(material);
284 if (!submesh.Material)
285 xml.Error(
FormatString(
"There is no such material named '%s'", material), submesh_elem);
287 const char* usesharedvertices = submesh_elem->Attribute(
"usesharedvertices");
288 const std::vector<StdMesh::Vertex>* vertices;
289 if(!usesharedvertices || strcmp(usesharedvertices,
"true") != 0)
291 TiXmlElement* geometry_elem = xml.RequireFirstChild(submesh_elem,
"geometry");
292 xml.LoadGeometry(*mesh, submesh.Vertices, geometry_elem);
293 vertices = &submesh.Vertices;
297 if(mesh->SharedVertices.empty())
298 xml.Error(
StdCopyStrBuf(
"Submesh specifies to use shared vertices but there is no shared geometry"), submesh_elem);
299 vertices = &mesh->SharedVertices;
302 TiXmlElement* faces_elem = xml.RequireFirstChild(submesh_elem,
"faces");
303 int FaceCount = xml.RequireIntAttribute(faces_elem,
"count");
304 submesh.Faces.resize(FaceCount);
307 for (TiXmlElement* face_elem = faces_elem->FirstChildElement(
"face"); face_elem !=
nullptr && i < submesh.Faces.size(); face_elem = face_elem->NextSiblingElement(
"face"), ++i)
311 v[0] = xml.RequireIntAttribute(face_elem,
"v1");
312 v[1] = xml.RequireIntAttribute(face_elem,
"v2");
313 v[2] = xml.RequireIntAttribute(face_elem,
"v3");
315 for (
unsigned int j = 0; j < 3; ++j)
317 if (v[j] < 0 ||
static_cast<unsigned int>(v[j]) >= vertices->size())
318 xml.Error(
FormatString(
"Vertex index v%u (%d) is out of range", j+1, v[j]), face_elem);
319 submesh.Faces[i].Vertices[j] = v[j];
326 if(mesh->BoundingBox.x1 == mesh->BoundingBox.x2 || mesh->BoundingBox.y1 == mesh->BoundingBox.y2)
327 xml.Error(
StdCopyStrBuf(
"Bounding box is empty"), mesh_elem);
330 TiXmlElement* skeletonlink_elem = mesh_elem->FirstChildElement(
"skeletonlink");
331 if (skeletonlink_elem)
333 const char* name = xml.RequireStrAttribute(skeletonlink_elem,
"name");
334 StdCopyStrBuf xml_filename(name); xml_filename.Append(
".xml");
339 mesh->Skeleton = skel_loader.GetSkeletonByName(skeleton_filename);
340 if (!mesh->Skeleton) xml.Error(
FormatString(
"Failed to load '%s'", skeleton_filename.
getData()), skeletonlink_elem);
343 if (sharedgeometry_elem)
345 TiXmlElement* boneassignments_elem = xml.RequireFirstChild(mesh_elem,
"boneassignments");
346 xml.LoadBoneAssignments(*mesh, mesh->SharedVertices, boneassignments_elem);
350 unsigned int submesh_index = 0;
351 for (TiXmlElement* submesh_elem = submesh_elem_base; submesh_elem !=
nullptr; submesh_elem = submesh_elem->NextSiblingElement(
"submesh"), ++submesh_index)
353 StdSubMesh& submesh = mesh->SubMeshes[submesh_index];
354 if (!submesh.Vertices.empty())
356 TiXmlElement* boneassignments_elem = xml.RequireFirstChild(submesh_elem,
"boneassignments");
357 xml.LoadBoneAssignments(*mesh, submesh.Vertices, boneassignments_elem);
366 for (TiXmlElement* submesh_elem = submesh_elem_base; submesh_elem !=
nullptr; submesh_elem = submesh_elem->NextSiblingElement(
"submesh"))
368 TiXmlElement* boneassignments_elem = submesh_elem->FirstChildElement(
"boneassignments");
369 if (boneassignments_elem)
370 xml.Error(
StdStrBuf(
"Mesh has bone assignments, but no skeleton"), boneassignments_elem);
373 TiXmlElement* boneassignments_elem = mesh_elem->FirstChildElement(
"boneassignments");
374 if (boneassignments_elem)
375 xml.Error(
StdStrBuf(
"Mesh has bone assignments, but no skeleton"), boneassignments_elem);
378 return mesh.release();
StdStrBuf FormatString(const char *szFmt,...)