diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index f67b5fea0..b9b0a43d5 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -2111,16 +2111,16 @@ void IrrDriver::applyObjectPassShader() } scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float radius, - float energy, float r, float g, float b, bool sun) + float energy, float r, float g, float b, bool sun, scene::ISceneNode* parent) { if (m_glsl) { LightNode *light = NULL; if (!sun) - light = new LightNode(m_scene_manager, radius, energy, r, g, b); + light = new LightNode(m_scene_manager, parent, radius, energy, r, g, b); else - light = new SunNode(m_scene_manager, r, g, b); + light = new SunNode(m_scene_manager, parent, r, g, b); light->grab(); light->setParent(NULL); diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 953c18100..88b7c4dc4 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -457,7 +457,7 @@ public: void applyObjectPassShader(scene::ISceneNode * const node, bool rimlit = false); // ------------------------------------------------------------------------ scene::ISceneNode *addLight(const core::vector3df &pos, float radius = 1.0f, float energy = 1., float r = 1.0f, - float g = 1.0f, float b = 1.0f, bool sun = false); + float g = 1.0f, float b = 1.0f, bool sun = false, scene::ISceneNode* parent = NULL); // ------------------------------------------------------------------------ void clearLights(); // ------------------------------------------------------------------------ diff --git a/src/graphics/light.cpp b/src/graphics/light.cpp index 105c760e5..46f8de22e 100644 --- a/src/graphics/light.cpp +++ b/src/graphics/light.cpp @@ -34,8 +34,8 @@ using namespace core; aabbox3df LightNode::box; -LightNode::LightNode(scene::ISceneManager* mgr, float radius, float e, float r, float g, float b): - ISceneNode(mgr->getRootSceneNode(), mgr, -1) +LightNode::LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float radius, float e, float r, float g, float b): + ISceneNode(parent == NULL ? mgr->getRootSceneNode() : parent, mgr, -1) { m_energy = e; m_energy_multiplier = 1.0f; diff --git a/src/graphics/light.hpp b/src/graphics/light.hpp index 542aa23f5..29de481da 100644 --- a/src/graphics/light.hpp +++ b/src/graphics/light.hpp @@ -34,7 +34,7 @@ namespace irr class LightNode: public scene::ISceneNode { public: - LightNode(scene::ISceneManager* mgr, float radius, float energy, float r, float g, float b); + LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float radius, float energy, float r, float g, float b); virtual ~LightNode(); virtual void render() OVERRIDE; diff --git a/src/graphics/sun.cpp b/src/graphics/sun.cpp index cd3dc3cf7..91ebb5ad4 100644 --- a/src/graphics/sun.cpp +++ b/src/graphics/sun.cpp @@ -34,10 +34,9 @@ using namespace video; using namespace scene; using namespace core; -SunNode::SunNode(scene::ISceneManager* mgr, float r, float g, float b): - LightNode(mgr, 10000, 0., r, g, b) +SunNode::SunNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float r, float g, float b): + LightNode(mgr, parent, 10000, 0., r, g, b) { - sq = new ScreenQuad(irr_driver->getVideoDriver()); SMaterial &m = sq->getMaterial(); diff --git a/src/graphics/sun.hpp b/src/graphics/sun.hpp index 62052ca14..ff719084c 100644 --- a/src/graphics/sun.hpp +++ b/src/graphics/sun.hpp @@ -28,7 +28,7 @@ class ScreenQuad; class SunNode: public LightNode { public: - SunNode(scene::ISceneManager* mgr, float r, float g, float b); + SunNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float r, float g, float b); virtual ~SunNode(); virtual void render() OVERRIDE; diff --git a/src/tracks/lod_node_loader.cpp b/src/tracks/lod_node_loader.cpp index 10abbca2d..f64a49866 100644 --- a/src/tracks/lod_node_loader.cpp +++ b/src/tracks/lod_node_loader.cpp @@ -88,10 +88,11 @@ bool LodNodeLoader::check(const XMLNode* xml) void LodNodeLoader::done(Track* track, std::string directory, std::vector& cache, + scene::ISceneNode* parent, std::vector& out) { scene::ISceneManager* sm = irr_driver->getSceneManager(); - scene::ISceneNode* sroot = sm->getRootSceneNode(); + 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 @@ -144,7 +145,7 @@ void LodNodeLoader::done(Track* track, if (group.size() > 0) { - LODNode* lod_node = new LODNode(groupname, sroot, sm); + LODNode* lod_node = new LODNode(groupname, parent, sm); lod_node->setPosition(xyz); lod_node->setRotation(hpr); lod_node->setScale(scale); diff --git a/src/tracks/lod_node_loader.hpp b/src/tracks/lod_node_loader.hpp index 3da7b9eca..293dc1669 100644 --- a/src/tracks/lod_node_loader.hpp +++ b/src/tracks/lod_node_loader.hpp @@ -32,6 +32,7 @@ namespace irr namespace scene { class IMesh; + class ISceneNode; } } @@ -76,6 +77,7 @@ public: void done(Track* track, std::string directory, std::vector& cache, + scene::ISceneNode* parent, std::vector& out); void clear(); diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 893828c87..0699e9a92 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1183,7 +1183,7 @@ bool Track::loadMainTrack(const XMLNode &root) // Create LOD nodes std::vector lod_nodes; - lodLoader.done(this, m_root, m_all_cached_meshes, lod_nodes); + lodLoader.done(this, m_root, m_all_cached_meshes, NULL, lod_nodes); for (unsigned int n=0; nadd(*node); + m_track_object_manager->add(*node, parent); } else if (name == "library") { std::string name; node->get("name", &name); + core::vector3df xyz; + node->get("xyz", &xyz); + XMLNode* libroot; std::string lib_path = file_manager->getAsset("library/" + name); bool create_lod_definitions = true; @@ -1727,7 +1730,10 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, file_manager->pushTextureSearchPath(lib_path + "/"); file_manager->pushModelSearchPath (lib_path); - loadObjects(libroot, lib_path, create_lod_definitions); + 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(); @@ -1774,7 +1780,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, { if (UserConfigParams::m_graphical_effects) { - m_track_object_manager->add(*node); + m_track_object_manager->add(*node, parent); } } else if (name == "sky-dome" || name == "sky-box" || name == "sky-color") @@ -1787,7 +1793,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, } else if (name == "light") { - m_track_object_manager->add(*node); + m_track_object_manager->add(*node, parent); } else if (name == "weather") { @@ -1866,13 +1872,19 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, std::vector lod_nodes; std::vector devnull; - lod_loader.done(this, m_root, devnull, lod_nodes); + lod_loader.done(this, m_root, devnull, parent, lod_nodes); - m_track_object_manager->assingLodNodes(lod_nodes); + m_track_object_manager->assingLodNodes(lod_nodes, parent); // --------------------------------------------- // Init all track objects m_track_object_manager->init(); + + for (std::map::iterator it = library_nodes.begin(); + it != library_nodes.end(); it++) + { + delete it->second; + } } //----------------------------------------------------------------------------- diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 1e2a7d6b3..e1591b8f1 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -400,7 +400,7 @@ private: 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); + bool create_lod_definitions, scene::ISceneNode* parent); public: diff --git a/src/tracks/track_object.cpp b/src/tracks/track_object.cpp index 0bf6e79cf..f10c47366 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, LODNode* lod_node) +TrackObject::TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lod_node) { - init(xml_node, lod_node); + init(xml_node, parent, lod_node); } // ---------------------------------------------------------------------------- @@ -79,7 +79,7 @@ TrackObject::TrackObject(const core::vector3df& xyz, const core::vector3df& hpr, // ---------------------------------------------------------------------------- -void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) +void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lod_node) { m_init_xyz = core::vector3df(0,0,0); m_init_hpr = core::vector3df(0,0,0); @@ -114,19 +114,19 @@ void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) if (xml_node.getName() == "particle-emitter") { m_type = "particle-emitter"; - m_presentation = new TrackObjectPresentationParticles(xml_node); + m_presentation = new TrackObjectPresentationParticles(xml_node, parent); } else if (xml_node.getName() == "light") { m_type = "light"; - m_presentation = new TrackObjectPresentationLight(xml_node); + m_presentation = new TrackObjectPresentationLight(xml_node, parent); } else if (type == "sfx-emitter") { // FIXME: at this time sound emitters are just disabled in multiplayer // otherwise the sounds would be constantly heard if (race_manager->getNumLocalPlayers() < 2) - m_presentation = new TrackObjectPresentationSound(xml_node); + m_presentation = new TrackObjectPresentationSound(xml_node, parent); } else if (type == "action-trigger") { @@ -142,7 +142,7 @@ void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) } else if (type == "billboard") { - m_presentation = new TrackObjectPresentationBillboard(xml_node); + m_presentation = new TrackObjectPresentationBillboard(xml_node, parent); } else if (type=="cutscene_camera") { @@ -163,7 +163,8 @@ void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) { m_type = "mesh"; m_presentation = new TrackObjectPresentationMesh(xml_node, - m_enabled); + m_enabled, + parent); glownode = ((TrackObjectPresentationMesh *) m_presentation)->getNode(); } diff --git a/src/tracks/track_object.hpp b/src/tracks/track_object.hpp index 3d8bd52d2..8c41bbd73 100644 --- a/src/tracks/track_object.hpp +++ b/src/tracks/track_object.hpp @@ -82,10 +82,10 @@ protected: ThreeDAnimation* m_animator; - void init(const XMLNode &xml_node, LODNode* lodNode); + void init(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lodNode); public: - TrackObject(const XMLNode &xml_node, LODNode* lodNode=NULL); + TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lodNode=NULL); 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 6ff5c5e5f..ffb876b13 100644 --- a/src/tracks/track_object_manager.cpp +++ b/src/tracks/track_object_manager.cpp @@ -45,7 +45,7 @@ TrackObjectManager::~TrackObjectManager() * TrackObjectManager::assingLodNodes after everything is loaded * to finalize their creation. */ -void TrackObjectManager::add(const XMLNode &xml_node) +void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent) { try { @@ -59,7 +59,7 @@ void TrackObjectManager::add(const XMLNode &xml_node) } else { - m_all_objects.push_back(new TrackObject(xml_node)); + m_all_objects.push_back(new TrackObject(xml_node, parent)); } } catch (std::exception& e) @@ -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& lod_nodes) +void TrackObjectManager::assingLodNodes(const std::vector& lod_nodes, scene::ISceneNode* parent) { for (unsigned int n=0; n& lod_nodes) assert( queue.size() > 0 ); const XMLNode* xml = queue[ queue.size() - 1 ]; - TrackObject* obj = new TrackObject(*xml, lod_nodes[n]); + TrackObject* obj = new TrackObject(*xml, parent, lod_nodes[n]); queue.erase( queue.end() - 1 ); m_all_objects.push_back(obj); diff --git a/src/tracks/track_object_manager.hpp b/src/tracks/track_object_manager.hpp index eba7b9300..99a2ae289 100644 --- a/src/tracks/track_object_manager.hpp +++ b/src/tracks/track_object_manager.hpp @@ -54,7 +54,7 @@ protected: public: TrackObjectManager(); ~TrackObjectManager(); - void add(const XMLNode &xml_node); + void add(const XMLNode &xml_node, scene::ISceneNode* parent); void update(float dt); void handleExplosion(const Vec3 &pos, const PhysicalObject *mp, bool secondary_hits=true); @@ -68,7 +68,7 @@ public: void removeObject(TrackObject* who); - void assingLodNodes(const std::vector& lod); + void assingLodNodes(const std::vector& lod, scene::ISceneNode* parent); 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 8b1eb2534..3e23509b2 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -140,7 +140,8 @@ TrackObjectPresentationLOD::~TrackObjectPresentationLOD() } // ---------------------------------------------------------------------------- -TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node, bool enabled) : +TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node, + bool enabled, scene::ISceneNode* parent) : TrackObjectPresentationSceneNode(xml_node) { m_is_looped = false; @@ -181,7 +182,7 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node throw std::runtime_error("Model '" + model_name + "' cannot be found"); } - init(&xml_node, enabled); + init(&xml_node, parent, enabled); } TrackObjectPresentationMesh::TrackObjectPresentationMesh( @@ -213,10 +214,10 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh( throw std::runtime_error("Model '" + model_file + "' cannot be found"); } - init(NULL, true); + init(NULL, NULL, true); } -void TrackObjectPresentationMesh::init(const XMLNode* xml_node, bool enabled) +void TrackObjectPresentationMesh::init(const XMLNode* xml_node, scene::ISceneNode* parent, bool enabled) { bool animated = (UserConfigParams::m_graphical_effects || World::getWorld()->getIdent() == IDENT_CUSTSCENE); @@ -239,7 +240,7 @@ void TrackObjectPresentationMesh::init(const XMLNode* xml_node, bool enabled) else if (animated) { scene::IAnimatedMeshSceneNode *node = - irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)m_mesh); + irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)m_mesh, parent); m_node = node; m_frame_start = node->getStartFrame(); @@ -252,7 +253,7 @@ void TrackObjectPresentationMesh::init(const XMLNode* xml_node, bool enabled) } else { - m_node = irr_driver->addMesh(m_mesh); + m_node = irr_driver->addMesh(m_mesh, parent); m_frame_start = 0; m_frame_end = 0; } @@ -311,9 +312,11 @@ void TrackObjectPresentationMesh::reset() // ---------------------------------------------------------------------------- -TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_node) : +TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_node, scene::ISceneNode* parent) : TrackObjectPresentation(xml_node) { + // TODO: respect 'parent' if any + m_sound = NULL; m_xyz = m_init_xyz; @@ -424,7 +427,7 @@ void TrackObjectPresentationSound::move(const core::vector3df& xyz, const core:: // ---------------------------------------------------------------------------- -TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode& xml_node) : +TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode& xml_node, scene::ISceneNode* parent) : TrackObjectPresentationSceneNode(xml_node) { std::string texture_name; @@ -452,7 +455,7 @@ TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode { Log::warn("TrackObjectPresentation", "Billboard texture '%s' not found", texture_name.c_str()); } - m_node = irr_driver->addBillboard(core::dimension2df(width, height), texture); + m_node = irr_driver->addBillboard(core::dimension2df(width, height), texture, parent); Material *stk_material = material_manager->getMaterial(texture_name); stk_material->setMaterialProperties(&(m_node->getMaterial(0)), NULL); @@ -492,7 +495,7 @@ TrackObjectPresentationBillboard::~TrackObjectPresentationBillboard() // ---------------------------------------------------------------------------- -TrackObjectPresentationParticles::TrackObjectPresentationParticles(const XMLNode& xml_node) : +TrackObjectPresentationParticles::TrackObjectPresentationParticles(const XMLNode& xml_node, scene::ISceneNode* parent) : TrackObjectPresentationSceneNode(xml_node) { m_emitter = NULL; @@ -500,10 +503,7 @@ TrackObjectPresentationParticles::TrackObjectPresentationParticles(const XMLNode std::string path; xml_node.get("kind", &path); - - //irr::core::vector3df emitter_origin; - //xml_node.getXYZ(&emitter_origin); - + int clip_distance = -1; xml_node.get("clip_distance", &clip_distance); @@ -516,16 +516,15 @@ TrackObjectPresentationParticles::TrackObjectPresentationParticles(const XMLNode { throw std::runtime_error(path + " could not be loaded"); } - ParticleEmitter* emitter = new ParticleEmitter( kind, m_init_xyz ); + ParticleEmitter* emitter = new ParticleEmitter(kind, m_init_xyz, parent); if (clip_distance > 0) { scene::ISceneManager* sm = irr_driver->getSceneManager(); scene::ISceneNode* sroot = sm->getRootSceneNode(); - LODNode* lod = new LODNode("particles", sroot, sm); + LODNode* lod = new LODNode("particles", parent == NULL ? sroot : parent, sm); lod->add(clip_distance, (scene::ISceneNode*)emitter->getNode(), true); - //m_all_emitters.push_back(emitter); m_node = lod; m_lod_emitter_node = lod; m_emitter = emitter; @@ -579,7 +578,7 @@ void TrackObjectPresentationParticles::triggerParticles() // ---------------------------------------------------------------------------- -TrackObjectPresentationLight::TrackObjectPresentationLight(const XMLNode& xml_node) : +TrackObjectPresentationLight::TrackObjectPresentationLight(const XMLNode& xml_node, scene::ISceneNode* parent) : TrackObjectPresentationSceneNode(xml_node) { xml_node.get("color", &m_color); @@ -593,7 +592,7 @@ TrackObjectPresentationLight::TrackObjectPresentationLight(const XMLNode& xml_no if (irr_driver->isGLSL()) { - m_node = irr_driver->addLight(m_init_xyz, m_distance, m_energy, colorf.r, colorf.g, colorf.b); + m_node = irr_driver->addLight(m_init_xyz, m_distance, m_energy, colorf.r, colorf.g, colorf.b, false, parent); } else { diff --git a/src/tracks/track_object_presentation.hpp b/src/tracks/track_object_presentation.hpp index eb077ecac..a4d64c457 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -174,10 +174,10 @@ private: /** End frame of the animation to be played. */ unsigned int m_frame_end; - void init(const XMLNode* xml_node, bool enabled); + void init(const XMLNode* xml_node, scene::ISceneNode* parent, bool enabled); public: - TrackObjectPresentationMesh(const XMLNode& xml_node, bool enabled); + TrackObjectPresentationMesh(const XMLNode& xml_node, bool enabled, scene::ISceneNode* parent); TrackObjectPresentationMesh( const std::string& model_file, const core::vector3df& xyz, @@ -207,7 +207,7 @@ private: public: - TrackObjectPresentationSound(const XMLNode& xml_node); + TrackObjectPresentationSound(const XMLNode& xml_node, scene::ISceneNode* parent); virtual ~TrackObjectPresentationSound(); virtual void onTriggerItemApproached(Item* who) OVERRIDE; virtual void update(float dt) OVERRIDE; @@ -235,7 +235,7 @@ class TrackObjectPresentationBillboard : public TrackObjectPresentationSceneNode float m_fade_out_start; float m_fade_out_end; public: - TrackObjectPresentationBillboard(const XMLNode& xml_node); + TrackObjectPresentationBillboard(const XMLNode& xml_node, scene::ISceneNode* parent); virtual ~TrackObjectPresentationBillboard(); virtual void update(float dt) OVERRIDE; }; @@ -253,7 +253,7 @@ private: std::string m_trigger_condition; public: - TrackObjectPresentationParticles(const XMLNode& xml_node); + TrackObjectPresentationParticles(const XMLNode& xml_node, scene::ISceneNode* parent); virtual ~TrackObjectPresentationParticles(); virtual void update(float dt) OVERRIDE; @@ -275,7 +275,7 @@ private: float m_energy; public: - TrackObjectPresentationLight(const XMLNode& xml_node); + TrackObjectPresentationLight(const XMLNode& xml_node, scene::ISceneNode* parent); virtual ~TrackObjectPresentationLight(); };