[osg-users] Coordinate system in all readerwriters

17 views
Skip to first unread message

Sukender

unread,
Dec 28, 2009, 11:54:59 AM12/28/09
to osg-users
Hi all,

I've got a question/remark: Are all readers supposed to adapt models to the OpenGL's coordinate system (I mean that +/- Y/Z-up thing)? If so:
1. It doesn't seem to be with some readers.
2. All writers, AFAIK, directly write the scene without any further processing. Thus osgconv-like programs may produce a rotated scene (with respect to the original one) if the reader processes coordinate system and writer doesn't. When reading an FBX and exporting to 3DS for instance, it may happen.

On the other hand, if readers are supposed to ignore this, we'll loose features by removing coordinate system adaptation in existing readers (=FBX).

Other problems are:
- If we change things in readers, it will break many users' apps.
- If we plan to make all writers respect the coordinate systems, it'll also break things.

Discussion is opened :)

Cheers,

Sukender
PVLE - Lightweight cross-platform game engine - http://pvle.sourceforge.net/
_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Paul Martz

unread,
Dec 28, 2009, 1:11:40 PM12/28/09
to OpenSceneGraph Users
Hi Sukender --

First, OpenGL doesn't really have a default coordinate system (see the
thread "Cameras View Matrix - I am perplexed" from October). osgGA
camera manipulators use a right-handed +z up convention for the home
position, but this is easily configured to anything else by the app if
desired. Also, OSG apps don't have to use osgGA manipulators, they can
use their own. So although osgGA has a default, I'd argue it's incorrect
for any code to make assumptions about an OSG app's coordinate system.

Regarding OSG plugins, I think their primary job is to either give me
what they read, or write out what I give them. If I modeled an aircraft
with the nose pointing in +y, then I expect the OSG plugin to give me a
scene graph with the nose pointing in +y. If it doesn't do this by
default, that's a bug, isn't it?

That being said, I don't object to OSG plugins having Options to control
application of transformations. In fact, this is required in some cases.
For example, OpenFlight DOF nodes specify range of motion parameters,
and the plugin must scale and rotate these values to match the app's
coordinate system.

Paul Martz
Skew Matrix Software LLC
_http://www.skew-matrix.com_ <http://www.skew-matrix.com/>
+1 303 859 9466

Sukender

unread,
Dec 29, 2009, 1:26:36 AM12/29/09
to OpenSceneGraph Users

Hi Paul,

What I like with you is that your answers are clear! ;) Well you're absolutely right. Thanks.

The only thing that bothers me is: should "write( read(A) ) == A"? As far as I'm concerned, I would answer "yes". And you?
This is not the case when reading FBX and writing, for instance (regardless of the output format). So I've been scratching my head to figure out where the problem (bug?) is, and I still don't find a suitable answer. Maybe something stupid I don't see in my code...

Cheers,

--

Sukender
PVLE - Lightweight cross-platform game engine - http://pvle.sourceforge.net/

Paul Martz

unread,
Dec 29, 2009, 12:06:38 PM12/29/09
to OpenSceneGraph Users
Sukender wrote:
> What I like with you is that your answers are clear!

Ha!

> The only thing that bothers me is: should "write( read(A) ) == A"? As
> far as I'm concerned, I would answer "yes". And you?

Yes, for the coordinate system, definitely.

> This is not the case when reading FBX and writing, for instance
> (regardless of the output format). So I've been scratching my head to
> figure out where the problem (bug?) is, and I still don't find a
> suitable answer. Maybe something stupid I don't see in my code...

I've noticed the same thing with OBJ. Try this:
osgconv dumptruck.osg dumptruck.obj
osgviewer dumptruck.obj
You get a truck on its side. I agree with you that this is incorrect
behavior. This doesn't happen in conversion to FLT and back to OSG, for
example.

I'm reluctant to use the term "bug" because I think the plugin was coded
this way intentionally, so the code is doing exactly what it was
designed to do. Perhaps it's a "bug" in the design of the plugin, which
was trying to solve a problem that didn't really exist.

When I encountered this issue with OBJ, I wanted to submit a fix for it,
but didn't want to waste time creating a fix that would get rejected
because it might break existing apps. So, thank you for bringing up this
topic. :-) If we all agree this is wrong, then we can fix the issue,
accept the consequences, and be better off several months down the road.

I ended up working around the OBJ issue by using the ROT pseudoloader to
apply a -90 degree rotation around the x axis:
osgconv dumptruck.osg.-90,1,0,0.rot dumptruck.obj
osgviewer dumptruck.obj
You should be able to do the same, in lieu of any code change.
-Paul

Paul Martz

unread,
Dec 29, 2009, 12:52:40 PM12/29/09
to OpenSceneGraph Users
Paul Martz wrote:
> I've noticed the same thing with OBJ.

A little digging reveals that the OBJ plugin has a "noRotation" Option
that disables the x axis rotation. The rotation is only done on file
load, not on file write.

