[osg-users] getting translate rotate scale right.

2009-01-15 Thread Dorosky, Christopher G

I thought I understood this just fine, but I apparently don't.

I have a model that is half the size it needs to be. So, I need to scale
it by 2.0 in all directions.

It is also in the wrong position, so I need to translate it out to
(1000, 2000, 3000);

Once it is translated, I need to rotate it. This involves quats, but for
simplicities sake, lets say the rotations are 10,20,30. Order is
irrelevant, since I am just trying to print these things for now.

So, I have a matrix transform. I set the matrix by:

Mt-setMatrix(osg::Matrix::scale( scalevec) * osg::Matrix::rotate(
rotquat) * osg::Matrix::trans (transvec));

Seems fine.
Then, if I print out the values, I get some goofiness.

Using the matrix getScale(), getTrans(), getRot() routines, I get them
and print out values.

Trans is fine. Rot and scale are goofy.
This doesn't entirely surprise me, since the order of operations is
dependent.

In the scene graph, it looks wrong.

If I use a position attitude transform, and explicitly set the trans,
rot, scale separately, then it works.

Before, I would have had a series of matricies that looks like this:

Scenegraph root -trans-rot-scale-model;

What's the right way to do this?

I'm thinking a translate - rotate - -translate  is involved somehow.

BTW if the scale is 1.0 in all directions, this works just fine.

Thanks...

Chris
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] getting translate rotate scale right.

2009-01-15 Thread Dorosky, Christopher G
As usual, when I spend a day or two on something, I figure out the
answer immediately after I post a question to this list.

Problem was, I was fooling with the matrix afterwards, and recomposing
it.

GetRotate and GetScale mess up if matrix has both.
Decompose is needed.

Heh... I just noticed that Gazi posted this as well.

Thanks

Chris

-Original Message-
From: osg-users-boun...@lists.openscenegraph.org
[mailto:osg-users-boun...@lists.openscenegraph.org] On Behalf Of
Dorosky, Christopher G
Sent: Thursday, January 15, 2009 11:40 AM
To: osg-users@lists.openscenegraph.org
Subject: [osg-users] getting translate rotate scale right.


I thought I understood this just fine, but I apparently don't.

I have a model that is half the size it needs to be. So, I need to scale
it by 2.0 in all directions.

It is also in the wrong position, so I need to translate it out to
(1000, 2000, 3000);

Once it is translated, I need to rotate it. This involves quats, but for
simplicities sake, lets say the rotations are 10,20,30. Order is
irrelevant, since I am just trying to print these things for now.

So, I have a matrix transform. I set the matrix by:

Mt-setMatrix(osg::Matrix::scale( scalevec) * osg::Matrix::rotate(
rotquat) * osg::Matrix::trans (transvec));

Seems fine.
Then, if I print out the values, I get some goofiness.

Using the matrix getScale(), getTrans(), getRot() routines, I get them
and print out values.

Trans is fine. Rot and scale are goofy.
This doesn't entirely surprise me, since the order of operations is
dependent.

In the scene graph, it looks wrong.

If I use a position attitude transform, and explicitly set the trans,
rot, scale separately, then it works.

Before, I would have had a series of matricies that looks like this:

Scenegraph root -trans-rot-scale-model;

What's the right way to do this?

I'm thinking a translate - rotate - -translate  is involved somehow.

BTW if the scale is 1.0 in all directions, this works just fine.

Thanks...

Chris
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.or
g
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] getting translate rotate scale right.

2009-01-15 Thread Gazi Alankus
I can't tell you the right answer, but maybe this might help a little bit.
[rant]
OSG matrices are not correct homogeneous transformation matrices. They are
transposed. When you come up with a solution that involves multiplication of
transformation matrices on paper, you have to reverse the order of
multiplications when implementing it with OSG to get things working.

This problem arises from the confusion that OpenGL stores matrices in
column-major order and OSG treats that data as if it was stored in row-major
order, effectively transposing the matrix. There is no such thing as
row-major matrix since matrices are mathematical entities that have
nothing to do with storage.

So, if you have a linear algebra and theoretical computer graphics
background, every time you multiply matrices by hand in OSG you are likely
to make mistakes. Looking at your problem again with this light might help.

Just my 0.02. I didn't want to offend anybody, OSG is an amazing piece of
library. It just hurts me that there is such a fundamental issue with it.
[/rant]

Apart from that, docs for osg::Matrixd::getRotate() state:

Note that this function assumes a non-scaled matrix and will return
incorrect results for scaled matrixces. Consider decompose() instead.

That would probably help.

-Gazi

