I want to dynamically load and release objects based on location or time, without making the player wait.
This small demo starts with one Sinbad model on a grass plane, and after 500 frames, switches to a plane of beach stones and adds one more Sinbad.
Starting with ExampleApplication.h
, I put the dynamic code in the frameEnded() function:
bool frameEnded(const FrameEvent& evt) { gpf->frameNUM++; //gpf is pointer to object class gstate if (gpf->loadSTATE==0) if (gpf->frameNUM>500) { gpf->loadSTATE=1; gpf->ent1->setMaterialName("Examples/BeachStones"); gpf->ent2=msm->createEntity("MyEntity2","sinbad.mesh"); //msm is mSceneMgr gpf->node2=msm->createSceneNode("Node2"); msm->getRootSceneNode()->addChild(gpf->node2); gpf->node2->setPosition(10,0,0); gpf->node2->attachObject(gpf->ent2); } updateStats(); return true; }
The entire main.cpp
:
<pre>
#include "Ogre.h"
class gstate {
public:
gstate() { loadSTATE=0; frameNUM=0; ent1=NULL; ent2=NULL; node2=NULL; }
Ogre::Entity *ent1, *ent2;
Ogre::SceneNode *node2;
int loadSTATE,frameNUM;
};
#include "ExampleApplication.h"
class Test4 : public ExampleApplication {
public:
void createScene() {
gp=new gstate();
Ogre::Plane plane(Vector3::UNIT_Y, -10);
Ogre::MeshManager::getSingleton().createPlane("plane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,plane,1500,1500,200,200,true,1,5,5,Vector3::UNIT_Z);
gp->ent1=mSceneMgr->createEntity("GrassPlane","plane");
mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(gp->ent1);
gp->ent1->setMaterialName("Examples/GrassFloor");
Ogre::Entity *ent=mSceneMgr->createEntity("MyEntity","sinbad.mesh");
mSceneMgr->getRootSceneNode()->attachObject(ent);
}
};
Test4 app;
int main(void) {
app.go();
return 0;
}
The remainder of ExampleApp.h
and ExampleFrameListener.h
are untouched, except for changes to allow ExampleApp to share data with the Frame Listener through the gstate class. There must be a more elegant way to expose application objects to the frame listener, but that is a good question for another day.
QUESTIONS:
Is frameEnded() a good place to put dynamic additions to the scene? What would be better?
How to delete the dynamically created mesh, entity, and node?
What Ogre functions are safe to put in a separate thread? Manual Object / position / textureCoord / convertToMesh? What about createEntity / createSceneNode?
Answer to 1): use the scene manager, it has methods to destroy entities and nodes.
2) I don't know, gutfeeling is: none of these.
In general for stuff like scene alterations I would advise against the frame listener but rather implement your own rendering loop using Root->renderOneFrame() (maybe something similar, don't know the exact name from the top of my head)