Rotation about x is on by default. I'd suggest a change to off by
default, and the Option changed to "doRotation" to enable it.

Ulrich Hertlein

unread,
Dec 30, 2009, 4:05:53 AM12/30/09
to OpenSceneGraph Users
On 29/12/09 6:52 PM, Paul Martz wrote:
> Paul Martz wrote:
>> I've noticed the same thing with OBJ.
>
> A little digging reveals that the OBJ plugin has a "noRotation" Option
> that disables the x axis rotation. The rotation is only done on file
> load, not on file write.
>
> Rotation about x is on by default. I'd suggest a change to off by
> default, and the Option changed to "doRotation" to enable it.

The .x plugin has 'leftHanded' and 'rightHanded'. Maybe we could establish a common
option for this type of functionality (one that does 'convert to right-handed, Z-axis up').

There already are options with (apparently) related functionality (courtesy of 'osgconv
--formats'):

Coordinate system:
obj:noRotation
x:leftHanded
x:rightHanded

Optimization:
obj:generateFacetNormals
obj:noTriStripPolygons
stl:generateNormals
stl:smooth
stl:tristrip

Image orientation
hdr:NO_YFLIP
hdr:YFLIP
x:flipTexture

Cheers,
/ulrich

Sukender

unread,
Dec 30, 2009, 5:35:30 AM12/30/09
to OpenSceneGraph Users
Hi Ulrich, Paul, and all,

I agree we should unify the coordinate system during loading AND writing. Here are my suggestions :
- Have plugins do NO rotation by default (reading and writing) when the format doesn't have coordinate system information (that is to say all but FBX and maybe FLT).
- Have plugins read and apply coordinate system information if available by default when reading.
- Have optionnal READING options:
- readXup, readYup, readZup to suppose model is X, Y or Z-up (overrides format's coordinate system information)
- readLeftHanded, readRightHanded (similar setting)
- When in conflict (two options defined), use the latest one
- Have optionnal WRITING options:
- writeXup, writeYup, writeZup, writeLeftHanded, writeRightHanded (which should almost never be supported, in my opinion)
- Let plugings optionnally support these options prefixed with their name and "_". For instance "3ds_readYup" would assume ONLY ".3ds" files are Y-up. These would take precedence over the general settings.
- Also support "pluginName_read/writeAutoUp" and "pluginName_read/writeAutoHanded", which would specifically deactivate a global setting for a given plugin. For instance, "fbx_readAutoUp" would let the plugin decide the up vector (here using coordinate system information in the .fbx). "3ds_readAutoUp" would mean "no rotation" for .3ds.
- Write a portion of code somewhere in osgDB to parse all these options and store it in a nice structure (to avoid each plugin duplicating code). To be called with something like "myStructure = osgDB::readStandardCoordinateSystemOptions(PLUGIN_NAME)".
- As OpenGL doesn't have a "etched in stone" orientation standard, use the osgGA as an "internal" standard (that is to say +Z up, right handed) when a change is needed.

1. Please raise your hand if you agree, and tell about changes you'd like to introduce in this summary.
2a. Please mention all plugins you know which break these rules.
2b. Please tell if you agree modifying those plugins.

When all is ok, I'll code it.

Cheers,

Sukender
PVLE - Lightweight cross-platform game engine - http://pvle.sourceforge.net/

----- "Ulrich Hertlein" <u.her...@sandbox.de> a écrit :

Rizzen

unread,
Dec 30, 2009, 8:37:33 AM12/30/09
to OpenSceneGraph Users
Hi all,

Defining a coordinate system for OSG is a good idea. Though to me the
most important aspect of reader and writers, is that this expression
must be true:

read( write( A ) ) = A

Rizzen

Sukender

unread,
Dec 30, 2009, 9:10:22 AM12/30/09
to OpenSceneGraph Users
Hi Rizzen,

Of course! I forgot to add this to the summary.

Sukender
PVLE - Lightweight cross-platform game engine - http://pvle.sourceforge.net/

----- "Rizzen" <riz...@darkstar.co.za> a écrit :

Ulrich Hertlein

unread,
Dec 30, 2009, 10:32:33 AM12/30/09
to OpenSceneGraph Users
Hi all,

On 30/12/09 11:35 AM, Sukender wrote:
> - Have plugins do NO rotation by default (reading and writing) when the format doesn't
have coordinate system information (that is to say all but FBX and maybe FLT).
> - Have plugins read and apply coordinate system information if available by default when reading.
> - Have optionnal READING options:
> - readXup, readYup, readZup to suppose model is X, Y or Z-up (overrides format's
coordinate system information)
> - readLeftHanded, readRightHanded (similar setting)
> - When in conflict (two options defined), use the latest one
> - Have optionnal WRITING options:
> - writeXup, writeYup, writeZup, writeLeftHanded, writeRightHanded (which should almost
never be supported, in my opinion)
> - Let plugings optionnally support these options prefixed with their name and "_". For
instance "3ds_readYup" would assume ONLY ".3ds" files are Y-up. These would take
precedence over the general settings.
> - Also support "pluginName_read/writeAutoUp" and "pluginName_read/writeAutoHanded",
which would specifically deactivate a global setting for a given plugin. For instance,

Do we really want all those options? At the moment we only have:
- rotate around X-axis (for Y-up to Z-up conversion) and
- convert left- to right-hand CS

While I agree that plugins could leave the orientation alone I still think that they
should do the conversion to a right-handed coordinate system by default, because the
default OpenGL face-winding is right handed.

Additionally, how would the applied transformation be transmitted to the writer? If this
were to be stored with the loaded node then it could be automatically be undone by the
writer. Another possibility might be to just create a transformation node above the
unmodified model. The transformation node could do all the necessary scaling/rotation
(and FrontFace); this could simply be ignored when writing. The downside of this is that
it doesn't integrate nicely and might be a performance penalty.

Sukender

unread,
Dec 30, 2009, 11:21:59 AM12/30/09
to OpenSceneGraph Users
Hi ulrich,

As Paul said, OpenGL doesn't have any convention. It's just a "common usage" that tell us we should use right-handed.
However, I agree the number of proposed options could be reduced (I just fear that it may become less explicit... or not?).

Your reflexion make me think we should merge read and write options. That way, we may have the two options you mentionned, and writing would the do the opposite operation. We thus keep write(read(A)) == A.

Is that okay for you?

Sukender
PVLE - Lightweight cross-platform game engine - http://pvle.sourceforge.net/

----- "Ulrich Hertlein" <u.her...@sandbox.de> a écrit :

> Hi all,

Paul Martz

unread,
Dec 30, 2009, 1:12:23 PM12/30/09
to OpenSceneGraph Users
To simplify things, I'd propose the following:

- I don't think we need options to control writing. Your app can do
any required transformation with a NodeVisitor before calling osgDB to
write. The plugin should just write the scene graph passed to it.
- For reading, we just need rotation and scale options. "rotate <axis>
<degrees>" and "scale <x> <y> <z>". Those alone will handle changes to
orientation, handedness, and unit scaling.
- If the format stores an up vector, handedness, and unit information,
then the import plugins for those few formats need some kind of
"convertTo" option, sort of like FLT's "convertToMeters" (which scales
the model from its native units).

As an addendum to the last point, regarding Ulrich's comment, an import
plugin can only convert to right-handed if it knows the handedness of
the model. Which formats store that information? And to clarify,
OpenGL's "right-handed" rule is only the default for the definition of a
front face. Your application and your models may or may not use this
convention, and I think it would be wrong for a plugin to do such a
conversion automatically, assuming it knows something about the
convention you are using.

Finally, in principle, I agree: write( read( A ) ) should equal A. But I
want to re-emphasize this can only be true in the context of coordinate
systems. (100% equality in round-trip model conversions is essentially
an impossibility.)

_______________________________________________

Sukender

unread,
Dec 31, 2009, 2:24:01 AM12/31/09
to OpenSceneGraph Users
Hi Paul and all,

I agree with you simplification, but I'm not sure it'll keep write(read(A))==A. For instance:
- Read a model with a rotation (Y to Z-up for instance). Your +y facing plane will be then +z facing.
- Write the model. Model is still rotated and will be +z in the file, thus having write(read(A))!=A.

This is why I suggested writers should "undo" what is done during the reading by applying the opposite transform given by the read options. Of course one could have control over those things by changing options between reading and writing, but it's then the user's choice. It's surely the same when writing first and then reading.

Am I wrong?

Cheers,

Sukender
PVLE - Lightweight cross-platform game engine - http://pvle.sourceforge.net/

----- "Paul Martz" <pma...@skew-matrix.com> a écrit :

Paul Martz

unread,
Dec 31, 2009, 2:53:04 PM12/31/09
to OpenSceneGraph Users
Sukender wrote:
> Hi Paul and all,
>
> I agree with you simplification, but I'm not sure it'll keep write(read(A))==A. For instance:
> - Read a model with a rotation (Y to Z-up for instance). Your +y facing plane will be then +z facing.
> - Write the model. Model is still rotated and will be +z in the file, thus having write(read(A))!=A.

Transforms during write are already entirely under application control
because the application has access to the scene graph. In the case
above, if the app wants to restore the original coordinate system, it
would do this with the inverse transform before it writes the scene graph.

In fact, I don't think we need these options in the plugin for read,
either. The application would simply transform the scene graph after the
read completes.

In my opinion, the only situation in which plugins _require_ these
options is for the few formats that store units, handedness, and
coordinate system info in the file format, and the app needs to
"convertTo" a la OpenFlight. For all other formats, the application can
do the transformation itself, with a NodeVisitor or Transform.

But we should probably support some kind of transform Options for all
import plugins anyway, for backwards compatibility. If we change all
import plugins to not transform by default, application developers will
want an easy switch to get the old default behavior from the plugin.
-Paul

Reply all
Reply to author
Forward
0 new messages