2009/1/15 Dorosky, Christopher G christopher.g.doro...@lmco.com


 I thought I understood this just fine, but I apparently don't.

 I have a model that is half the size it needs to be. So, I need to scale
 it by 2.0 in all directions.

 It is also in the wrong position, so I need to translate it out to
 (1000, 2000, 3000);

 Once it is translated, I need to rotate it. This involves quats, but for
 simplicities sake, lets say the rotations are 10,20,30. Order is
 irrelevant, since I am just trying to print these things for now.

 So, I have a matrix transform. I set the matrix by:

 Mt-setMatrix(osg::Matrix::scale( scalevec) * osg::Matrix::rotate(
 rotquat) * osg::Matrix::trans (transvec));

 Seems fine.
 Then, if I print out the values, I get some goofiness.

 Using the matrix getScale(), getTrans(), getRot() routines, I get them
 and print out values.

 Trans is fine. Rot and scale are goofy.
 This doesn't entirely surprise me, since the order of operations is
 dependent.

 In the scene graph, it looks wrong.

 If I use a position attitude transform, and explicitly set the trans,
 rot, scale separately, then it works.

 Before, I would have had a series of matricies that looks like this:

 Scenegraph root -trans-rot-scale-model;

 What's the right way to do this?

 I'm thinking a translate - rotate - -translate  is involved somehow.

 BTW if the scale is 1.0 in all directions, this works just fine.

 Thanks...

 Chris
 ___
 osg-users mailing list
 osg-users@lists.openscenegraph.org
 http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] getting translate rotate scale right.

2009-01-15 Thread Paul Fotheringham
--- On Thu, 15/1/09, Gazi Alankus ala...@gmail.com wrote:

 From: Gazi Alankus ala...@gmail.com
 Subject: Re: [osg-users] getting translate rotate scale right.
 To: OpenSceneGraph Users osg-users@lists.openscenegraph.org
 Date: Thursday, 15 January, 2009, 6:25 PM
 I can't tell you the right answer, but maybe this might
 help a little bit.
 [rant]
 OSG matrices are not correct homogeneous
 transformation matrices.

Eh? By what definition exactly?

They are
 transposed. When you come up with a solution that involves
 multiplication of
 transformation matrices on paper, you have to reverse the
 order of
 multiplications when implementing it with OSG to get things
 working.
 
 This problem arises from the confusion that OpenGL stores
 matrices in
 column-major order and OSG treats that data as if it was
 stored in row-major
 order, effectively transposing the matrix.

OpenGL is neither row-major or column-major. It treats a transformation matrix 
as 16 floats, nothing more. Only when one imposes a 4x4 structure of rows and 
columns on the 16 numbers does one then encounter the question Which way shall 
I order them?. At that point you choose row-major or column-major as the 
description of how your data is stored in the matrix.

 There is no such
 thing as
 row-major matrix since matrices are
 mathematical entities that have
 nothing to do with storage.

Yes there is, I've just described it above. It's storage that has nothing to do 
with it i.e. OpenGL's view of it as 16 numbers, it's how you construct your 
mathematical entity, your matrix, that imposes one view or the other.

Paul


  
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] getting translate rotate scale right.

2009-01-15 Thread Gazi Alankus
A correct transformation matrix (which is a 2D entity) according to math
literature:

R11 R12 R13 Tx
R21 R22 R23 Ty
R31 R32 R33 Tz
0 0 0 1

That matrix stored in column-major order in 1D memory:
R11 R21 R31 0 R12 R22 R32 0 R13 R23 R33 0 Tx Ty Tz 1

That matrix stored in row-major order in 1D memory:
R11 R12 R13 Tx R21 R22 R23 Ty R31 R32 R33 Tz 0 0 0 1

If these are the things you dispute, that is an easier argument to deal
with. Otherwise my response follows:


2009/1/15 Paul Fotheringham osg_u...@yahoo.co.uk
[...]


 Eh? By what definition exactly?



http://fly.cc.fer.hr/~unreal/theredbook/appendixg.html
http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/translate.html
http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/rotate.html

Rotation matrix order:
http://en.wikipedia.org/wiki/Rotation_matrix
Which is the order in the OpenGL man pages. If you create a simple rotation
matrix in OSG and compare it to there, you'll see that it's transposed
according to this definition.


 OpenGL is neither row-major or column-major.


http://en.wikipedia.org/wiki/Row-major_order
You can't store a well-defined multidimensional entity in one dimensional
storage and say it's neither. If you do, the definition of the
multidimensional entity becomes open to interpretation. Which actually is
not, as explained in the next paragraph.


 It treats a transformation matrix as 16 floats, nothing more. Only when one
 imposes a 4x4 structure of rows and columns on the 16 numbers does one then
 encounter the question Which way shall I order them?. At that point you
 choose row-major or column-major as the description of how your data is
 stored in the matrix.


