From 7c729ca6f42cd2926aee8b59a72177d4e2fdbfa5 Mon Sep 17 00:00:00 2001 From: auria Date: Thu, 17 Mar 2011 20:19:09 +0000 Subject: [PATCH] Not sure I should introduce this so close to a release, but anyway let's go, we can disable if it causes issues ;) use LOD on karts : far away karts will not be animated. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@7973 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/lod_node.cpp | 24 ++++++++++++++++++++---- src/graphics/lod_node.hpp | 18 ++++++++++++++++-- src/karts/kart.cpp | 20 +++++++++++++++++++- src/karts/kart_model.cpp | 12 ++++++++++-- 4 files changed, 65 insertions(+), 9 deletions(-) diff --git a/src/graphics/lod_node.cpp b/src/graphics/lod_node.cpp index 4a1e4e24c..71ed0f2c8 100644 --- a/src/graphics/lod_node.cpp +++ b/src/graphics/lod_node.cpp @@ -21,8 +21,10 @@ LODNode::LODNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id) - : IDummyTransformationSceneNode(parent, mgr, id) +: ISceneNode(parent, mgr, id) //: IDummyTransformationSceneNode(parent, mgr, id) { + assert(mgr != NULL); + assert(parent != NULL); parent->addChild(this); } @@ -43,14 +45,26 @@ void LODNode::OnRegisterSceneNode() // Assumes all children are at the same location const int dist = - (int)(m_nodes[0]->getPosition().getDistanceFromSQ( curr_cam->getPosition() )); + (int)((getPosition() + m_nodes[0]->getPosition()).getDistanceFromSQ( curr_cam->getPosition() )); for (unsigned int n=0; nOnRegisterSceneNode(); - return; + break; + } + } + + // If this node has children other than the LOD nodes, draw them + core::list::Iterator it; + + for (it = Children.begin(); it != Children.end(); it++) + { + if (m_nodes_set.find(*it) == m_nodes_set.end()) + { + assert(*it != NULL); + (*it)->OnRegisterSceneNode(); } } } @@ -61,11 +75,13 @@ void LODNode::add(int level, scene::ISceneNode* node, bool reparent) // I'm not convinced (Auria) but he's the artist pro, so I listen ;P level += (int)(((rand()%1000)-500)/500.0f*(level*0.1f)); - // FIXME : this class assumes that 'm_detail' is sorted, this may not always be the case + assert(node != NULL); + node->grab(); node->remove(); m_detail.push_back(level*level); m_nodes.push_back(node); + m_nodes_set.insert(node); node->setParent(this); node->drop(); } diff --git a/src/graphics/lod_node.hpp b/src/graphics/lod_node.hpp index abd5608e0..172a67baf 100644 --- a/src/graphics/lod_node.hpp +++ b/src/graphics/lod_node.hpp @@ -22,6 +22,8 @@ #include "irrlicht.h" using namespace irr; +#include + namespace irr { namespace scene @@ -34,7 +36,7 @@ namespace irr * \brief manages smoke particle effects * \ingroup graphics */ -class LODNode : public scene::IDummyTransformationSceneNode +class LODNode : public scene::ISceneNode // scene::IDummyTransformationSceneNode { private: core::matrix4 RelativeTransformationMatrix; @@ -42,7 +44,9 @@ private: std::vector m_detail; std::vector m_nodes; - + + std::set m_nodes_set; + public: LODNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id=-1); @@ -51,6 +55,7 @@ public: //! returns the axis aligned bounding box of this node virtual const core::aabbox3d& getBoundingBox() const { return Box; } + /* //! Returns a reference to the current relative transformation matrix. //! This is the matrix, this scene node uses instead of scale, translation //! and rotation. @@ -58,9 +63,18 @@ public: //! Returns the relative transformation of the scene node. virtual core::matrix4 getRelativeTransformation() const { return RelativeTransformationMatrix; } + */ + /** + * Adds a node associated with a level of detail. + * \note The LOD levels must be added in ascending order. + * \param level Distance (number of units) from which this level of detail kicks in + * \param node The node to show at this level + * \param reparent If true, node will be removed from its current parent first + */ void add(int level, scene::ISceneNode* node, bool reparent); + /** Get the highest level of detail node */ scene::ISceneNode* getFirstNode() { return m_nodes[0]; } virtual void OnRegisterSceneNode(); diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 9bcaf8ebf..83a0d9cc8 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -29,6 +29,7 @@ #include "audio/sfx_base.hpp" #include "config/user_config.hpp" #include "graphics/camera.hpp" +#include "graphics/lod_node.hpp" #include "graphics/material_manager.hpp" #include "graphics/particle_emitter.hpp" #include "graphics/particle_kind.hpp" @@ -1651,7 +1652,24 @@ void Kart::updatePhysics(float dt) */ void Kart::loadData(RaceManager::KartType type, Track* track, bool animatedModel) { - m_node = m_kart_model->attachModel(animatedModel); + if (animatedModel) + { + scene::ISceneNode* staticModel = m_kart_model->attachModel(false); + scene::ISceneNode* animatedModel = m_kart_model->attachModel(animatedModel); + LODNode* node = new LODNode(irr_driver->getSceneManager()->getRootSceneNode(), irr_driver->getSceneManager()); + node->add(100, animatedModel, true); + node->add(500, staticModel, true); + m_node = node; + } + else + { + m_node = m_kart_model->attachModel(animatedModel); + } + +#if DEBUG + m_node->setName( (m_kart_properties->getIdent()+"(lod-node)").c_str() ); +#endif + // Attachment must be created after attachModel, since only then the // scene node will exist (to which the attachment is added). But the // attachment is needed in createPhysics (which gets the mass, which diff --git a/src/karts/kart_model.cpp b/src/karts/kart_model.cpp index 0bf997b32..f70abb64d 100644 --- a/src/karts/kart_model.cpp +++ b/src/karts/kart_model.cpp @@ -215,8 +215,16 @@ scene::ISceneNode* KartModel::attachModel(bool animatedModels) } #ifdef DEBUG - std::string debug_name = m_model_filename+" (kart-model)"; - node->setName(debug_name.c_str()); + if (animatedModels) + { + std::string debug_name = m_model_filename+" (animated-kart-model)"; + node->setName(debug_name.c_str()); + } + else + { + std::string debug_name = m_model_filename+" (kart-model)"; + node->setName(debug_name.c_str()); + } #endif for(unsigned int i=0; i<4; i++)