Add the basic infrastructure to support level-of-detail. Note that at this time the implementation is not the most efficient one can think of so let's not use this widely just yet
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@7805 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
4fac382508
commit
c08b9b3a7f
src
@ -63,6 +63,8 @@ supertuxkart_SOURCES = \
|
||||
graphics/explosion.hpp \
|
||||
graphics/irr_driver.cpp \
|
||||
graphics/irr_driver.hpp \
|
||||
graphics/lod_node.cpp \
|
||||
graphics/lod_node.hpp \
|
||||
graphics/material.cpp \
|
||||
graphics/material.hpp \
|
||||
graphics/material_manager.cpp \
|
||||
|
77
src/graphics/lod_node.cpp
Normal file
77
src/graphics/lod_node.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Marianne Gagnon
|
||||
// based on code Copyright (C) 2002-2010 Nikolaus Gebhardt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/lod_node.hpp"
|
||||
|
||||
|
||||
LODNode::LODNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id)
|
||||
: IDummyTransformationSceneNode(parent, mgr, id)
|
||||
{
|
||||
parent->addChild(this);
|
||||
}
|
||||
|
||||
LODNode::~LODNode()
|
||||
{
|
||||
}
|
||||
|
||||
void LODNode::render()
|
||||
{
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
//ISceneNode::render();
|
||||
}
|
||||
|
||||
void LODNode::OnRegisterSceneNode()
|
||||
{
|
||||
// TODO: optimize this, there is no need to check every frame
|
||||
scene::ICameraSceneNode* curr_cam = irr_driver->getSceneManager()->getActiveCamera();
|
||||
|
||||
// Assumes all children are at the same location
|
||||
const int dist = 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (dist >= m_detail[m_nodes.size()-1])
|
||||
{
|
||||
m_nodes[m_nodes.size()-1]->OnRegisterSceneNode();
|
||||
}
|
||||
else
|
||||
{
|
||||
// This probably means the first level of detail is not 0
|
||||
assert(false);
|
||||
}
|
||||
//ISceneNode::OnRegisterSceneNode();
|
||||
}
|
||||
|
||||
void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
|
||||
{
|
||||
// FIXME : this class assumes that 'm_detail' is sorted, this may not always be the case
|
||||
node->grab();
|
||||
node->remove();
|
||||
m_detail.push_back(level*level);
|
||||
m_nodes.push_back(node);
|
||||
node->setParent(this);
|
||||
node->drop();
|
||||
}
|
65
src/graphics/lod_node.hpp
Normal file
65
src/graphics/lod_node.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Marianne Gagnon
|
||||
// based on code Copyright (C) 2002-2010 Nikolaus Gebhardt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_LOD_NODE_HPP
|
||||
#define HEADER_LOD_NODE_HPP
|
||||
|
||||
#include "irrlicht.h"
|
||||
using namespace irr;
|
||||
|
||||
|
||||
/**
|
||||
* \brief manages smoke particle effects
|
||||
* \ingroup graphics
|
||||
*/
|
||||
class LODNode : public scene::IDummyTransformationSceneNode
|
||||
{
|
||||
private:
|
||||
core::matrix4 RelativeTransformationMatrix;
|
||||
core::aabbox3d<f32> Box;
|
||||
|
||||
std::vector<int> m_detail;
|
||||
std::vector<scene::ISceneNode*> m_nodes;
|
||||
|
||||
public:
|
||||
|
||||
LODNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id);
|
||||
virtual ~LODNode();
|
||||
|
||||
//! 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.
|
||||
virtual core::matrix4& getRelativeTransformationMatrix() { return RelativeTransformationMatrix; }
|
||||
|
||||
//! Returns the relative transformation of the scene node.
|
||||
virtual core::matrix4 getRelativeTransformation() const { return RelativeTransformationMatrix; }
|
||||
|
||||
void add(int level, scene::ISceneNode* node, bool reparent);
|
||||
|
||||
virtual void OnRegisterSceneNode();
|
||||
virtual void render();
|
||||
|
||||
virtual scene::ESCENE_NODE_TYPE getType() const { return scene::ESNT_DUMMY_TRANSFORMATION; }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -47,6 +47,7 @@
|
||||
952A154D103F66D600B1895D /* shadow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 952A153D103F66D600B1895D /* shadow.cpp */; };
|
||||
952A154E103F66D600B1895D /* skid_marks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 952A153F103F66D600B1895D /* skid_marks.cpp */; };
|
||||
952A1554103F68D000B1895D /* profile_world.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 952A1552103F68D000B1895D /* profile_world.cpp */; };
|
||||
95376CAF1320784100C842A4 /* lod_node.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95376CAD1320784100C842A4 /* lod_node.cpp */; };
|
||||
953789730FC7829100DD1F8E /* graph_node.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 953789720FC7829100DD1F8E /* graph_node.cpp */; };
|
||||
953789820FC7831400DD1F8E /* quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 953789810FC7831400DD1F8E /* quad.cpp */; };
|
||||
9538A56012CD094200CE3220 /* addon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9538A55E12CD094200CE3220 /* addon.cpp */; };
|
||||
@ -441,6 +442,8 @@
|
||||
952A1540103F66D600B1895D /* skid_marks.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = skid_marks.hpp; path = ../../graphics/skid_marks.hpp; sourceTree = SOURCE_ROOT; };
|
||||
952A1552103F68D000B1895D /* profile_world.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = profile_world.cpp; path = ../../modes/profile_world.cpp; sourceTree = SOURCE_ROOT; };
|
||||
952A1553103F68D000B1895D /* profile_world.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = profile_world.hpp; path = ../../modes/profile_world.hpp; sourceTree = SOURCE_ROOT; };
|
||||
95376CAD1320784100C842A4 /* lod_node.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lod_node.cpp; path = ../../graphics/lod_node.cpp; sourceTree = SOURCE_ROOT; };
|
||||
95376CAE1320784100C842A4 /* lod_node.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = lod_node.hpp; path = ../../graphics/lod_node.hpp; sourceTree = SOURCE_ROOT; };
|
||||
953789710FC7829100DD1F8E /* graph_node.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = graph_node.hpp; path = ../../tracks/graph_node.hpp; sourceTree = SOURCE_ROOT; };
|
||||
953789720FC7829100DD1F8E /* graph_node.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = graph_node.cpp; path = ../../tracks/graph_node.cpp; sourceTree = SOURCE_ROOT; };
|
||||
953789800FC7831400DD1F8E /* quad.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = quad.hpp; path = ../../tracks/quad.hpp; sourceTree = SOURCE_ROOT; };
|
||||
@ -1355,6 +1358,8 @@
|
||||
952A1530103F66D600B1895D /* explosion.hpp */,
|
||||
952A1531103F66D600B1895D /* irr_driver.cpp */,
|
||||
952A1532103F66D600B1895D /* irr_driver.hpp */,
|
||||
95376CAD1320784100C842A4 /* lod_node.cpp */,
|
||||
95376CAE1320784100C842A4 /* lod_node.hpp */,
|
||||
952A1533103F66D600B1895D /* material.cpp */,
|
||||
952A1534103F66D600B1895D /* material.hpp */,
|
||||
952A1535103F66D600B1895D /* material_manager.cpp */,
|
||||
@ -2980,6 +2985,7 @@
|
||||
9559DE7F12FF777600350DE8 /* rain.cpp in Sources */,
|
||||
9592DC6D13021B350039DBC8 /* minimal_race_gui.cpp in Sources */,
|
||||
95E1FCDF130369EB004D83CC /* per_camera_node.cpp in Sources */,
|
||||
95376CAF1320784100C842A4 /* lod_node.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -33,6 +33,7 @@ using namespace irr;
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/CBatchingMesh.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/lod_node.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/mesh_tools.hpp"
|
||||
#include "graphics/moving_texture.hpp"
|
||||
@ -521,6 +522,8 @@ bool Track::loadMainTrack(const XMLNode &root)
|
||||
MeshTools::minMax3D(merged_mesh, &m_aabb_min, &m_aabb_max);
|
||||
World::getWorld()->getPhysics()->init(m_aabb_min, m_aabb_max);
|
||||
|
||||
std::map< std::string, std::vector< std::pair<int, scene::ISceneNode*> > > lod_groups;
|
||||
|
||||
for(unsigned int i=0; i<track_node->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode *n=track_node->getNode(i);
|
||||
@ -549,6 +552,12 @@ bool Track::loadMainTrack(const XMLNode &root)
|
||||
core::vector3df scale(1.0f, 1.0f, 1.0f);
|
||||
n->get("scale", &scale);
|
||||
|
||||
std::string lodgroup;
|
||||
n->get("lodgroup", &lodgroup);
|
||||
|
||||
int detail = -1;
|
||||
n->get("detail", &detail);
|
||||
|
||||
if (tangent)
|
||||
{
|
||||
scene::IMeshManipulator* manip = irr_driver->getVideoDriver()->getMeshManipulator();
|
||||
@ -601,9 +610,31 @@ bool Track::loadMainTrack(const XMLNode &root)
|
||||
|
||||
|
||||
handleAnimatedTextures(scene_node, *n);
|
||||
m_all_nodes.push_back(scene_node);
|
||||
|
||||
if (lodgroup.empty())
|
||||
{
|
||||
m_all_nodes.push_back( scene_node );
|
||||
}
|
||||
else
|
||||
{
|
||||
lod_groups[lodgroup].push_back( std::pair<int, scene::ISceneNode*>(detail, scene_node) );
|
||||
}
|
||||
} // for i
|
||||
|
||||
scene::ISceneManager* sm = irr_driver->getSceneManager();
|
||||
scene::ISceneNode* sroot = sm->getRootSceneNode();
|
||||
std::map<std::string, std::vector< std::pair<int, scene::ISceneNode*> > >::iterator it;
|
||||
for (it = lod_groups.begin(); it != lod_groups.end(); it++)
|
||||
{
|
||||
LODNode* node = new LODNode(sroot, sm, -1);
|
||||
std::vector< std::pair<int, scene::ISceneNode*> >& nodes = it->second;
|
||||
for (unsigned int n=0; n<nodes.size(); n++)
|
||||
{
|
||||
node->add( nodes[n].first, nodes[n].second, true );
|
||||
}
|
||||
m_all_nodes.push_back( node );
|
||||
}
|
||||
|
||||
// This will (at this stage) only convert the main track model.
|
||||
for(unsigned int i=0; i<m_all_nodes.size(); i++)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user