SceneManager & Entitys & Render Passes?

Started by
12 comments, last by FxMazter 19 years, 6 months ago
Hello! I'm currently designing my scenemanager. For now I'm having some problems with the entity design... In the SceneManager I'm saving Entity objects, those objects can be Renderable, Sound or Physics objects... They are all saved in a std::vector as an "Entity". Then when it comes to rendering the objects, I must somehow identify the objects that are Renderable right? So I iterate through my list checking for renderables, and similarily I would do the same for other types. (This is the basic idea...I know of some ways to speed this up...) SO, basically: for(int i = 0; i < vecAllEntitys.size(); ++i) { if(vecAllEntitys->GetEntityID() == I_RENDERABLE) { //Prepare the object for rendering } } This is the first time I'm making a SceneManager / SceneGraph... I would really appreciate if you guys could fill me in with some other designs on what I have done above. Thank you! [Edited by - FxMazter on September 29, 2004 10:29:39 AM]
Advertisement
Another way to do it is to give each of your entities a common interface. That way you wouldn't need to check which type of entity it is. Base all your different kinds of entities, (sound, renderable, etc.), on a single base class IEntity.

The base class would have functions for updating itself every frame. So that your code would become:

for(int i = 0; i < vecAllEntitys.size(); ++i) {  // Update the entity  vecAllEntitys->Update();}


How you update the entity, and which parameters you send with the function is purely implementation-specific...
Or you could have a SceneGraphNode that is a separate class to Entity. This way you could derive from SceneGraphNode for each node type and implement a DoAction() function that calls the appropriate function on the Entity.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Or you could have separate structure which handles renderable entities, structure which manages sound entities, etc. but still you hold them in one scenegraph (for serialization, high-level view, attachments, etc.)
So... Muira Yoshimoto sliced off his head, walked 8 miles, and defeated a Mongolian horde... by beating them with his head?

Documentation? "We are writing games, we don't have to document anything".
Quote:Original post by FxMazter
In the SceneManager I'm saving Entity objects, those objects can be Renderable, Sound or Physics objects... They are all saved in a std::vector as an "Entity".


ah, and i never found a solution thats really making me happy. lets take render, physics, sound objects. all of them need a position, so no matter if you put it into the class itself or use multiple inheritance you end up with three positions. sure, thats useful if all three use different positions and you dont really mind updating all of them all the time or dont care about ignoring two of them.

for the list/vector you could of course simply use different vectors in addition to the "abstract" scenegraph, so you dont waste time on ifs or calling basically empty functions. removing an object will be more work obviously.

another thing thats kind of ugly as well is using pointers. not really that different from inheritance.

struct entity {  Render* render;  Physics* physics;  Sound* sound;  Position* position;};


that would avoid the problems of multiple inh. at the expense of needing a "parent" pointer in all subobjects, making sure that position will exist if render exists and accessing the position from within render in an ugly way like parent->position.


though if all you want is removing a ton of ifs (that often beautifully kill your cache in critical places) you could go with "empty" functions (though then ALL entities always have a render() function, no matter if its used or not) though im not sure if the useless stack pushing and popping is much better than an if or simply seperate lists for different jobs.
f@dzhttp://festini.device-zero.de

what you have is what i do. Accept what i do is query a boolean to see if the entity is visible.

if (entity->IsVisible())
{
}

I understand how you can have different types of entities, like weapons, inventory, and static brushes. what i have done in my engine is made sure the renderer has no clue what an entity is. they merely send over the model instances. this way someone is able to declare a lightweight structure that simply contains model data and send that through the pipeline.

[Edited by - vajuras on September 26, 2004 9:34:23 AM]
Another thread
So... Muira Yoshimoto sliced off his head, walked 8 miles, and defeated a Mongolian horde... by beating them with his head?

Documentation? "We are writing games, we don't have to document anything".
I'm also contemplating the same thing. I don't worry much about multiple inheritance as it was created for a reason, and there ARE times where it is appropriate (believe it or not).

I'm considering having base classes Renderable, Sound or Physics objects as well. Each of these can hold a static pointer/reference to their manager, then update themselves by calling
manager.update(this);

class manager{  public:    manager();    update_entity(const entity*);    ....  private:    list<entity> entitylist;    ....};manager::manager(){  entity::man=this;}class entity{  friend class manager;  public:    update();  private:    static manager* man;};entity::update(){  man.update(this);}


Where manager would be something like Renderer or Physics
and entity would be Renderable or Physical, respectively.

It would of course have to use multiple inheritance, but its one of the more elegant (IMHO) choices I've considered.
Just thought I'd throw my two cents in.

I've always created in-game objects with bounding volumes. This lets me test each object type for visibility and usage in the scene. Here's an idea of the "big' picture
class InGameObject{...sxBoundingVolume *Give_Volume();virtual void Think()=0;virtual void Render()=0;...}//ingame objects that need updating..class Geometry : public InGameObject{...}class Emitter : public InGameObject{...}class Map //loaded from file{vector <Geometry> geo;vector <Emitter> particles;...}class RenderList{...void CreateVisibleList(Map *map,Frustum *frust);void CullInGameObjects();void SortSkipInGameObjects();}class Scene{...Map *g_Map;void GetVisibleList();void RenderList(RenderList *list);void Think();}


Scene::Think() and RenderList::SortSkipInGameObjects() are the two big hitters here. Think handles update for everyone in the scene, while SortSkip sorts visible geometry into effecient batches, and places non renderables into specific usage lists. (IE if we have a sound, add it to the sound array, and call sound player)

Hope that helps
==Colt "MainRoach" McAnlisGraphics Engineer - http://mainroach.blogspot.com
Thx guys! Keep the ideas comming ! :)

After reading some posts about SceneManagement I have decided something like this:

1. Accosding to Yann the Scene Graph should not be rendering stuff... only Updating the world right? So thats what I'm gonna do. But then I'm alsi gonna mix the SceneGraph implementations with an Octree by multiple inheritance.

2. I'm thinking about a Messaging system for rendering. The updating of objects will be taken care by the SceneManager:

node->Process();

But the rendering will be taken care by some other structure that will send messages to the objects to render like:

IMessage* pRenderPassMessage = 0;
for(all render passes) {
pRenderPassMessage = someRenderPass;
pRenderPassMessage->SetRenderPassInfo(...);
for(all visible objects to render) {
notifyAllRenderable(pRenderPassMessage, this);
}
}

Then an abject could look like this:

notified(IMessage* pMessage, IMessenger* pSource) {
IRenderLoop* pRenderLoop = (IOctree*)pSource;
IRenderer* pRenderer = pRenderLoop->GetRenderer();

if(rtti_system::dyn_cast<PreRenderPassMessage*>(pMessage)) {
...
}

if(rtti_system::dyn_cast<ReflectRenderPassMessage*>(pMessage)) {
...
}

if(rtti_system::dyn_cast<RefractRenderPassMessage*>(pMessage)) {
...
}

if(rtti_system::dyn_cast<MainRenderPassMessage*>(pMessage)) {
...
}

if(rtti_system::dyn_cast<TransparencyRenderPassMessage*>(pMessage)) {
...
}

if(rtti_system::dyn_cast<PostRenderPassMessage*>(pMessage)) {
...
}
}

How does that look guys?

This topic is closed to new replies.

Advertisement