Ejemplo n.º 1
0
int
main (int argc, char **argv)
{
	google::InitGoogleLogging(argv[0]);
	if (argc == 2)
	{
		std::string xml_filename(argv[1]);
		nCache::nCacheLoader cache_loader;
		cache_loader.process(xml_filename);
	}
	else
	{
		std::cerr << boost::format("Usage : %1% <ncache xml>") % argv[0] << std::endl;
		return 1;
	}
	return 0;
}
Ejemplo n.º 2
0
StdMesh *StdMeshLoader::LoadMeshXml(const char* xml_data, size_t size, const StdMeshMatManager& manager, StdMeshSkeletonLoader& skel_loader, const char* filename)
{
	StdMeshXML xml(filename ? filename : "<unknown>", xml_data);

	std::unique_ptr<StdMesh> mesh(new StdMesh);

	TiXmlElement* mesh_elem = xml.RequireFirstChild(NULL, "mesh");

	// Load shared geometry, if any
	TiXmlElement* sharedgeometry_elem = mesh_elem->FirstChildElement("sharedgeometry");
	if(sharedgeometry_elem != NULL)
		xml.LoadGeometry(*mesh, mesh->SharedVertices, sharedgeometry_elem);

	TiXmlElement* submeshes_elem = xml.RequireFirstChild(mesh_elem, "submeshes");

	TiXmlElement* submesh_elem_base = xml.RequireFirstChild(submeshes_elem, "submesh");
	for (TiXmlElement* submesh_elem = submesh_elem_base; submesh_elem != NULL; submesh_elem = submesh_elem->NextSiblingElement("submesh"))
	{
		mesh->SubMeshes.push_back(StdSubMesh());
		StdSubMesh& submesh = mesh->SubMeshes.back();

		const char* material = xml.RequireStrAttribute(submesh_elem, "material");
		submesh.Material = manager.GetMaterial(material);
		if (!submesh.Material)
			xml.Error(FormatString("There is no such material named '%s'", material), submesh_elem);

		const char* usesharedvertices = submesh_elem->Attribute("usesharedvertices");
		const std::vector<StdMesh::Vertex>* vertices;
		if(!usesharedvertices || strcmp(usesharedvertices, "true") != 0)
		{
			TiXmlElement* geometry_elem = xml.RequireFirstChild(submesh_elem, "geometry");
			xml.LoadGeometry(*mesh, submesh.Vertices, geometry_elem);
			vertices = &submesh.Vertices;
		}
		else
		{
			if(mesh->SharedVertices.empty())
				xml.Error(StdCopyStrBuf("Submesh specifies to use shared vertices but there is no shared geometry"), submesh_elem);
			vertices = &mesh->SharedVertices;
		}

		TiXmlElement* faces_elem = xml.RequireFirstChild(submesh_elem, "faces");
		int FaceCount = xml.RequireIntAttribute(faces_elem, "count");
		submesh.Faces.resize(FaceCount);

		unsigned int i = 0;
		for (TiXmlElement* face_elem = faces_elem->FirstChildElement("face"); face_elem != NULL && i < submesh.Faces.size(); face_elem = face_elem->NextSiblingElement("face"), ++i)
		{
			int v[3];

			v[0] = xml.RequireIntAttribute(face_elem, "v1");
			v[1] = xml.RequireIntAttribute(face_elem, "v2");
			v[2] = xml.RequireIntAttribute(face_elem, "v3");

			for (unsigned int j = 0; j < 3; ++j)
			{
				if (v[j] < 0 || static_cast<unsigned int>(v[j]) >= vertices->size())
					xml.Error(FormatString("Vertex index v%u (%d) is out of range", j+1, v[j]), face_elem);
				submesh.Faces[i].Vertices[j] = v[j];
			}
		}
	}

	// We allow bounding box to be empty if it's only due to Z direction since
	// this is what goes inside the screen in Clonk.
	if(mesh->BoundingBox.x1 == mesh->BoundingBox.x2 || mesh->BoundingBox.y1 == mesh->BoundingBox.y2)
		xml.Error(StdCopyStrBuf("Bounding box is empty"), mesh_elem);

	// Read skeleton, if any
	TiXmlElement* skeletonlink_elem = mesh_elem->FirstChildElement("skeletonlink");
	if (skeletonlink_elem)
	{
		const char* name = xml.RequireStrAttribute(skeletonlink_elem, "name");
		StdCopyStrBuf xml_filename(name); xml_filename.Append(".xml");

		StdCopyStrBuf skeleton_filename;
		StdMeshSkeletonLoader::MakeFullSkeletonPath(skeleton_filename, filename, xml_filename.getData());

		mesh->Skeleton = skel_loader.GetSkeletonByName(skeleton_filename);
		if (!mesh->Skeleton) xml.Error(FormatString("Failed to load '%s'", skeleton_filename.getData()), skeletonlink_elem);

		// Vertex<->Bone assignments for shared geometry
		if (sharedgeometry_elem)
		{
			TiXmlElement* boneassignments_elem = xml.RequireFirstChild(mesh_elem, "boneassignments");
			xml.LoadBoneAssignments(*mesh, mesh->SharedVertices, boneassignments_elem);
		}

		// Vertex<->Bone assignments for all vertices (need to go through SubMeshes again...)
		unsigned int submesh_index = 0;
		for (TiXmlElement* submesh_elem = submesh_elem_base; submesh_elem != NULL; submesh_elem = submesh_elem->NextSiblingElement("submesh"), ++submesh_index)
		{
			StdSubMesh& submesh = mesh->SubMeshes[submesh_index];
			if (!submesh.Vertices.empty())
			{
				TiXmlElement* boneassignments_elem = xml.RequireFirstChild(submesh_elem, "boneassignments");
				xml.LoadBoneAssignments(*mesh, submesh.Vertices, boneassignments_elem);
			}
		}
	}
	else
	{
		// Mesh has no skeleton
		// Bone assignements do not make sense then, as the
		// actual bones are defined in the skeleton file.
		for (TiXmlElement* submesh_elem = submesh_elem_base; submesh_elem != NULL; submesh_elem = submesh_elem->NextSiblingElement("submesh"))
		{
			TiXmlElement* boneassignments_elem = submesh_elem->FirstChildElement("boneassignments");
			if (boneassignments_elem)
				xml.Error(StdStrBuf("Mesh has bone assignments, but no skeleton"), boneassignments_elem);
		}

		TiXmlElement* boneassignments_elem = mesh_elem->FirstChildElement("boneassignments");
		if (boneassignments_elem)
			xml.Error(StdStrBuf("Mesh has bone assignments, but no skeleton"), boneassignments_elem);
	}

	return mesh.release();
}