Not calculating world transform each frame?

Started by
8 comments, last by uglybdavis 11 years, 2 months ago

Up until now i've always calculated the world transform once per frame for every object (After the update step, before collision resolution or rendering).

Is there a more optimal way to do this? For instance, only recalculate the final world position if the game object moves? I was thinking of doing that, BUT then each child object would need it's world position recalculated when the parent moves. If i move enough nodes in a tree / frame this could be more expensive than just calculating the world for everything anyway.

Right now i'm submitting the verts for an object in local space with the world matrix to the shader. Should i maybe be submitting them already in world space? But that doesn't really solve my delima.

Sorry if this is a stupid question, but i've been stumped by it all day...

Advertisement
It sounds like you're using a scenegraph, so can't you push transformation matrices when you visit the children?
With for instance glPushMatrix() (I don't know if you're using opengl), you can render the children at their relative coordinates.
If you're going for collisions, you might have to at least do world space bounding boxes...

To what you mentioned, even if you needed to recalculate every child object transform for a change in the parent, isn't that still less work than calculating ALL objects EVERY frame? at worst case you are only adding an extra boolean check(if(this->moved) { do child stuffs }) per object. At best you are saving N-1 transform calculations per frame.

@Burnt_fyr, I see what you mean. Guess ill try going down that road.

@supervga, I wish I was using a scenegraph at this point. I decided i want to try something fancier. The game has a simple array of game objects it loops trough for updates. Each object has a transform that has a parent, which makes up my "scene graph". After all the game objects are updated they recalculate their world position, resolve any collisions and are then rendered.
Rendering is done trough a render component, when one is attached to an object it registers with the render manager. After collisions are resolved, the camera determines which objects in render manager are visible. Each visible object gets its mesh data and world matrix passed to opengl to be rendered.

Is this design too convoluted? What might be a better way to manage these entities and still not be dependant on a scene graph when updating an object?
Sounds like a reasonably standard setup to me. Is there something specific you're trying to simplify, or... ?

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

@supervga, I wish I was using a scenegraph at this point. I decided i want to try something fancier. The game has a simple array of game objects it loops trough for updates. Each object has a transform that has a parent, which makes up my "scene graph". After all the game objects are updated they recalculate their world position, resolve any collisions and are then rendered.
Rendering is done trough a render component, when one is attached to an object it registers with the render manager. After collisions are resolved, the camera determines which objects in render manager are visible. Each visible object gets its mesh data and world matrix passed to opengl to be rendered.

Is this design too convoluted? What might be a better way to manage these entities and still not be dependant on a scene graph when updating an object?

I too think it seems like a fair number of updates (on every object) if you have a low amount of objects.

The peculiar thing with your set up is, that you perform transforms upwards (or, at least, on every item you consider the parent and so forth)

Where you'll find it more straightforward to start from a root node.

I can fully understand if you don't want this; if all your objects are dynamic and independent of oneanother, there's no reason to bind them in a transformation tree.

But this doesn't mean you cannot use optimizations for updates and collisions.

You can also optimize by having

1) a resting flag that is raised when the kinetic energy in the object has run out. (Object stops moving seconds after hitting the ground, etc.)

2) Creating a grid of sectors that each contain a list of references to their contents.

When computing collisions, you can prune objects that are x sectors away from the current object (based on how large objects and sectors are)

If you want to take it a little further, or have a lot of objects, you should look into using Quadtrees (Random, seemingly interesting quadtree article here)

@apochpiq Thanks, having some confirmation that this is a pretty standard setup helps. I'm not looking for anything specific, this is the first time i'm rendering things from a render queue (Up until now everything i did graphics wise was immediate (and fixed function pipeline)). It's also the first time i'm not using a monolithic scene graph. I'm used to traversing the graph once, and calling it a day. Like SuperVGA pointed out, it seems like a fair amount of work for a simple scene.

@SuperVGA you got me thinking, having a list of children in each transform rather than a parent wouldn't be a crazy idea and i could definitely save some time there.

The article is pretty great, i was planning to implement an Oct-Tree further down the line; just haven't gotten around to it yet. I'm still busy trying to to jump back to using a monolithic scene graph :)

Thanks for clearing these things up guys!

My original question has been answered at this point, regardless if anyone else has comments or suggestions i would love to hear them.

Think i figured out what i want to do. First, each game object contains a transform. Each transform contains an array of child transforms (A scene graph of sorts)


class Scene {
	vector<GameObject*> m_pGameObjects;
	Transform* m_pRootTransform;

	void Update() {
		foreach(GameObject* go in m_pGameObjects) 
			go->Update();
		foreach(GameObject* go in m_pGameObjects)
			go->UpdateCoroutines();
		foreach(GameObject* go in m_pGameObjects)
			go->LateUpdate();
		
		UpdateDirtyTransforms(Transform);
		ResolveCollisions(Transform);
	}
};

Each object can be moved in any of the three update functions. If moved, the transform of the game object is marked dirty. UpdateDirtyTransforms will simply traverses the graph and updates all nodes recursively based on the top most dirty node that is hit. After each transform is moved into world space, the game can resolve collisions if needed. Resolve Collisions will issue OnCollision callbacks to each script

Now the big issue i see with this is if a parent's world position is updated in update, and in Late update another object tries to collide with the child of said parent that was moved. The resolve collisions function will recalculate all positions and send out the OnCollision message, no problem. BUT if i just try to access the transform of the child object directly and do manual math on it, that would be in the wrong world spot.

This leads me to think it might be more beneficial to update the transform (and all it's children) immediately... But that seems so wasteful....

Any insight as to this delima?

Make sure you maintain a clean separation between "the state the world is in during the current simulation frame" and "the state the world is going to be in once this frame is done updating." One simple way to do this is double-buffering.

Basically, as you resolve collision responses, you should be updating the new world state, not clobbering the existing world state. This allows you to resolve objects in any order without worrying about whose transforms are in the "new" versus "old" states.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

@ApochPiQ THANK YOU that was the last bit of dark magic i needed.

This topic is closed to new replies.

Advertisement