Refactor library nodes to be proper TrackObjects, allows animating them with curves

This commit is contained in:
Marianne Gagnon
2014-10-18 19:11:24 -04:00
parent e23aba65f4
commit 9b46cdc981
7 changed files with 128 additions and 84 deletions

View File

@@ -122,3 +122,17 @@ scene::IMesh* ModelDefinitionLoader::getFirstMeshFor(const std::string& name)
{
return irr_driver->getMesh(m_lod_groups[name][0].m_model_file);
}
// ----------------------------------------------------------------------------
void ModelDefinitionLoader::cleanLibraryNodesAfterLoad()
{
for (std::map<std::string, XMLNode*>::iterator it = m_library_nodes.begin();
it != m_library_nodes.end(); it++)
{
delete it->second;
file_manager->popTextureSearchPath();
file_manager->popModelSearchPath();
}
}

View File

@@ -68,12 +68,13 @@ struct ModelDefinition
}
};
/** Utility class to load level-of-detail nodes and instaincing nodes
/** Utility class to load level-of-detail nodes and library nodes
* \ingroup tracks
*/
class ModelDefinitionLoader
{
private:
std::map<std::string, XMLNode*> m_library_nodes;
std::map< std::string, std::vector< ModelDefinition > > m_lod_groups;
std::map< std::string, STKInstancedSceneNode* > m_instancing_nodes;
Track* m_track;
@@ -86,8 +87,25 @@ public:
void clear();
scene::IMesh* getFirstMeshFor(const std::string& name);
std::map<std::string, XMLNode*>& getLibraryNodes()
{
return m_library_nodes;
}
void cleanLibraryNodesAfterLoad();
bool containsLibraryNode(const std::string& name) const
{
return m_library_nodes.find(name) != m_library_nodes.end();
}
void addToLibrary(const std::string& name, XMLNode* xml)
{
assert(xml != NULL);
m_library_nodes[name] = xml;
}
}; // ModelDefinitionLoader
#endif // HEADER_LOD_NODE_LOADER_HPP

View File

