我应该在Ogre3D框架的哪里添加/删除动态对象?
我想根据位置或时间动态加载和释放对象,而不让玩家等待。
这个小型演示从草地平面上的一个辛巴达模型开始,500 帧后,切换到海滩石头平面并添加另一个辛巴达。
从 ExampleApplication.h
开始,我将动态代码放入 frameEnded() 函数中:
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; }
整个 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;
}
ExampleApp.h
和 ExampleFrameListener.h
的其余部分保持不变,除了允许 ExampleApp 通过 gstate 类与 Frame Listener 共享数据的更改之外。必须有一种更优雅的方法将应用程序对象公开给帧侦听器,但这是另一个很好的问题。
问题:
frameEnded() 是向场景添加动态内容的好地方吗?什么会更好?
如何删除动态创建的网格、实体、节点?
哪些 Ogre 函数可以安全地放入单独的线程中?手动对象/位置/textureCoord/convertToMesh? createEntity / createSceneNode 怎么样?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
回答1):使用场景管理器,它有销毁实体和节点的方法。
2)我不知道,直觉是:这些都不是。
一般来说,对于诸如场景更改之类的内容,我建议不要使用帧侦听器,而是使用 Root->renderOneFrame() 实现您自己的渲染循环(也许类似,但我不知道确切的名称)
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)