Quaternions?

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
powerpop
Posts: 171
Joined: Thu Jan 08, 2004 1:39 am
Location: san francisco

Quaternions?

Post by powerpop »

so what does it mean that the engine "now supports Quaternions" - are you using these internally for the engine rather than the matrix math? - or does it mean you just provide a conversion API to quaternions from the internal representation?

just curious

and awesome job on this release - good stuff in there!!!
[dx/x]=HUNT3R
Posts: 271
Joined: Sat Aug 23, 2003 5:52 pm
Location: Hurricane Central, Florida

Post by [dx/x]=HUNT3R »

Straight outta the API...

irr::core::quaternion Class Reference
Quaternion class. More...
#include <quaternion.h>

List of all members.


Public Methods
quaternion ()
quaternion (f32 X, f32 Y, f32 Z, f32 W)
quaternion (f32 x, f32 y, f32 z)
quaternion (const matrix4 &mat)
bool operator== (const quaternion &other) const
quaternion & operator= (const quaternion &other)
quaternion & operator= (const matrix4 &other)
quaternion operator+ (const quaternion &other) const
quaternion operator * (const quaternion &other) const
quaternion operator * (f32 s) const
quaternion & operator *= (const quaternion &other)
f32 getDotProduct (const quaternion &other) const
void set (f32 x, f32 y, f32 z, f32 w)
void set (f32 x, f32 y, f32 z)
quaternion & normalize ()
matrix4 getMatrix () const
void makeInverse ()
quaternion Slerp (quaternion q1, quaternion q2, f32 time)


Public Attributes
f32 X
f32 Y
f32 Z
f32 W



--------------------------------------------------------------------------------

Detailed Description
Quaternion class.


--------------------------------------------------------------------------------

Constructor & Destructor Documentation
irr::core::quaternion::quaternion ( ) [inline]

Default Constructor.




irr::core::quaternion::quaternion ( f32 X,
f32 Y,
f32 Z,
f32 W
) [inline]

Constructor.




irr::core::quaternion::quaternion ( f32 x,
f32 y,
f32 z
) [inline]

Constructor which converts euler angles to a quaternion.




irr::core::quaternion::quaternion ( const matrix4 & mat ) [inline]

Constructor which converts a matrix to a quaternion.





--------------------------------------------------------------------------------

Member Function Documentation
f32 irr::core::quaternion::getDotProduct ( const quaternion & other ) const [inline]

calculates the dot product




matrix4 irr::core::quaternion::getMatrix ( ) [inline]

Creates a matrix from this quaternion.




void irr::core::quaternion::makeInverse ( ) [inline]

Inverts this quaternion.




quaternion & irr::core::quaternion::normalize ( ) [inline]

normalizes the quaternion




quaternion irr::core::quaternion::operator * ( f32 s ) const [inline]

multiplication operator




quaternion irr::core::quaternion::operator * ( const quaternion & other ) const [inline]

multiplication operator




quaternion & irr::core::quaternion::operator *= ( const quaternion & other ) [inline]

multiplication operator




quaternion irr::core::quaternion::operator+ ( const quaternion & other ) const [inline]

add operator




quaternion & irr::core::quaternion::operator= ( const matrix4 & other ) [inline]

matrix assignment operator




quaternion & irr::core::quaternion::operator= ( const quaternion & other ) [inline]

assignment operator




bool irr::core::quaternion::operator== ( const quaternion & other ) const [inline]

equal operator




void irr::core::quaternion::set ( f32 x,
f32 y,
f32 z
) [inline]

sets new quaternion based on euler angles




void irr::core::quaternion::set ( f32 x,
f32 y,
f32 z,
f32 w
) [inline]

sets new quaternion




quaternion irr::core::quaternion::Slerp ( quaternion q1,
quaternion q2,
f32 time
) [inline]






--------------------------------------------------------------------------------

Member Data Documentation
f32 irr::core::quaternion::W





f32 irr::core::quaternion::X





f32 irr::core::quaternion::Y





f32 irr::core::quaternion::Z






--------------------------------------------------------------------------------
The documentation for this class was generated from the following file:
quaternion.h
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

yes, but where in the engine does he actually USE quaternions?