Yes, and the definition of the matrix multiplication operator in OSG makes
it clear that the first index of the array is rows and second index is
columns. Also if you look at the code closely, the first index is always
referred to as rows. So, when you treat the indices as such, you see that
the matrix being stored is actually a transposed version of a transformation
matrix. Hence, you have to treat them as transposed transformation matrices
to get your math right.




  There is no such
  thing as
  row-major matrix since matrices are
  mathematical entities that have
  nothing to do with storage.

 Yes there is, I've just described it above. It's storage that has nothing
 to do with it i.e. OpenGL's view of it as 16 numbers, it's how you construct
 your mathematical entity, your matrix, that imposes one view or the other.


You don't construct the mathematical entity of transformation matrices based
on how OpenGL stores matrices. The mathematical definition in the literature
is clear, which is also used in the OpenGL man pages when talking about
transformation matrices.


I know it sucks, but it's just the way it is.

-Gazi
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] getting translate rotate scale right.

2009-01-15 Thread Mark Sciabica

Hi Gazi,

It is true that OSG differs from your literature. That does not make OSG 
incorrect. In fact, the literature wasn't always dominated by the format 
you're promoting.


This link http://steve.hollasch.net/cgindex/math/matrix/column-vec.html 
provides some history on the matter.


One format isn't correct, and the other incorrect. It's simply a 
convention, and one needs to be aware of the convention used in the 
context in which one is working. OSG assumes row vectors while OpenGL 
assumes column vectors, but OSG (like C++) uses row-major ordering while 
OpenGL uses column-major ordering. This combination makes OSG binary 
compatible with OpenGL but not notationally compatible. Perhaps binary 
compatibility and ease of coding was the reason for the convention 
chosen, or it could be other historical factors. We would have to get 
that answer from Robert. Whatever the reason, that's the convention OSG 
uses and it's in no way 'incorrect'.


Direct3D (and presumably any literature directed to it) uses the same 
row-vector convention as OSG so it's hard to convincingly paint OSG as 
some maverick API in this context.


Regards,
Mark


Gazi Alankus wrote:
A correct transformation matrix (which is a 2D entity) according to 
math literature:


R11 R12 R13 Tx
R21 R22 R23 Ty
R31 R32 R33 Tz
0 0 0 1

That matrix stored in column-major order in 1D memory:
R11 R21 R31 0 R12 R22 R32 0 R13 R23 R33 0 Tx Ty Tz 1

That matrix stored in row-major order in 1D memory:
R11 R12 R13 Tx R21 R22 R23 Ty R31 R32 R33 Tz 0 0 0 1

If these are the things you dispute, that is an easier argument to 
deal with. Otherwise my response follows: 



2009/1/15 Paul Fotheringham osg_u...@yahoo.co.uk 
mailto:osg_u...@yahoo.co.uk

[...]


Eh? By what definition exactly?



http://fly.cc.fer.hr/~unreal/theredbook/appendixg.html 
http://fly.cc.fer.hr/%7Eunreal/theredbook/appendixg.html

http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/translate.html
http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/rotate.html

Rotation matrix order:
http://en.wikipedia.org/wiki/Rotation_matrix
Which is the order in the OpenGL man pages. If you create a simple 
rotation matrix in OSG and compare it to there, you'll see that it's 
transposed according to this definition. 



OpenGL is neither row-major or column-major. 



http://en.wikipedia.org/wiki/Row-major_order
You can't store a well-defined multidimensional entity in one 
dimensional storage and say it's neither. If you do, the definition of 
the multidimensional entity becomes open to interpretation. Which 
actually is not, as explained in the next paragraph. 
 


It treats a transformation matrix as 16 floats, nothing more. Only
when one imposes a 4x4 structure of rows and columns on the 16
numbers does one then encounter the question Which way shall I
order them?. At that point you choose row-major or column-major
as the description of how your data is stored in the matrix.


Yes, and the definition of the matrix multiplication operator in OSG 
makes it clear that the first index of the array is rows and second 
index is columns. Also if you look at the code closely, the first 
index is always referred to as rows. So, when you treat the indices as 
such, you see that the matrix being stored is actually a transposed 
version of a transformation matrix. Hence, you have to treat them as 
transposed transformation matrices to get your math right. 

 



 There is no such
 thing as
 row-major matrix since matrices are
 mathematical entities that have
 nothing to do with storage.

Yes there is, I've just described it above. It's storage that has
nothing to do with it i.e. OpenGL's view of it as 16 numbers, it's
how you construct your mathematical entity, your matrix, that
imposes one view or the other.


You don't construct the mathematical entity of transformation matrices 
based on how OpenGL stores matrices. The mathematical definition in 
the literature is clear, which is also used in the OpenGL man pages 
when talking about transformation matrices. 



