From 0f97aee66a1be35a51a885c3b72b9c38b11c9cee Mon Sep 17 00:00:00 2001 From: auria Date: Wed, 1 Jan 2014 21:18:06 +0000 Subject: [PATCH] Remove the old LOD loading code, we now support only the new much cleaner way. Will need to re-export all tracks that use LOD, meanwhile LOD objects will be missing from tracks git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14879 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/lod_node_loader.cpp | 186 +++++++---------------- src/tracks/lod_node_loader.hpp | 37 ++--- src/tracks/track.cpp | 90 ++++------- src/tracks/track_object.cpp | 16 +- src/tracks/track_object.hpp | 6 +- src/tracks/track_object_manager.cpp | 33 +--- src/tracks/track_object_manager.hpp | 9 +- src/tracks/track_object_presentation.cpp | 9 +- src/tracks/track_object_presentation.hpp | 5 +- 9 files changed, 129 insertions(+), 262 deletions(-) diff --git a/src/tracks/lod_node_loader.cpp b/src/tracks/lod_node_loader.cpp index abdcca639..d9add8869 100644 --- a/src/tracks/lod_node_loader.cpp +++ b/src/tracks/lod_node_loader.cpp @@ -29,174 +29,104 @@ using namespace irr; #include #include -LodNodeLoader::LodNodeLoader() +LodNodeLoader::LodNodeLoader(Track* track) { + m_track = track; } // ---------------------------------------------------------------------------- -bool PairCompare(const std::pair& i, const std::pair& j) -{ - return (i.first < j.first); -} - -// ---------------------------------------------------------------------------- - -/** Check a XML node in case it contains a LOD object and if so remember it */ -bool LodNodeLoader::check(const XMLNode* xml, scene::ISceneNode* parent) +void LodNodeLoader::addLODModelDefinition(const XMLNode* xml) { float lod_distance = -1.0f; xml->get("lod_distance", &lod_distance); - bool lod_instance = false; - xml->get("lod_instance", &lod_instance); - std::string lodgroup; xml->get("lod_group", &lodgroup); bool tangent = false; xml->get("tangents", &tangent); - if (!lodgroup.empty()) - { - if (lod_instance) - { - lod_instances[lodgroup].push_back(LodInstance(xml, parent)); - } - else - { - std::string model_name; - xml->get("model", &model_name); + std::string model_name; + xml->get("model", &model_name); - lod_groups[lodgroup][(int)lod_distance] = LodModel(xml, model_name, tangent); - } - return true; - } - else - { - return false; - } + m_lod_groups[lodgroup].push_back(LodModel(xml, (int)lod_distance, model_name, tangent)); } // ---------------------------------------------------------------------------- -/** - * Call when the XML file is fully parsed and we're ready to create the node - * @param cache the individual meshes will be added there - * @param[out] out the nodes are added here - */ -void LodNodeLoader::done(Track* track, - std::string directory, - std::vector& cache, - std::vector& out) +LODNode* LodNodeLoader::instanciate(const XMLNode* node, scene::ISceneNode* parent) + //Track* track, std::vector& cache) { scene::ISceneManager* sm = irr_driver->getSceneManager(); - // Creating LOD nodes is more complicated than one might have hoped, on the C++ side; - // but it was done this way to minimize the work needed on the side of the artists + std::string groupname = ""; + node->get("lod_group", &groupname); - // 1. Sort LOD groups (highest detail first, lowest detail last) - std::map > > sorted_lod_groups; + std::vector< LodModel >& group = m_lod_groups[groupname]; - std::map >::iterator it; - for (it = lod_groups.begin(); it != lod_groups.end(); it++) + //core::vector3df xyz(0,0,0); + //node->get("xyz", &xyz); + //core::vector3df hpr(0,0,0); + //node->get("hpr", &hpr); + //core::vector3df scale(1.0f, 1.0f, 1.0f); + //node->get("scale", &scale); + + if (group.size() > 0) { - std::map::iterator it2; - for (it2 = it->second.begin(); it2 != it->second.end(); it2++) + scene::ISceneNode* actual_parent = (parent == NULL ? sm->getRootSceneNode() : parent); + LODNode* lod_node = new LODNode(groupname, actual_parent, sm); + //lod_node->setPosition(xyz); + //lod_node->setRotation(hpr); + //lod_node->setScale(scale); + lod_node->updateAbsolutePosition(); + for (unsigned int m=0; mfirst, it2->second.c_str(), it->first.c_str()); - sorted_lod_groups[it->first].push_back( std::pair(it2->first, it2->second) ); - } - std::sort( sorted_lod_groups[it->first].begin(), sorted_lod_groups[it->first].end(), PairCompare ); + // TODO: check whether the mesh contains animations or not? + scene::IMesh* a_mesh = irr_driver->getMesh(group[m].m_model_file); - //printf("Group '%s' :\n", it->first.c_str()); - //for (unsigned int x=0; xfirst].size(); x++) - //{ - // printf(" - (%i) %s\n", sorted_lod_groups[it->first][x].first, sorted_lod_groups[it->first][x].second.c_str()); - //} - } - - // 2. Read the XML nodes and instanciate LOD scene nodes where relevant - std::string groupname; - std::map< std::string, std::vector< LodInstance > >::iterator it3; - for (it3 = lod_instances.begin(); it3 != lod_instances.end(); it3++) - { - std::vector< std::pair >& group = sorted_lod_groups[it3->first]; - - std::vector< LodInstance >& v = it3->second; - for (unsigned int n=0; nget("lod_group", &groupname); - //if (model_name != sorted_lod_groups[it3->first][0].second) continue; - - core::vector3df xyz(0,0,0); - node->get("xyz", &xyz); - core::vector3df hpr(0,0,0); - node->get("hpr", &hpr); - core::vector3df scale(1.0f, 1.0f, 1.0f); - node->get("scale", &scale); - - if (group.size() > 0) + if (!a_mesh) { - scene::ISceneNode* parent = (v[n].m_parent == NULL ? sm->getRootSceneNode() : v[n].m_parent); - LODNode* lod_node = new LODNode(groupname, parent, sm); - lod_node->setPosition(xyz); - lod_node->setRotation(hpr); - lod_node->setScale(scale); - lod_node->updateAbsolutePosition(); - for (unsigned int m=0; mgetMesh(group[m].second.m_model_file); + Log::warn("LODNodeLoad", "Warning: object model '%s' not found, ignored.\n", + group[m].m_model_file.c_str()); + continue; + } - if (!a_mesh) - { - Log::warn("LODNodeLoad", "Warning: object model '%s' not found, ignored.\n", - group[m].second.m_model_file.c_str()); - continue; - } + if (group[m].m_tangent && a_mesh->getMeshBuffer(0)->getVertexType() != video::EVT_TANGENTS) + { + scene::IMeshManipulator* manip = irr_driver->getVideoDriver()->getMeshManipulator(); + scene::IMesh* m2 = manip->createMeshWithTangents(a_mesh); + // FIXME: do we need to clean up 'a_mesh' ? + a_mesh = m2; + irr_driver->setAllMaterialFlags(a_mesh); + } - if (group[m].second.m_tangent) - { - scene::IMeshManipulator* manip = irr_driver->getVideoDriver()->getMeshManipulator(); - scene::IMesh* m2 = manip->createMeshWithTangents(a_mesh); - // FIXME: do we need to clean up 'a_mesh' ? - a_mesh = m2; - irr_driver->setAllMaterialFlags(a_mesh); + a_mesh->grab(); + //cache.push_back(a_mesh); + irr_driver->grabAllTextures(a_mesh); + scene::IMeshSceneNode* scene_node = irr_driver->addMesh(a_mesh); - } + m_track->handleAnimatedTextures( scene_node, *group[m].m_xml ); - a_mesh->grab(); - cache.push_back(a_mesh); - irr_driver->grabAllTextures(a_mesh); - scene::IMeshSceneNode* scene_node = irr_driver->addMesh(a_mesh); - - track->handleAnimatedTextures( scene_node, *group[m].second.m_xml ); - - lod_node->add( group[m].first, scene_node, true ); - } + lod_node->add( group[m].m_distance, scene_node, true ); + } #ifdef DEBUG - std::string debug_name = groupname+" (LOD track-object)"; - lod_node->setName(debug_name.c_str()); + std::string debug_name = groupname+" (LOD track-object)"; + lod_node->setName(debug_name.c_str()); #endif - out.push_back(lod_node); - } - else - { - fprintf(stderr, "[LodNodeLoader] WARNING, LOD group '%s' is empty\n", groupname.c_str()); - } - } - } // end for + return lod_node; + } + else + { + Log::warn("LodNodeLoader", "LOD group '%s' is empty", groupname.c_str()); + return NULL; + } } // ---------------------------------------------------------------------------- void LodNodeLoader::clear() { - lod_groups.clear(); - lod_instances.clear(); + m_lod_groups.clear(); } diff --git a/src/tracks/lod_node_loader.hpp b/src/tracks/lod_node_loader.hpp index d3c551b15..29e97b747 100644 --- a/src/tracks/lod_node_loader.hpp +++ b/src/tracks/lod_node_loader.hpp @@ -36,43 +36,28 @@ namespace irr } } -struct LodInstance -{ - const XMLNode* m_xml_node; - scene::ISceneNode* m_parent; - - /** Constructor to allow storing this in STL containers */ - LodInstance() - { - m_parent = NULL; - m_xml_node = NULL; - } - - LodInstance(const XMLNode* xml_node, scene::ISceneNode* parent) - { - m_xml_node = xml_node; - m_parent = parent; - } -}; struct LodModel { std::string m_model_file; bool m_tangent; const XMLNode* m_xml; + int m_distance; /** Constructor to allow storing this in STL containers */ LodModel() { m_tangent = false; + m_distance = 0; m_xml = NULL; } - LodModel(const XMLNode* xml, std::string& model, bool tangent) + LodModel(const XMLNode* xml, int distance, std::string& model, bool tangent) { m_model_file = model; m_tangent = tangent; m_xml = xml; + m_distance = distance; } ~LodModel() @@ -86,17 +71,15 @@ struct LodModel class LodNodeLoader { private: - std::map< std::string, std::map< int, LodModel > > lod_groups; - std::map< std::string, std::vector< LodInstance > > lod_instances; + std::map< std::string, std::vector< LodModel > > m_lod_groups; + Track* m_track; public: - LodNodeLoader(); + LodNodeLoader(Track* track); - bool check(const XMLNode* xml, scene::ISceneNode* parent); - void done(Track* track, - std::string directory, - std::vector& cache, - std::vector& out); + void addLODModelDefinition(const XMLNode* xml); + LODNode* instanciate(const XMLNode* xml_node, scene::ISceneNode* parent); + //Track* track, std::vector& cache); void clear(); diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 34e19affc..895f9f7cd 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -854,7 +854,7 @@ bool Track::loadMainTrack(const XMLNode &root) m_aabb_max.setY(m_aabb_max.getY()+30.0f); World::getWorld()->getPhysics()->init(m_aabb_min, m_aabb_max); - LodNodeLoader lodLoader; + LodNodeLoader lodLoader(this); // Load LOD groups const XMLNode *lod_xml_node = root.getNode("lod"); @@ -865,10 +865,7 @@ bool Track::loadMainTrack(const XMLNode &root) const XMLNode* lod_group_xml = lod_xml_node->getNode(i); for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++) { - // TODO: eventually, remove support for the old way of specifying LOD - // definitions among node, and support only the new way of using - // a section. Then, the LOD loading sequence can be simplified a lot - lodLoader.check(lod_group_xml->getNode(j), NULL); + lodLoader.addLODModelDefinition(lod_group_xml->getNode(j)); } } } @@ -1033,7 +1030,8 @@ bool Track::loadMainTrack(const XMLNode &root) std::string challenge; n->get("challenge", &challenge); - bool is_lod = lodLoader.check(n, NULL); + bool lod_instance = false; + n->get("lod_instance", &lod_instance); if (tangent) { @@ -1078,9 +1076,17 @@ bool Track::loadMainTrack(const XMLNode &root) handleAnimatedTextures(scene_node, *n); m_all_nodes.push_back( scene_node ); } - else if (is_lod) + else if (lod_instance) { - // nothing to do + LODNode* node = lodLoader.instanciate(n, NULL); + if (node != NULL) + { + node->setPosition(xyz); + node->setRotation(hpr); + node->setScale(scale); + + m_all_nodes.push_back( node ); + } } else { @@ -1198,16 +1204,6 @@ bool Track::loadMainTrack(const XMLNode &root) } // for i - // Create LOD nodes - std::vector lod_nodes; - lodLoader.done(this, m_root, m_all_cached_meshes, lod_nodes); - for (unsigned int n=0; n library_nodes; - loadObjects(root, path, lod_loader, true, NULL, library_nodes); + LodNodeLoader lod_loader(this); - // -------- Create and assign LOD nodes -------- - // recheck the static area, we will need LOD info - const XMLNode* track_node = root->getNode("track"); - if (track_node != NULL) + // Load LOD groups + const XMLNode *lod_xml_node = root->getNode("lod"); + if (lod_xml_node != NULL) { - for (unsigned int i=0; igetNumNodes(); i++) + for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++) { - const XMLNode* n = track_node->getNode(i); - bool is_instance = false; - n->get("lod_instance", &is_instance); - - if (!is_instance) lod_loader.check(n, NULL); + const XMLNode* lod_group_xml = lod_xml_node->getNode(i); + for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++) + { + lod_loader.addLODModelDefinition(lod_group_xml->getNode(j)); + } } } - std::vector lod_nodes; - std::vector devnull; - lod_loader.done(this, m_root, devnull, lod_nodes); - - m_track_object_manager->assingLodNodes(lod_nodes); - // --------------------------------------------- + std::map library_nodes; + loadObjects(root, path, lod_loader, true, NULL, library_nodes); // Cleanup library nodes for (std::map::iterator it = library_nodes.begin(); @@ -1736,23 +1725,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa if (name == "track" || name == "default-start") continue; if (name == "object") { - bool is_instance = false; - node->get("lod_instance", &is_instance); - - float lod_distance = -1; - node->get("lod_distance", &lod_distance); - - if (lod_distance > 0.0f && !is_instance) - { - // lod definition - if (create_lod_definitions) - lod_loader.check(node, parent); - } - else - { - lod_loader.check(node, parent); - } - m_track_object_manager->add(*node, parent); + m_track_object_manager->add(*node, parent, lod_loader); } else if (name == "library") { @@ -1790,10 +1763,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa const XMLNode* lod_group_xml = lod_xml_node->getNode(i); for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++) { - // TODO: eventually, remove support for the old way of specifying LOD - // definitions among node, and support only the new way of using - // a section. Then, the LOD loading sequence can be simplified a lot - lod_loader.check(lod_group_xml->getNode(j), NULL); + lod_loader.addLODModelDefinition(lod_group_xml->getNode(j)); } } } @@ -1851,7 +1821,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa { if (UserConfigParams::m_graphical_effects) { - m_track_object_manager->add(*node, parent); + m_track_object_manager->add(*node, parent, lod_loader); } } else if (name == "sky-dome" || name == "sky-box" || name == "sky-color") @@ -1864,7 +1834,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa } else if (name == "light") { - m_track_object_manager->add(*node, parent); + m_track_object_manager->add(*node, parent, lod_loader); } else if (name == "weather") { diff --git a/src/tracks/track_object.cpp b/src/tracks/track_object.cpp index f10c47366..42f9f30a0 100644 --- a/src/tracks/track_object.cpp +++ b/src/tracks/track_object.cpp @@ -38,9 +38,9 @@ * model, enable/disable status, timer information. * \param lod_node Lod node (defaults to NULL). */ -TrackObject::TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lod_node) +TrackObject::TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader) { - init(xml_node, parent, lod_node); + init(xml_node, parent, lod_loader); } // ---------------------------------------------------------------------------- @@ -79,7 +79,7 @@ TrackObject::TrackObject(const core::vector3df& xyz, const core::vector3df& hpr, // ---------------------------------------------------------------------------- -void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lod_node) +void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader) { m_init_xyz = core::vector3df(0,0,0); m_init_hpr = core::vector3df(0,0,0); @@ -99,6 +99,9 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, LODNo xml_node.get("interaction", &m_interaction); xml_node.get("lod_group", &m_lod_group); + bool lod_instance = false; + xml_node.get("lod_instance", &lod_instance); + m_soccer_ball = false; xml_node.get("soccer_ball", &m_soccer_ball); @@ -152,12 +155,13 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, LODNo { scene::ISceneNode *glownode = NULL; - if (lod_node != NULL) + if (lod_instance) { m_type = "lod"; - m_presentation = new TrackObjectPresentationLOD(xml_node, lod_node); + TrackObjectPresentationLOD* lod_node = new TrackObjectPresentationLOD(xml_node, parent, lod_loader); + m_presentation = lod_node; - glownode = lod_node->getAllNodes()[0]; + glownode = ((LODNode*)lod_node->getNode())->getAllNodes()[0]; } else { diff --git a/src/tracks/track_object.hpp b/src/tracks/track_object.hpp index 8c41bbd73..4fca007e6 100644 --- a/src/tracks/track_object.hpp +++ b/src/tracks/track_object.hpp @@ -31,7 +31,7 @@ class XMLNode; class ThreeDAnimation; - +class LodNodeLoader; /** * \ingroup tracks @@ -82,10 +82,10 @@ protected: ThreeDAnimation* m_animator; - void init(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lodNode); + void init(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader); public: - TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lodNode=NULL); + TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader); TrackObject(const core::vector3df& xyz, const core::vector3df& hpr, diff --git a/src/tracks/track_object_manager.cpp b/src/tracks/track_object_manager.cpp index 60ffe4c66..6e20f4208 100644 --- a/src/tracks/track_object_manager.cpp +++ b/src/tracks/track_object_manager.cpp @@ -49,31 +49,16 @@ TrackObjectManager::~TrackObjectManager() * in a separate section that's read before everything and remove all this * crap */ -void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent) +void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader) { try { - std::string groupname; - xml_node.get("lod_group", &groupname); - bool is_lod = !groupname.empty(); - - if (is_lod) - { - bool lod_instance = false; - xml_node.get("lod_instance", &lod_instance); - - if (lod_instance) - m_lod_objects[groupname].push_back(&xml_node); - } - else - { - m_all_objects.push_back(new TrackObject(xml_node, parent)); - } + m_all_objects.push_back(new TrackObject(xml_node, parent, lod_loader)); } catch (std::exception& e) { - fprintf(stderr, "[TrackObjectManager] WARNING: Could not load track object. Reason : %s\n", - e.what()); + Log::warn("TrackObjectManager", "Could not load track object. Reason : %s", + e.what()); } } // add @@ -219,13 +204,8 @@ void TrackObjectManager::removeObject(TrackObject* obj) } // removeObject // ---------------------------------------------------------------------------- -/** - * \brief To be called after all objects are loaded and the LodNodeLoader is done - * parsing everything. - * This method exists because LOD objects need to be created after others. - * - * \param lod_nodes the LOD nodes created by the LodNodeLoader. - */ + +/* void TrackObjectManager::assingLodNodes(const std::vector& lod_nodes) { for (unsigned int n=0; n& lod_nodes) m_lod_objects.clear(); } +*/ \ No newline at end of file diff --git a/src/tracks/track_object_manager.hpp b/src/tracks/track_object_manager.hpp index 5539f08cd..f45bd390d 100644 --- a/src/tracks/track_object_manager.hpp +++ b/src/tracks/track_object_manager.hpp @@ -46,15 +46,10 @@ protected: enum TrackObjectType {TO_PHYSICAL, TO_GRAPHICAL}; PtrVector m_all_objects; - /** Temporary storage for LOD objects whose XML node was read but whose - * scene node is not yet ready - */ - std::map > m_lod_objects; - public: TrackObjectManager(); ~TrackObjectManager(); - void add(const XMLNode &xml_node, scene::ISceneNode* parent); + void add(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader); void update(float dt); void handleExplosion(const Vec3 &pos, const PhysicalObject *mp, bool secondary_hits=true); @@ -68,8 +63,6 @@ public: void removeObject(TrackObject* who); - void assingLodNodes(const std::vector& lod); - PtrVector& getObjects() { return m_all_objects; } const PtrVector& getObjects() const { return m_all_objects; } diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 3e23509b2..21975a93a 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -32,6 +32,7 @@ #include "modes/world.hpp" #include "states_screens/dialogs/race_paused_dialog.hpp" #include "states_screens/dialogs/tutorial_message_dialog.hpp" +#include "tracks/lod_node_loader.hpp" #include "tracks/track.hpp" #include @@ -125,10 +126,12 @@ TrackObjectPresentationEmpty::~TrackObjectPresentationEmpty() // ---------------------------------------------------------------------------- -TrackObjectPresentationLOD::TrackObjectPresentationLOD(const XMLNode& xml_node, LODNode* lod_node) : +TrackObjectPresentationLOD::TrackObjectPresentationLOD(const XMLNode& xml_node, + scene::ISceneNode* parent, LodNodeLoader& lod_loader) : TrackObjectPresentationSceneNode(xml_node) { - m_node = lod_node; + m_node = lod_loader.instanciate(&xml_node, parent); + if (m_node == NULL) throw std::exception("Cannot load LOD node"); m_node->setPosition(m_init_xyz); m_node->setRotation(m_init_hpr); m_node->setScale(m_init_scale); @@ -136,8 +139,8 @@ TrackObjectPresentationLOD::TrackObjectPresentationLOD(const XMLNode& xml_node, TrackObjectPresentationLOD::~TrackObjectPresentationLOD() { - irr_driver->removeNode(m_node); } + // ---------------------------------------------------------------------------- TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node, diff --git a/src/tracks/track_object_presentation.hpp b/src/tracks/track_object_presentation.hpp index a4d64c457..e12c3fdd5 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -40,6 +40,7 @@ class SFXBase; class ParticleEmitter; class PhysicalObject; class ThreeDAnimation; +class LodNodeLoader; /** * \ingroup tracks @@ -147,7 +148,9 @@ class TrackObjectPresentationLOD : public TrackObjectPresentationSceneNode { public: - TrackObjectPresentationLOD(const XMLNode& xml_node, LODNode* lod_node); + TrackObjectPresentationLOD(const XMLNode& xml_node, + scene::ISceneNode* parent, + LodNodeLoader& lod_loader); virtual ~TrackObjectPresentationLOD(); };