[2.1] Rotating a node multiple times in world space

Problems building or running the engine, queries about how to use features etc.
Post Reply
Tomeamis
Gnoblar
Posts: 4
Joined: Mon Jan 04, 2016 2:29 pm

[2.1] Rotating a node multiple times in world space

Post by Tomeamis »

I am creating a camera controller with Ogre and it uses some calls to Node.translate() and Node.rotate() in world space. These are called on two nodes in parent-child relationship.
As world space operations use _getDerivedXX(), the second time this happens in a single frame, the assert( !mCachedTransformOutOfDate ); fails.

I see pretty much two ways out of this:
1) Don't use rotate and translate, do my own math using _getDerivedXXUpdated(), that basically means duplicating code from Ogre in my own project.
2) Track changes of both nodes and update their transforms as needed. Unfortunately, _updateFromParent is protected, so I can't use it directly, and using it indirectly would mean using one of the _getDerivedXXUpdated functions and discarding the result.

Unfortunately, both of these kind of smell, so I'm wondering if I've missed some part of Ogre API that lets me do multiple consecutive updates in a single frame without trying to use a stale Transform.
hyyou
Gremlin
Posts: 173
Joined: Wed Feb 03, 2016 2:24 am
x 17
Contact:

Re: [2.1] Rotating a node multiple times in world space

Post by hyyou »

_getDerivedXX()
I am not an expert, but I don't think it is appropriate to request transformation from Ogre, except when rendering.
It is simply not Ogre's duty.

If I remembered it correctly, Ogre 1.9 camera tutorial still applicable for your case
http://www.ogre3d.org/tikiwiki/tiki-ind ... =Tutorials

I have tried it. It requires only a little tweak.
You should also take a look at 2.0 PORTING MANUAL - camera section.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5299
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1280
Contact:

Re: [2.1] Rotating a node multiple times in world space

Post by dark_sylinc »

Both are correct in a kind of way.

When we refactored Ogre, we saw the most common scenario was that static geometry would be set only once then forgotten, and for dynamic geometry a physics engine would update the position and rotation using its own representations, then these would be copied over to Ogre.
Therefore we shifted our focus to optimize Ogre for setting position and rotation from external sources, for later internal processing. It also meant that calling _getDerivedXXUpdated en-mass would result in a huge slowdown (if needed, users could evaluate calling SceneManager::updateSceneGraph to update all nodes efficiently) i.e. calling _getDerivedXXUpdated 10.000 times per frame is bad.

Nonetheless, there were cases where Ogre-only solutions are desirable. Camera handling is a prime example of it.
For those cases, _getDerivedXXUpdated is handy and completely acceptable (it won't make a real difference if it gets called a few times per frame).

Unfortunately when translate( ..., TS_WORLD ) or rotate( ..., TS_WORLD ) are called, the derived transform is required, which means these asserts will trigger if the functions are called in succession (or if called while it's still dirty from something else).
Despite this, because of what we said above we know that translate/roll/_getDerived** are already meant to be called infrequently (e.g. specific cases like camera handling), thus just calling _getFullTransformUpdated without any tracking becomes acceptable i.e.:

Code: Select all

//If you can call them in this order:
node->_getFullTransformUpdated(); //Ensure it's updated
node->rotate( rot, TS_WORLD );
node->translate( pos, TS_WORLD );

//If you have to call translate first:
node->_getFullTransformUpdated();
node->translate( pos, TS_WORLD );
node->_getFullTransformUpdated();
node->rotate( rot, TS_WORLD );
Note that we call _getFullTransformUpdated because it returns a reference to an internal variable (which is a single 32/64-bit pointer value that fits in a register) as opposed to the rest of the _getXXUpdated family where we must load several floats from memory which can be several bytes apart and call Vector3's/Quaternion's constructor, then store the result in the stack.
In other words, even if _getFullTransformUpdated's return value is discarded, the impact should be negligible as the elephant in the room would be the update itself, and the calls shouldn't be frequent.

I personally decided to not expose _updateFromParent in the hopes that users would have to think about the situation in the way you did. I feared exposing it would encourage reckless usage; and since _getFullTransformUpdated was almost the same as calling _updateFromParent, it felt like a win-win.

Therefore if you understand your usage pattern, then just calling _getFullTransformUpdated is just ok.

A lot of careful thought had been given on the refactoring of SceneNodes for Ogre 2.x. This is the "smelly" part, as you said it, of this refactor but we aimed at improved the common case scenario, pushing the smelly parts to the least used cases. Back in 1.x the smelly part used to be the abysmally slow performance, which we fixed.
Tomeamis
Gnoblar
Posts: 4
Joined: Mon Jan 04, 2016 2:29 pm

Re: [2.1] Rotating a node multiple times in world space

Post by Tomeamis »

@hyyou: I thought that since the functions are there, I may as well use them.

Also, I'm not implementing a first person camera controller (already have one. It was easy to implement and works quite well), but something akin to Black and White 2's camera controls, if you've ever played that.

@dark_sylinc: Thanks for the reply. In my case, the update would need to be done only once every couple of seconds, so that should not be a problem.
As it doesn't really construct anything, in this case _getFullTransformUpdated will do nicely, and as you said, I don't think I will run into similar problems elsewhere.
Thanks!
Lax
Hobgoblin
Posts: 583
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 50

Re: [2.1] Rotating a node multiple times in world space

Post by Lax »

Hello together,

I really do not understand, how can I assure, that Ogre updated the nodes and the cache does exist?
I'm using Ogre2.1 for testing and OgreNewt. OgreNewt needs to update scene nodes and their _derived-Data to feed with physics result values. But each time I get the assert.
I do not want to call before each position update:

Code: Select all

node->_getFullTransformUpdated();
As it is not performant?

I read the Ogre 2 Porting manual, but it is not clear what has to be done. Later I have tons of scene nodes which are update by OgreNewt to calculate the final position and orientation, so what must be called, so that everything will run performant?

Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

Lax
Hobgoblin
Posts: 583
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 50

Re: [2.1] Rotating a node multiple times in world space

Post by Lax »

Ok, I managed to fix it.
In OgreNewt there are static and dynamic bodies. Static bodies are not influenced by the physics engine, so I had to introduce a static/dynamic type for bodies. When the body is static and the user changed the position manually, the _getDerived...Updated() is called, else nothing is called. For dynamic bodies, which are updated frequently, _derived... does work!

Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

Post Reply