I know it sucks, but it's just the way it is.
 
-Gazi 





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
  


___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] getting translate rotate scale right.

2009-01-15 Thread Gazi Alankus
2009/1/15 Mark Sciabica msciab...@itracs.com

  Hi Gazi,

 It is true that OSG differs from your literature. That does not make OSG
 incorrect. In fact, the literature wasn't always dominated by the format
 you're promoting.


Hi Mark,

It's not just my literature, it's the dominant one that anyone starting to
learn about computer graphics today is exposed to. But you are right, it
seems the history had its debates.




 This link 
 http://steve.hollasch.net/cgindex/math/matrix/column-vec.htmlprovides some 
 history on the matter.


Great link to bookmark, thank you. It's interesting to see all the past
debate and origins of this.



 One format isn't correct, and the other incorrect. It's simply a
 convention, and one needs to be aware of the convention used in the context
 in which one is working. OSG assumes row vectors while OpenGL assumes column
 vectors, but OSG (like C++) uses row-major ordering while OpenGL uses
 column-major ordering. This combination makes OSG binary compatible with
 OpenGL but not notationally compatible. Perhaps binary compatibility and
 ease of coding was the reason for the convention chosen, or it could be
 other historical factors. We would have to get that answer from Robert.
 Whatever the reason, that's the convention OSG uses and it's in no way
 'incorrect'.


I know, I should deal with it:). It's incorrect according to the sources I
mentioned, calling it just incorrect would be unfair. The implementation
reason is ease of coding of the matrix class.
http://www.openscenegraph.org/projects/osg/wiki/Support/Maths/MatrixTransformations
cites
the way c arrays are stored as the reason for this choice and agrees that
the choice was not in compliance with most books and the OpenGL manual. They
just wanted to be able to push the two dimensional array directly to OpenGL.
However, not abstracting this out in the matrix class, in my opinion, was
unfortunate. One way is to store them the way OpenGL does but treat them
logically the way OpenGL manual treats them in the class functions, which
would be the right way if OpenGL is right (implementation and
documentation-wise). A simple the first index is the column and the second
index is the row rule does this. Or, avoiding a two dimensional array, thus
not giving any inherent meaning to indices, and treating the one dimensional
array as a matrix stored in column-major order in the functions of the
matrix class would be even less error-prone. OGRE does it by flipping
indices in its matrix multiplication code and warns the users about the
matrix notation:
http://www.ogre3d.org/docs/api/html/classOgre_1_1Matrix4.html#_details

I believe this issue has to be actively documented in the OSG API reference,
too. Just like it should be actively documented that operator precedence for
^ and + is not the way it is in maths for cross product and addition of
vectors.


 Direct3D (and presumably any literature directed to it) uses the same
 row-vector convention as OSG so it's hard to convincingly paint OSG as some
 maverick API in this context.


The whole point I'm trying to make is that *this is unexpected for a good
number of people and should be actively documented in the API so that people
don't suffer*. My intention was not to defame OSG in any way and I don't
think I did that. I pointed out the disparity and that this could be a
reason for a bug (reply to Chris), and that this is not a non-issue (replay
to Paul). I'm sorry if it sounded any other way.

All is for less bugs and less headache for everyone. I swear, I love OSG and
its community.

Regards,

-Gazi




 Regards,
 Mark


 Gazi Alankus wrote:

 A correct transformation matrix (which is a 2D entity) according to math
 literature:

  R11 R12 R13 Tx
 R21 R22 R23 Ty
 R31 R32 R33 Tz
 0 0 0 1

  That matrix stored in column-major order in 1D memory:
  R11 R21 R31 0 R12 R22 R32 0 R13 R23 R33 0 Tx Ty Tz 1

  That matrix stored in row-major order in 1D memory:
  R11 R12 R13 Tx R21 R22 R23 Ty R31 R32 R33 Tz 0 0 0 1

  If these are the things you dispute, that is an easier argument to deal
 with. Otherwise my response follows:


  2009/1/15 Paul Fotheringham osg_u...@yahoo.co.uk
  [...]


  Eh? By what definition exactly?



  
 http://fly.cc.fer.hr/~unreal/theredbook/appendixg.htmlhttp://fly.cc.fer.hr/%7Eunreal/theredbook/appendixg.html

 http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/translate.html

 http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/rotate.html

  Rotation matrix order:
 http://en.wikipedia.org/wiki/Rotation_matrix
  Which is the order in the OpenGL man pages. If you create a simple
 rotation matrix in OSG and compare it to there, you'll see that it's
 transposed according to this definition.


  OpenGL is neither row-major or column-major.


  http://en.wikipedia.org/wiki/Row-major_order
  You can't store a well-defined multidimensional entity in one dimensional
 storage and say it's neither. If you do, the definition of the