I assume he is storing rotational information in matrix format, and merely quaternion-izing it when he adds new rotation information to the matrix (IE: matrx->quaterion. new rot->quaterion. quatXquat. quat->back to matrix)
a screen cap is worth 0x100000 DWORDS
niko
Site Admin
Posts: 1759
Joined: Fri Aug 22, 2003 4:44 am
Location: Vienna, Austria
Contact:

Post by niko »

keless wrote:yes, but where in the engine does he actually USE quaternions?
Currently just at one location: The animation of .x files. And this is even a little bit buggy. (for more informations read the comments in CXAnimationPlayer.cpp ;) ) But I think in future versions quaternions may become more important.
level1

Post by level1 »

niko wrote:
keless wrote:yes, but where in the engine does he actually USE quaternions?
Currently just at one location: The animation of .x files. And this is even a little bit buggy. (for more informations read the comments in CXAnimationPlayer.cpp ;) ) But I think in future versions quaternions may become more important.
read my post in the Beginner/or Advanced?? '5.0 Bug' thread. The quaternion multiplicaton was not correct! maybe this solves the x animation stuff too?

cheers
level1
buhatkj
Posts: 444
Joined: Fri Dec 12, 2003 4:53 am
Contact:

not really, it's still messed up somehow...

Post by buhatkj »

i tried changing this and recompiling the engine, but it's still not right, i dunno if that's it, or if that's ONLY it....
didnt make any discernable difference in my app, though you would think it would either work or break ti worse yknow, you would think i'd see SOMETHING cuz the function is totally different now....
-ted
My irrlicht-based projects have gone underground for now, but if you want, check out my webcomic instead! http://brokenboomerang.net
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

dont have time to evaluate IrrLicht Engine's code, but here is my working Quaternion class from GTEngine:

http://www.skyesurfer.net/keless/download/Quaternion.h
http://www.skyesurfer.net/keless/downlo ... ernion.cpp
a screen cap is worth 0x100000 DWORDS
buhatkj
Posts: 444
Joined: Fri Dec 12, 2003 4:53 am
Contact:

given that...

Post by buhatkj »

given the assumption that keless's quaternions are correct(which i trust), so are niko's. the multiplication functions match _exactly_.
its just that where keless's class says q[0] niko says w, etc...
here's the mapping(based on how they are used in the matrix constructors):
q[0] = w
q[1] = x
q[2] = y
q[3] = z

so it's most likely not that part....
must be something else.
-Ted
My irrlicht-based projects have gone underground for now, but if you want, check out my webcomic instead! http://brokenboomerang.net
level1

Re: buhatkj

Post by level1 »

well, trust noone!

i have my quaternion information from
http://www.euclideanspace.com/maths/alg ... /index.htm
and there the signs look somewhat different :? the question is now where do the signs from Niko and Keless come from? And even more interesting is why do the two implementations give the same result?

I'm completely confuseld!

btw. ogre3d uses the multiplication version from David Eberly (Magic Software Inc). He comes to the same mult. signs as mentioned in the url above. and if I multiply two quaternions by hand then i come to the same result too.

can someone explaine this please? This would really interest me

level1
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

hrm. much of my class came from the tutorials on GameTutorials.com, as well as an online math FAQ (which may be linked to in the source).

Perhaps Niko went thru the same channels?

My class specifically works for Q3 'curved' surfaces, and has no problems with that-- though it should work for other SLERP stuff, like animation.. :(
a screen cap is worth 0x100000 DWORDS
niko
Site Admin
Posts: 1759
Joined: Fri Aug 22, 2003 4:44 am
Location: Vienna, Austria
Contact:

Post by niko »

keless wrote:Perhaps Niko went thru the same channels?
That's right, I took a look at some places on the web and looked how they did it. I am not very experienced with quaternions, so I thought it would be a good idea to check if the results of my class are the same of some other, existing ones. :) However, the quaternions have some different results with that of D3D, so I think this is the problem. In D3D, they seem to be mirrored, but I'll find that out, too. :)
level1

Post by level1 »

every source i found on the web has the same implementation as euclideanspace.com. :o Could you provide an url to the tutorials where that different implementation is explained?

