### Re: [osg-users] Quat * Vec3 proposals - request for comments/help

```
--- On Tue, 21/4/09, J.P. Delport jpdelp...@csir.co.za wrote:

From: J.P. Delport jpdelp...@csir.co.za
Subject: [osg-users] Quat * Vec3 proposals - request for comments/help
To: osg users osg-users@lists.openscenegraph.org
Date: Tuesday, 21 April, 2009, 1:36 PM
Hi all,

it's been known for a while  that there are
inconsistencies with the way OSG handles Quat * Vec3. In
short: Quat * Vec3 is written in code as a post-multiply,
but the result of the operation is as if a pre-multiply was
performed. The attached test app also shows the problem
(more on it later).


and

What doesn't work?
There are many examples that can be constructed of where a
mathematical expression usings quats and vectors would not
I could come up with is this:

((q1 * q2) * v) != (q1 * (q2 * v))

Why are there not more complaints?

Well I curse this all the time, but not for the same reason. For me it's q1 *
q2 that's annoying as I see it as the opposite of what I expect from the
mathematics of applying a quaternion to a vector but then therein lies the
problem.

Using operator* for matrix multiplications is fine as that mirrors precisely
what you are doing with the matrices mathematically. Using operator* for
quaternion multiplication is a loose analogy since you are actually doing
q*v*q' mathematically when applying q to v. If you have two rotations, q1
followed by q2 then you would get q2*q1*v*q1'*q2' mathematically and so I
expect the interpretation of operator* to allow me to write q2*q1*v in code.

Of course that's just my interpretation and what I'm effectively saying within
that interpretation is that it's quat * quat that is wrong but there's no way
in the world you can swap that now! :)

Alternatively you could drop osg::Vec3::operator*( osg::Quat ) altogether and
have osg::Vec3::apply( osg::Quat ) or osg::Vec3::rotate( osg::Quat ). I've used
math libraries that do it this way (and where vec::operator*( quat ) is just
that i.e. the mathematical multiplication rather than the full blown rotation.

I guess it depends on whether you value the brevity of operator* over the
underlying mathematics. If operator* is still going to be used for applying a
quaternion to a vector then I support the idea of making the multiplication
orders consistent between quat/quat and vec/quat as per your proposal.

Making it consistent with OSG's row-major matrix multiplication is probably
easier for coders who are not concerned with the details of the maths (and as I
noted above it's not a workable solution to swap it now anyway).

Whatever happens I second the comment of Tanguy Fautre who asked for it to be
documented clearly somewhere. :)

Anyway I hope you don't mind me chipping in. It certainly is interesting that
there hasn't been more discussion. Maybe people just do what works and leave
it. ;)

Paul Fotheringham.

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

```

### Re: [osg-users] Quat * Vec3 proposals - request for comments/help

```
Alternatively you could drop osg::Vec3::operator*(
osg::Quat ) altogether and have osg::Vec3::apply( osg::Quat
) or osg::Vec3::rotate( osg::Quat ).

Woops. Of course I meant that it was osg::Quat::operator*( osg ::Vec3 ) that
could be dropped. Sorry.

Paul Fotheringham.

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

```

### [osg-users] Quat * Vec3 proposals - request for comments/help

```
Hi all,

it's been known for a while  that there are inconsistencies with the
way OSG handles Quat * Vec3. In short: Quat * Vec3 is written in code as
a post-multiply, but the result of the operation is as if a pre-multiply
was performed. The attached test app also shows the problem (more on it
later).


and

What doesn't work?
There are many examples that can be constructed of where a mathematical
expression usings quats and vectors would not provide the expected
results. See also . The easiest one I could come up with is this:

((q1 * q2) * v) != (q1 * (q2 * v))

Why are there not more complaints?
I suppose most people do all the quat multiplications before they
multiply with the vector. Since OSG does not have a pre-multiply for
quat, the only option is then to post-multiply the resulting quat with
the vector.

What can be done?
As a first step I think we can add the pre-multiply to OSG. The attached
header does this. (To fix the post-multiply can be done later.)

What will break?
I think and hope nothing, since there was no pre-multiply that people
could have used. (Fixing the post-multiply would break current code.)

Why now?
The itch finally got annoying enough.

I think we should in some way let developers know that the post-multiply
they currently use will change in future and that they should switch
their multiply to the pre-version (which will behave the same as current
code). I think a compiler warning or error would help more than only
documentation. Something like a deprecated warning. I need help with
this though, I do not know how to generate a warning in a cross-platform
manner. Later we can then fix the post-multiply quat code.

Test app details:
The test app considers two rotations and a vector. It shows that for
Matrix and Vec3 interactions everything is consistent, e.g.

((m1 * m2) * v) == (m1 * (m2 * v))
and
(v * (m1 * m2)) == ((v * m1) * m2)

It then shows that Quat post-multiply does not behave as Matrix
post-multiply does and actually behaves more like Matrix pre-multiply
does. It also shows the inconsistency of various expressions.

We also know (from the osgunittest example) that
m1(q1) * m2(q2) == q1 * q2
so the internal quat * quat is consistent with the matrix multiply
order. It is only the quat * vec that is not.

Finally it shows that with the added pre-multiply (enable by making the
#if 0 a 1), the quat pre-mult behaves the same as the matrix pre-mult.

regards
jp

--
This message is subject to the CSIR's copyright terms and conditions, e-mail legal notice, and implemented Open Document Format (ODF) standard.
The full disclaimer details can be found at http://www.csir.co.za/disclaimer.html.

This message has been scanned for viruses and dangerous content by MailScanner,
and is believed to be clean.  MailScanner thanks Transtec Computers for their support.

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* OpenSceneGraph Public License for more details.
*/

#ifndef OSG_QUAT
#define OSG_QUAT 1

#include osg/Export
#include osg/Vec3f
#include osg/Vec4f
#include osg/Vec3d
#include osg/Vec4d

namespace osg {

class Matrixf;
class Matrixd;

/** A quaternion class. It can be used to represent an orientation in 3D
space.*/
class OSG_EXPORT Quat
{

public:

typedef double value_type;

value_type  _v;// a four-vector

inline Quat() { _v=0.0; _v=0.0; _v=0.0; _v=1.0; }

inline Quat( value_type x, value_type y, value_type z, value_type w )
{
_v=x;
_v=y;
_v=z;
_v=w;
}

inline Quat( const Vec4f v )
{
_v=v.x();
_v=v.y();
_v=v.z();
_v=v.w();
}

inline Quat( const Vec4d v )
{
_v=v.x();
_v=v.y();
_v=v.z();
_v=v.w();
}

inline Quat( value_type angle, const Vec3f axis)
{
makeRotate(angle,axis);
}
inline Quat( value_type angle, const Vec3d axis)
{
makeRotate(angle,axis);
}

inline Quat( value_type angle1, const Vec3f axis1,
value_type angle2, ```