btTransform * operator giving the inverse ??

Post Reply
loefje
Posts: 18
Joined: Thu May 28, 2009 10:43 am

btTransform * operator giving the inverse ??

Post by loefje »

Hi,

Am I totally confused or do the () and * operators
of btTransform and btMatrix3x3 give the inverse transform ?

/**@brief Return the transform of the vector */
SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const
{
return btVector3(m_basis[0].dot(x) + m_origin.x(),
m_basis[1].dot(x) + m_origin.y(),
m_basis[2].dot(x) + m_origin.z());
}

what i'd expect is this:

return btVector3( m_basis[0] * x[0] + m_origin.x(),
m_basis[1] * x[1] + m_origin.y(),
m_basis[2] * x[2] + m_origin.z() );

what am I missing ?

thanks,

Jochem van der Spek
(void*)
Posts: 6
Joined: Tue Sep 15, 2009 2:32 pm

Re: btTransform * operator giving the inverse ??

Post by (void*) »

This is just how bullet stores their matrices I suspect (columns versus rows).

I know that when I convert from a bullet matrix to my own math library's matrix I have to transpose them.
loefje
Posts: 18
Joined: Thu May 28, 2009 10:43 am

Re: btTransform * operator giving the inverse ??

Post by loefje »

so what you're saying is that
m_basis[0] gives me the first column, right ?
I never really get my head around that.
in an OpenGL matrix, it's like this, (column-major)

xx, yx, zx, tx
xy, yy, zy, ty
xz, yz, zz, tz
xw, yw, zw, tw

so m_basis[0] should correspond to Vector3( xx, xy, xz )
giving me the x-axis of the coordinateframe,
the same as in OpenGL, but then the * and () operators
apparently give the inverse.

so, from this, i deduce that bullet stores row-major instead, and
that m_basis[0] gives Vector3( xx, yx, zx ) instead, am I correct ?

J
(void*)
Posts: 6
Joined: Tue Sep 15, 2009 2:32 pm

Re: btTransform * operator giving the inverse ??

Post by (void*) »

I'm not sure how much help I will be for you. I haven't spent a lot of time working through the details of bullet's math library and I don't use it directly (I have my own math library). I just know what I had to do in order for my code to interface with it.

Something else that comes to mind is that you may be dealing with a math operation order issue...

(Matrix * vector) versus (vector * Matrix)

In your first post you said you expected to see
return btVector3( m_basis[0] * x[0] + m_origin.x(),
m_basis[1] * x[1] + m_origin.y(),
m_basis[2] * x[2] + m_origin.z() );
Which is actually (vector * Matrix) according to bullet's math code.

Ref: btMatrix3x3.h

Code: Select all

	SIMD_FORCE_INLINE btVector3 
	operator*(const btMatrix3x3& m, const btVector3& v) 
	{
		return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v));
	}
	

	SIMD_FORCE_INLINE btVector3
	operator*(const btVector3& v, const btMatrix3x3& m)
	{
		return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v));
	}
Ref: btTransform.h

Code: Select all

	SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const
	{
		return btVector3(m_basis[0].dot(x) + m_origin.x(), 
			m_basis[1].dot(x) + m_origin.y(), 
			m_basis[2].dot(x) + m_origin.z());
	}

  /**@brief Return the transform of the vector */
	SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const
	{
		return (*this)(x);
	}
Sorry I can't be much more help than that. You originally "asked" if those operators returned the inverse... I believe the answer is "no" they do not return the inverse. However the conventions bullet uses may just be different than what you're used to working with.
loefje
Posts: 18
Joined: Thu May 28, 2009 10:43 am

Re: btTransform * operator giving the inverse ??

Post by loefje »

Hi,

Thanks for your answer. What I can't find is the code in bullet for btVector3 * btTransform then.

I actually get a compiler error on doing vector * matrix:

Code: Select all

	
btTransform trans = m_connA->getRenderNode()->getLocal();
btVector3 vec = m_connA->getConnectionPoint().getOrigin();
glVertex3fv( vec * trans );

gives:

..\..\src\Piston.cpp(407) : error C2679: binary '*' : no operator found which takes a right-hand operand of type 'btTransform' (or there is no acceptable conversion)

did u spot it somewhere ?

J
loefje
Posts: 18
Joined: Thu May 28, 2009 10:43 am

Re: btTransform * operator giving the inverse ??

Post by loefje »

just a followup on my previous post, I'm getting more & more confused here.
if btMatrix3x3 stores the orthogonal vectors of a reference frame in row-major
order, like this:

Code: Select all

m_el[0] = btVector3( xx, xy, xz );
m_el[1] = btVector3( yx, yy, yz );
m_el[2] = btVector3( zx, zy, zz );
then why on EARTH stores it the x,y and z-components
of each vector as a column in an OpenGL matrix, which is column-major ??

Code: Select all

// from btMatrix3x3.h
		void getOpenGLSubMatrix(btScalar *m) const 
		{
			m[0]  = btScalar(m_el[0].x()); 
			m[1]  = btScalar(m_el[1].x());
			m[2]  = btScalar(m_el[2].x());
			m[3]  = btScalar(0.0); 
			m[4]  = btScalar(m_el[0].y());
			m[5]  = btScalar(m_el[1].y());
			m[6]  = btScalar(m_el[2].y());
			m[7]  = btScalar(0.0); 
			m[8]  = btScalar(m_el[0].z()); 
			m[9]  = btScalar(m_el[1].z());
			m[10] = btScalar(m_el[2].z());
			m[11] = btScalar(0.0); 
		}
Am I being silly or is this weird ?
If anyone can enlighten me on this,
please, 'cause I'm just not getting it..

TIA,

J
loefje
Posts: 18
Joined: Thu May 28, 2009 10:43 am

Re: btTransform * operator giving the inverse ??

Post by loefje »

hi,

I should have seen before that there's another thread on this topic,
http://continuousphysics.com/Bullet/php ... 1b1a7d0566
and it seems to me beaelp is right in stating that the
getOpenGLSubMatrix gives the transpose of what's expected by glLoadMatrix.

Erwin, could you *please* clarify this ?

thanks a lot,

Jochem van der Spek
mewert
Posts: 52
Joined: Sat Oct 08, 2005 1:16 am
Location: Itinerant

Re: btTransform * operator giving the inverse ??

Post by mewert »

Bullet's transforms are stored row-major in memory. They are still column vectors with post multiply, though. i.e. T*v_body = v_world, where T is the rigid body transform. They use the same math conventions as OpenGL and... well, _math_ ( not Directx ). But the storage is different from OpenGL, where column vectors are stored column major.

I suspect this for the optimization that allows btMatrix3x3*btVector3 to be performed with 3 dot products.. SoA vs. AoS.

- Michael Alexander Ewert
Post Reply