/**
* All scene graph nodes will be derived from this class.
*/
class ISceneGraphNode : public IMBase
{
protected:
util::list<ISceneGraphNode*> m_childList; ///< Holds all the child nodes of this node
scene::ISceneManager* m_sceneManager; ///< Pointer to the scene manager for rendering and other
public:
/**
* Constructor
* \param smgr A pointer to the scene manager
*/
ISceneGraphNode(scene::ISceneManager* smgr)
: m_sceneManager(smgr)
{
// We are not calling smgr->get() because we want the graph to be destroyed when
// smgr->drop() is called.
}
/**
* Copy constructor
* \param i A const reference to an object derived from ISceneGraphNode
*/
ISceneGraphNode(const ISceneGraphNode& i)
: m_sceneManager(i.m_sceneManager)
{
// We are not calling smgr->get() because we want the graph to be destroyed when
// smgr->drop() is called.
}
/**
* Destructor
*/
virtual ~ISceneGraphNode()
{
util::list<ISceneGraphNode*>::iterator i = m_childList.begin();
for( ; i != m_childList.end() ; i++)
(*i)->drop(); // reduce the ref_count for all child nodes
m_sceneManager->drop();
}
/**
* Add a node to the child list.
* \param n A pointer to a ISceneGraphNode derived object
*/
void addSceneGraphNode(scene::ISceneGraphNode* n)
{
m_childList.push_back( n ); // add n to the list
}
/**
* Render all the child nodes.
*/
virtual void render()
{
util::list<ISceneGraphNode*>::iterator i = m_childList.begin();
for( ; i != m_childList.end(); i++)
(*i)->render(); // render child node
}
/**
* Things to do before rendering, like updating.
* \param delta_time The time (in seconds) since the last rendering frame
*/
virtual void preRender(float delta_time)
{
util::list<ISceneGraphNode*>::iterator i = m_childList.begin();
for( ; i != m_childList.end(); i++)
(*i)->preRender(delta_time); // render child node
}
/**
* Things to do after rendering.
* \param delta_time The time (in seconds) since the last rendering frame
*/
virtual void postRender(float delta_time)
{
util::list<ISceneGraphNode*>::iterator i = m_childList.begin();
for( ; i != m_childList.end(); i++)
(*i)->postRender(delta_time); // render child node
}
};
/**
* Render all objects in the scene graph.
*/
void CSceneGraph::render()
{
util::list<ISceneGraphNode*>::iterator i = m_nodeList.begin();
for( ; i != m_nodeList.end(); i++){
(*i)->preRender( m_hiResTimer.getElapsedSeconds() );
(*i)->render();
(*i)->postRender( m_hiResTimer.getElapsedSeconds() );
}
}
/**
* Update the animation.
* \param delta_time The time since the last update.
*/
void update(float delta_time)
{
m_modelTime += delta_time;
if ( m_modelTime >= 1.0f / MD2AnimationList[m_animState].fps )
m_modelTime = 0.0f;
updateInterpolation( m_modelTime / ( 1.0f / MD2AnimationList[m_animState].fps ) );
}
/**
* Pre-render things, like updating the animation.
*/
void preRender(float delta_time)
{
update(delta_time); // updates the animation
ISceneGraphNode::preRender(delta_time);
}
/**
* Render the model using indexed vertex arrays.
*/
void render()
{
if(m_texture)
m_texture->apply(); // apply the texture
// draw the indexed triangle list
m_sceneManager->getVideoDriver()->drawIndexedTriangleList(
m_displayVertexList.getPtr(), m_displayVertexList.getSize(),
m_displayIndexList.getPtr(), m_displayIndexList.getSize() );
ISceneGraphNode::render(); // render all the children
}