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
This commit is contained in:
auria 2011-03-17 20:19:09 +00:00
parent 01154fd6b4
commit 7c729ca6f4
4 changed files with 65 additions and 9 deletions

View File

@ -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; n<m_detail.size(); n++)
{
if (dist < m_detail[n])
{
m_nodes[n]->OnRegisterSceneNode();
return;
break;
}
}
// If this node has children other than the LOD nodes, draw them
core::list<ISceneNode*>::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();
}

View File

@ -22,6 +22,8 @@
#include "irrlicht.h"
using namespace irr;
#include <set>
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<int> m_detail;
std::vector<scene::ISceneNode*> m_nodes;
std::set<scene::ISceneNode*> 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<f32>& 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();

View File

@ -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

View File

@ -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++)