btQuaternion operator*(btQuaternion Q, btVector3 V)

Post Reply
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

btQuaternion operator*(btQuaternion Q, btVector3 V)

Post 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?
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

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

Post 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...
benelot
Posts: 350
Joined: Sat Jul 04, 2015 10:33 am
Location: Bern, Switzerland
Contact:

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

Post 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.
anthrax11
Posts: 72
Joined: Wed Feb 24, 2010 9:49 pm

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

Post 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.
benelot
Posts: 350
Joined: Sat Jul 04, 2015 10:33 am
Location: Bern, Switzerland
Contact:

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

Post 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).
Post Reply