i haven't managed to come to the results in your implementation even with conversion from left handed to right handed systems and back i get at least one PLUS sign in the terms for X,Y and Z components. and i checked the implementation of ogre3d and ODE, look all different than yours :?
also, check "Game Programming Gems 1" 2.7. and http://www.cs.berkeley.edu/~laura/cs184 ... rnion.html

i think it's dangerous to implement mathematical classes with behaviour special to some libraries' need. personally i'd provide a conversion method if needed. otherwise you'll have to think way too much when dealing with standard mathematical problems.

cheers :)
level1
buhatkj
Posts: 444
Joined: Fri Dec 12, 2003 4:53 am
Contact:

welp i never heard of quaternions in any calc class...

Post by buhatkj »

never learned em in school, otherwise i'd look it up in my old textbook. but all i can tell you guys is that niko's quaternion class appears to be identical in it implementation of all function common to keles's. so if one or the other is wrong, they are both wrong in the same way. i have been wondering if perhaps it has more to do with a loss of precision someplace, or perhaps how that transformation data is being applied...
-ted
My irrlicht-based projects have gone underground for now, but if you want, check out my webcomic instead! http://brokenboomerang.net
niko
Site Admin
Posts: 1759
Joined: Fri Aug 22, 2003 4:44 am
Location: Vienna, Austria
Contact:

Post by niko »

Yesterday I played a little bit with it (also using some math books ;) ), and I came to the following result. Most .x animations are now correct with this. But there seems to be still another bug which has not to do nothing with quaternions.
First, I transposed the coordinates of the elements created in quaterions::getMatrix():

Code: Select all

inline matrix4 quaternion::getMatrix() const
{
	core::matrix4 m;

	m(0,0) = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z; 
	m(0,1) = 2.0f*X*Y + 2.0f*Z*W; 
	m(0,2) = 2.0f*X*Z - 2.0f*Y*W; 
	m(0,3) = 0.0f;

	m(1,0) = 2.0f*X*Y - 2.0f*Z*W; 
	m(1,1) = 1.0f - 2.0f*X*X - 2.0f*Z*Z; 
	m(1,2) = 2.0f*Z*Y + 2.0f*X*W; 
	m(1,3) = 0.0f;

	m(2,0) = 2.0f*X*Z + 2.0f*Y*W; 
	m(2,1) = 2.0f*Z*Y - 2.0f*X*W; 
	m(2,2) = 1.0f - 2.0f*X*X - 2.0f*Y*Y; 
	m(2,3) = 0.0f;

	m(3,0) = 0.0f; 
	m(3,1) = 0.0f; 
	m(3,2) = 0.0f; 
	m(3,3) = 1.0f;

	return m;
}
Then, I slightly changed the slerp-method:

Code: Select all

inline quaternion quaternion::Slerp(quaternion q1, quaternion q2, f32 time)
{
    f32 angle = q1.getDotProduct(q2);

    if (angle < 0.0f) 
    {
	q1 *= -1.0f;
        angle *= -1.0f;
    }

	f32 scale;
    f32 invscale;

    if ((angle + 1.0f) > 0.05f) 
    {
		if ((1.0f - angle) < 0.05f)  // linear interploation
		{
			scale = 1.0f - time;
			invscale = time;
		}
		else // spherical interpolation
		{ 
			f32 theta = (f32)acos(angle);
			f32 invsintheta = 1.0f / (f32)sin(theta);
			scale = (f32)sin(theta * (1.0f-time)) * invsintheta;
			invscale = (f32)sin(theta * time) * invsintheta;
		}
    }
    else 
    {
        q2 = quaternion(-q1.Y, q1.X, -q1.W, q1.Z);
        scale = (f32)sin(PI * (0.5f - time));
        invscale = (f32)sin(PI * time);
    }

	*this = (q1*scale) + (q2*invscale);
	return *this;
}
buhatkj
Posts: 444
Joined: Fri Dec 12, 2003 4:53 am
Contact:

welp it's different...dunno if it's better..

Post by buhatkj »

well its definitely not the same as the old one. it seem better for the first few frames, but then it seems to skew off again. good progress though :-)
-Ted
My irrlicht-based projects have gone underground for now, but if you want, check out my webcomic instead! http://brokenboomerang.net
Post Reply