Jump to content
  • Advertisement
Sign in to follow this  
FxMazter

SceneManager & Entitys & Render Passes?

This topic is 5408 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!