Page 1 of 1

btQuaternion operator*(btQuaternion Q, btVector3 V)

Posted: Fri Sep 02, 2016 6:49 pm
by drleviathan
I'm bummed that there is no easy way to rotate a btVector3 with a btQuaternion. I'd like to just do this:

Code: Select all

rotatedV = rotation * V;
Unfortunately there is no such implementation in Bullet's math libraries. Instead there is an operator override that returns a new btQuaternion. There is no documentation about what it does. So I've been wondering...

(1) Does anyone here know what that operator is supposed to do?
(2) Is it actually used anywhere?
(3) Is there any support here for a real multiplication override between a btQuaternion and a btVector?

Re: btQuaternion operator*(btQuaternion Q, btVector3 V)

Posted: Fri Sep 02, 2016 7:17 pm
by drleviathan
Heh... when I remove that operator the Bullet lib and demo codebase still builds. That mysterious method is not used by the any core functionality.

Edit: Nevermind, I spoke too soon. The one in b3Quaternion.h is used somewhere. I will have to learn more...

Re: btQuaternion operator*(btQuaternion Q, btVector3 V)

Posted: Sat Sep 03, 2016 11:01 am
by benelot
I think I had a similar issue once about rotating a btVector3 by a btQuaternion. In my simulator, I just found myself to perform this operation in Ogre::Vector and Ogre::Quaternion. It could be a good idea to add this functionality.

I will look into the override you speak of, I am interested.

Edit:

I went back to before the introduction of the cryptic SIMD notation.

That is what it was before:

Code: Select all

SIMD_FORCE_INLINE btQuaternion
operator*(const btQuaternion& q, const btVector3& w)
{
	return btQuaternion( q[3] * w.x() + q.y() * w.z() - q.z() * w.y(),
		q[3] * w.y() + q.z() * w.x() - q.x() * w.z(),
		q[3] * w.z() + q.x() * w.y() - q.y() * w.x(),
		-q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); 
}

SIMD_FORCE_INLINE btQuaternion
operator*(const btVector3& w, const btQuaternion& q)
{
	return btQuaternion( w.x() * q[3] + w.y() * q.z() - w.z() * q.y(),
		w.y() * q[3] + w.z() * q.x() - w.x() * q.z(),
		w.z() * q[3] + w.x() * q.y() - w.y() * q.x(),
		-w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); 
}
from [https://github.com/bulletphysics/bullet ... ion.h#L236]

Maybe we can find out what it does. To me, it looks like some kind of 4D crossproduct, but that is not defined in such a way to my understanding.

Edit2:

Ok it is just a quaternion multiplication with w[3] = 0. Compare this (I marked the elements in the quaternion multiplication which are 0 within the lower quaternion-vector example because the vector does not have a fourth value):

SIMD_FORCE_INLINE btQuaternion
operator*(const btQuaternion& q1, const btQuaternion& q2) {
return btQuaternion( q1[3] * q2.x() + q1.x() * q2[3] + q1.y() * q2.z() - q1.z() * q2.y(),
q1[3] * q2.y() + q1.y() * q2[3] + q1.z() * q2.x() - q1.x() * q2.z(),
q1[3] * q2.z() + q1.z() * q2[3] + q1.x() * q2.y() - q1.y() * q2.x(),
q1[3] * q2[3] - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z());
}

SIMD_FORCE_INLINE btQuaternion
operator*(const btQuaternion& q1, const btVector3& w)
{
return btQuaternion( q1[3] * w.x() + q1.y() * w.z() - q1.z() * w.y(),
q1[3] * w.y() + q1.z() * w.x() - q1.x() * w.z(),
q1[3] * w.z() + q1.x() * w.y() - q1.y() * w.x(),
-q1.x() * w.x() - q1.y() * w.y() - q1.z() * w.z());
}

However, I am not sure what the interpretation of this is.

Re: btQuaternion operator*(btQuaternion Q, btVector3 V)

Posted: Sun Sep 04, 2016 10:15 am
by anthrax11
This page explains why multiplication is not enough to rotate a vector by a quaternion. The rotation you need (q*v*q^-1) is defined in the quatRotate function in btQuaternion.h. It should really be btQuaternion::rotate(btVector3 v), but Erwin will probably be opposed to cleaning up the codebase because of backwards compatibility and pending patches.

And yes, the multiplication v*q is defined as (v_xyz, 0)*q. It has something to do with multiplying complex numbers, but I don't know the details.

Re: btQuaternion operator*(btQuaternion Q, btVector3 V)

Posted: Mon Sep 05, 2016 9:17 pm
by benelot
Oh ok, I thought that this functionality must be hidden somewhere. Instead of renaming it, how about we define an operator that essentially performs this operation? Or is it too misleading? Probably yes, especially because the operator v * q would then internally calculate q * v * q^-1 and additionally because q * v (complex number thingy) would be a different operation from v * q (rotation thingy) (Not in terms of how the operator is applied, but what operation is performed).