@@ -1738,18 +1738,9 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
}
}
std::map<std::string, XMLNode*> library_nodes;
loadObjects(root, path, model_def_loader, true, NULL, library_nodes);
loadObjects(root, path, model_def_loader, true, NULL);
// Cleanup library nodes
for (std::map<std::string, XMLNode*>::iterator it = library_nodes.begin();
it != library_nodes.end(); it++)
{
delete it->second;
file_manager->popTextureSearchPath();
file_manager->popModelSearchPath();
}
model_def_loader.cleanLibraryNodesAfterLoad();
// Init all track objects
m_track_object_manager->init();
@@ -1914,8 +1905,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
//-----------------------------------------------------------------------------
void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& model_def_loader,
bool create_lod_definitions, scene::ISceneNode* parent,
std::map<std::string, XMLNode*>& library_nodes)
bool create_lod_definitions, scene::ISceneNode* parent)
{
unsigned int start_position_counter = 0;
@@ -1927,75 +1917,10 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
// The track object was already converted before the loop, and the
// default start was already used, too - so ignore those.
if (name == "track" || name == "default-start") continue;
if (name == "object")
if (name == "object" || name == "library")
{
m_track_object_manager->add(*node, parent, model_def_loader);
}
else if (name == "library")
{
std::string name;
node->get("name", &name);
core::vector3df xyz;
node->get("xyz", &xyz);
core::vector3df hpr;
node->get("hpr", &hpr);
core::vector3df scale;
node->get("scale", &scale);
XMLNode* libroot;
std::string lib_path =
file_manager->getAsset(FileManager::LIBRARY, name)+"/";
bool create_lod_definitions = true;
if (library_nodes.find(name) == library_nodes.end())
{
std::string lib_node_path = lib_path+"node.xml";
libroot = file_manager->createXMLTree(lib_node_path);
if (libroot == NULL)
{
Log::error("Track", "Cannot find library '%s'", lib_node_path.c_str());
continue;
}
file_manager->pushTextureSearchPath(lib_path + "/");
file_manager->pushModelSearchPath (lib_path);
material_manager->pushTempMaterial(lib_path + "/materials.xml");
library_nodes[name] = libroot;
// Load LOD groups
const XMLNode *lod_xml_node = libroot->getNode("lod");
if (lod_xml_node != NULL)
{
for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++)
{
const XMLNode* lod_group_xml = lod_xml_node->getNode(i);
for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
{
model_def_loader.addModelDefinition(lod_group_xml->getNode(j));
}
}
}
}
else
{
libroot = library_nodes[name];
create_lod_definitions = false; // LOD definitions are already created, don't create them again
}
scene::ISceneNode* parent = irr_driver->getSceneManager()->addEmptySceneNode();
#ifdef DEBUG
parent->setName(("libnode_" + name).c_str());
#endif
parent->setPosition(xyz);
parent->setRotation(hpr);
parent->setScale(scale);
parent->updateAbsolutePosition();
loadObjects(libroot, lib_path, model_def_loader, create_lod_definitions, parent, library_nodes);
//m_all_nodes.push_back(parent);
}
else if (name == "water")
{
createWater(*node);

View File

@@ -412,9 +412,6 @@ private:
std::vector<MusicInformation*>& m_music );
void loadCurves(const XMLNode &node);
void handleSky(const XMLNode &root, const std::string &filename);
void loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& lod_loader,
bool create_lod_definitions, scene::ISceneNode* parent,
std::map<std::string, XMLNode*>& library_nodes);
public:
@@ -472,6 +469,9 @@ public:
/** Returns true if this track has easter eggs. */
bool hasEasterEggs() const { return m_has_easter_eggs; }
// ------------------------------------------------------------------------
void loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& lod_loader,
bool create_lod_definitions, scene::ISceneNode* parent);
// ------------------------------------------------------------------------
bool isSoccer () const { return m_is_soccer; }
// ------------------------------------------------------------------------
void loadTrackModel (World* parent,

View File

@@ -132,6 +132,10 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
m_type = "light";
m_presentation = new TrackObjectPresentationLight(xml_node, parent);
}
else if (xml_node.getName() == "library")
{
m_presentation = new TrackObjectPresentationLibraryNode(xml_node, model_def_loader);
}
else if (type == "sfx-emitter")
{
// FIXME: at this time sound emitters are just disabled in multiplayer

View File

@@ -148,6 +148,77 @@ TrackObjectPresentationEmpty::~TrackObjectPresentationEmpty()
// ----------------------------------------------------------------------------
TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
const XMLNode& xml_node,
ModelDefinitionLoader& model_def_loader) :
TrackObjectPresentationSceneNode(xml_node)
{
std::string name;
xml_node.get("name", &name);
m_node = irr_driver->getSceneManager()->addEmptySceneNode();
#ifdef DEBUG
m_node->setName(("libnode_" + name).c_str());
#endif
XMLNode* libroot;
std::string lib_path =
file_manager->getAsset(FileManager::LIBRARY, name) + "/";
bool create_lod_definitions = true;
if (!model_def_loader.containsLibraryNode(name))
{
std::string lib_node_path = lib_path + "node.xml";
libroot = file_manager->createXMLTree(lib_node_path);
if (libroot == NULL)
{
Log::error("TrackObjectPresentationLibraryNode", "Cannot find library '%s'", lib_node_path.c_str());
return;
}
file_manager->pushTextureSearchPath(lib_path + "/");
file_manager->pushModelSearchPath(lib_path);
material_manager->pushTempMaterial(lib_path + "/materials.xml");
model_def_loader.addToLibrary(name, libroot);
// Load LOD groups
const XMLNode *lod_xml_node = libroot->getNode("lod");
if (lod_xml_node != NULL)
{
for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++)
{
const XMLNode* lod_group_xml = lod_xml_node->getNode(i);
for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++)
{
model_def_loader.addModelDefinition(lod_group_xml->getNode(j));
}
}
}
}
else
{
libroot = model_def_loader.getLibraryNodes()[name];
assert(libroot != NULL);
create_lod_definitions = false; // LOD definitions are already created, don't create them again
}
m_node->setPosition(m_init_xyz);
m_node->setRotation(m_init_hpr);
m_node->setScale(m_init_scale);
m_node->updateAbsolutePosition();
assert(libroot != NULL);
World::getWorld()->getTrack()->loadObjects(libroot, lib_path, model_def_loader,
create_lod_definitions, m_node);
}
TrackObjectPresentationLibraryNode::~TrackObjectPresentationLibraryNode()
{
irr_driver->removeNode(m_node);
}
// ----------------------------------------------------------------------------
TrackObjectPresentationLOD::TrackObjectPresentationLOD(const XMLNode& xml_node,
scene::ISceneNode* parent, ModelDefinitionLoader& model_def_loader) :
TrackObjectPresentationSceneNode(xml_node)

View File

@@ -152,6 +152,18 @@ public:
virtual ~TrackObjectPresentationEmpty();
};
/**
* \ingroup tracks
* A track object representation that is a library node
*/
class TrackObjectPresentationLibraryNode : public TrackObjectPresentationSceneNode
{
public:
TrackObjectPresentationLibraryNode(const XMLNode& xml_node,
ModelDefinitionLoader& model_def_loader);
virtual ~TrackObjectPresentationLibraryNode();
};
/**
* \ingroup tracks