Refactor LOD to allow parenting
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14853 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -43,7 +43,7 @@ bool PairCompare(const std::pair<int, LodModel>& i, const std::pair<int, LodMode
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** Check a XML node in case it contains a LOD object and if so remember it */
|
||||
bool LodNodeLoader::check(const XMLNode* xml)
|
||||
bool LodNodeLoader::check(const XMLNode* xml, scene::ISceneNode* parent)
|
||||
{
|
||||
float lod_distance = -1.0f;
|
||||
xml->get("lod_distance", &lod_distance);
|
||||
@@ -61,7 +61,7 @@ bool LodNodeLoader::check(const XMLNode* xml)
|
||||
{
|
||||
if (lod_instance)
|
||||
{
|
||||
lod_instances[lodgroup].push_back(xml);
|
||||
lod_instances[lodgroup].push_back(LodInstance(xml, parent));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -88,11 +88,9 @@ bool LodNodeLoader::check(const XMLNode* xml)
|
||||
void LodNodeLoader::done(Track* track,
|
||||
std::string directory,
|
||||
std::vector<scene::IMesh*>& cache,
|
||||
scene::ISceneNode* parent,
|
||||
std::vector<LODNode*>& out)
|
||||
{
|
||||
scene::ISceneManager* sm = irr_driver->getSceneManager();
|
||||
if (parent == NULL) parent = sm->getRootSceneNode();
|
||||
|
||||
// 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
|
||||
@@ -120,15 +118,15 @@ void LodNodeLoader::done(Track* track,
|
||||
|
||||
// 2. Read the XML nodes and instanciate LOD scene nodes where relevant
|
||||
std::string groupname;
|
||||
std::map< std::string, std::vector< const XMLNode* > >::iterator it3;
|
||||
std::map< std::string, std::vector< LodInstance > >::iterator it3;
|
||||
for (it3 = lod_instances.begin(); it3 != lod_instances.end(); it3++)
|
||||
{
|
||||
std::vector< std::pair<int, LodModel> >& group = sorted_lod_groups[it3->first];
|
||||
|
||||
std::vector< const XMLNode* >& v = it3->second;
|
||||
std::vector< LodInstance >& v = it3->second;
|
||||
for (unsigned int n=0; n<v.size(); n++)
|
||||
{
|
||||
const XMLNode* node = v[n];
|
||||
const XMLNode* node = v[n].m_xml_node;
|
||||
|
||||
groupname = "";
|
||||
node->get("lod_group", &groupname);
|
||||
@@ -141,10 +139,9 @@ void LodNodeLoader::done(Track* track,
|
||||
core::vector3df scale(1.0f, 1.0f, 1.0f);
|
||||
node->get("scale", &scale);
|
||||
|
||||
std::string full_path;
|
||||
|
||||
if (group.size() > 0)
|
||||
{
|
||||
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);
|
||||
@@ -158,7 +155,7 @@ void LodNodeLoader::done(Track* track,
|
||||
if (!a_mesh)
|
||||
{
|
||||
Log::warn("LODNodeLoad", "Warning: object model '%s' not found, ignored.\n",
|
||||
full_path.c_str());
|
||||
group[m].second.m_model_file.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,25 @@ 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;
|
||||
@@ -68,16 +87,15 @@ class LodNodeLoader
|
||||
{
|
||||
private:
|
||||
std::map< std::string, std::map< int, LodModel > > lod_groups;
|
||||
std::map< std::string, std::vector< const XMLNode* > > lod_instances;
|
||||
std::map< std::string, std::vector< LodInstance > > lod_instances;
|
||||
|
||||
public:
|
||||
LodNodeLoader();
|
||||
|
||||
bool check(const XMLNode* xml);
|
||||
bool check(const XMLNode* xml, scene::ISceneNode* parent);
|
||||
void done(Track* track,
|
||||
std::string directory,
|
||||
std::vector<irr::scene::IMesh*>& cache,
|
||||
scene::ISceneNode* parent,
|
||||
std::vector<LODNode*>& out);
|
||||
|
||||
void clear();
|
||||
|
||||
@@ -1016,7 +1016,7 @@ bool Track::loadMainTrack(const XMLNode &root)
|
||||
std::string challenge;
|
||||
n->get("challenge", &challenge);
|
||||
|
||||
bool is_lod = lodLoader.check(n);
|
||||
bool is_lod = lodLoader.check(n, NULL);
|
||||
|
||||
if (tangent)
|
||||
{
|
||||
@@ -1183,7 +1183,7 @@ bool Track::loadMainTrack(const XMLNode &root)
|
||||
|
||||
// Create LOD nodes
|
||||
std::vector<LODNode*> lod_nodes;
|
||||
lodLoader.done(this, m_root, m_all_cached_meshes, NULL, lod_nodes);
|
||||
lodLoader.done(this, m_root, m_all_cached_meshes, lod_nodes);
|
||||
for (unsigned int n=0; n<lod_nodes.size(); n++)
|
||||
{
|
||||
// FIXME: support for animated textures on LOD objects
|
||||
@@ -1513,7 +1513,45 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
loadMainTrack(*root);
|
||||
unsigned int main_track_count = m_all_nodes.size();
|
||||
|
||||
loadObjects(root, path, true, NULL);
|
||||
LodNodeLoader lod_loader;
|
||||
std::map<std::string, XMLNode*> library_nodes;
|
||||
loadObjects(root, path, lod_loader, true, NULL, library_nodes);
|
||||
|
||||
// -------- 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)
|
||||
{
|
||||
for (unsigned int i=0; i<track_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);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<LODNode*> lod_nodes;
|
||||
std::vector<scene::IMesh*> devnull;
|
||||
lod_loader.done(this, m_root, devnull, lod_nodes);
|
||||
|
||||
m_track_object_manager->assingLodNodes(lod_nodes);
|
||||
// ---------------------------------------------
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// Init all track objects
|
||||
m_track_object_manager->init();
|
||||
|
||||
|
||||
// ---- Fog
|
||||
// It's important to execute this BEFORE the code that creates the skycube,
|
||||
@@ -1665,14 +1703,12 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Track::loadObjects(const XMLNode* root, const std::string& path,
|
||||
bool create_lod_definitions, scene::ISceneNode* parent)
|
||||
void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoader& lod_loader,
|
||||
bool create_lod_definitions, scene::ISceneNode* parent,
|
||||
std::map<std::string, XMLNode*>& library_nodes)
|
||||
{
|
||||
LodNodeLoader lod_loader;
|
||||
unsigned int start_position_counter = 0;
|
||||
|
||||
std::map<std::string, XMLNode*> library_nodes;
|
||||
|
||||
unsigned int node_count = root->getNumNodes();
|
||||
for (unsigned int i = 0; i < node_count; i++)
|
||||
{
|
||||
@@ -1693,11 +1729,11 @@ void Track::loadObjects(const XMLNode* root, const std::string& path,
|
||||
{
|
||||
// lod definition
|
||||
if (create_lod_definitions)
|
||||
lod_loader.check(node);
|
||||
lod_loader.check(node, parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
lod_loader.check(node);
|
||||
lod_loader.check(node, parent);
|
||||
}
|
||||
m_track_object_manager->add(*node, parent);
|
||||
}
|
||||
@@ -1715,28 +1751,29 @@ void Track::loadObjects(const XMLNode* root, const std::string& path,
|
||||
|
||||
if (library_nodes.find(name) == library_nodes.end())
|
||||
{
|
||||
std::string lib_node_path = file_manager->getAsset("library/" + name + "/node.xml");
|
||||
std::string node_path = "library/" + name + "/node.xml";
|
||||
std::string lib_node_path = file_manager->getAsset(node_path);
|
||||
libroot = file_manager->createXMLTree(lib_node_path);
|
||||
if (libroot == NULL) continue;
|
||||
if (libroot == NULL)
|
||||
{
|
||||
Log::error("Track", "Cannot find library '%s'", node_path.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
file_manager->pushTextureSearchPath(lib_path + "/");
|
||||
file_manager->pushModelSearchPath (lib_path);
|
||||
library_nodes[name] = libroot;
|
||||
}
|
||||
else
|
||||
{
|
||||
libroot = library_nodes[name];
|
||||
create_lod_definitions = false; // LOD definitions are already created, don't create them again
|
||||
}
|
||||
|
||||
library_nodes[name] = libroot;
|
||||
|
||||
file_manager->pushTextureSearchPath(lib_path + "/");
|
||||
file_manager->pushModelSearchPath (lib_path);
|
||||
|
||||
scene::ISceneNode* parent = irr_driver->getSceneManager()->addEmptySceneNode();
|
||||
parent->setPosition(xyz);
|
||||
parent->updateAbsolutePosition();
|
||||
loadObjects(libroot, lib_path, create_lod_definitions, parent);
|
||||
|
||||
file_manager->popTextureSearchPath();
|
||||
file_manager->popModelSearchPath();
|
||||
loadObjects(libroot, lib_path, lod_loader, create_lod_definitions, parent, library_nodes);
|
||||
}
|
||||
else if (name == "water")
|
||||
{
|
||||
@@ -1854,37 +1891,6 @@ void Track::loadObjects(const XMLNode* root, const std::string& path,
|
||||
}
|
||||
|
||||
} // for i<root->getNumNodes()
|
||||
|
||||
// -------- 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)
|
||||
{
|
||||
for (unsigned int i=0; i<track_node->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode* n = track_node->getNode(i);
|
||||
bool is_instance = false;
|
||||
n->get("lod_instance", &is_instance);
|
||||
|
||||
if (!is_instance && create_lod_definitions) lod_loader.check(n);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<LODNode*> lod_nodes;
|
||||
std::vector<scene::IMesh*> devnull;
|
||||
lod_loader.done(this, m_root, devnull, parent, lod_nodes);
|
||||
|
||||
m_track_object_manager->assingLodNodes(lod_nodes, parent);
|
||||
// ---------------------------------------------
|
||||
|
||||
// Init all track objects
|
||||
m_track_object_manager->init();
|
||||
|
||||
for (std::map<std::string, XMLNode*>::iterator it = library_nodes.begin();
|
||||
it != library_nodes.end(); it++)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace irr
|
||||
namespace scene { class IMesh; class ILightSceneNode; }
|
||||
}
|
||||
using namespace irr;
|
||||
class LodNodeLoader;
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
|
||||
@@ -399,8 +400,9 @@ 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,
|
||||
bool create_lod_definitions, scene::ISceneNode* parent);
|
||||
void loadObjects(const XMLNode* root, const std::string& path, LodNodeLoader& lod_loader,
|
||||
bool create_lod_definitions, scene::ISceneNode* parent,
|
||||
std::map<std::string, XMLNode*>& library_nodes);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ void TrackObjectManager::removeObject(TrackObject* obj)
|
||||
*
|
||||
* \param lod_nodes the LOD nodes created by the LodNodeLoader.
|
||||
*/
|
||||
void TrackObjectManager::assingLodNodes(const std::vector<LODNode*>& lod_nodes, scene::ISceneNode* parent)
|
||||
void TrackObjectManager::assingLodNodes(const std::vector<LODNode*>& lod_nodes)
|
||||
{
|
||||
for (unsigned int n=0; n<lod_nodes.size(); n++)
|
||||
{
|
||||
@@ -226,7 +226,7 @@ void TrackObjectManager::assingLodNodes(const std::vector<LODNode*>& lod_nodes,
|
||||
assert( queue.size() > 0 );
|
||||
const XMLNode* xml = queue[ queue.size() - 1 ];
|
||||
|
||||
TrackObject* obj = new TrackObject(*xml, parent, lod_nodes[n]);
|
||||
TrackObject* obj = new TrackObject(*xml, lod_nodes[n]->getParent(), lod_nodes[n]);
|
||||
queue.erase( queue.end() - 1 );
|
||||
|
||||
m_all_objects.push_back(obj);
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
void removeObject(TrackObject* who);
|
||||
|
||||
void assingLodNodes(const std::vector<LODNode*>& lod, scene::ISceneNode* parent);
|
||||
void assingLodNodes(const std::vector<LODNode*>& lod);
|
||||
|
||||
PtrVector<TrackObject>& getObjects() { return m_all_objects; }
|
||||
const PtrVector<TrackObject>& getObjects() const { return m_all_objects; }
|
||||
|
||||
Reference in New Issue
Block a user