Page 1 of 1
btTransform * operator giving the inverse ??
Posted: Fri Oct 02, 2009 1:47 pm
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
Re: btTransform * operator giving the inverse ??
Posted: Fri Oct 02, 2009 3:09 pm
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.
Re: btTransform * operator giving the inverse ??
Posted: Fri Oct 02, 2009 3:55 pm
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
Re: btTransform * operator giving the inverse ??
Posted: Fri Oct 02, 2009 8:42 pm
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.
Re: btTransform * operator giving the inverse ??
Posted: Sat Oct 03, 2009 3:33 am
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
Re: btTransform * operator giving the inverse ??
Posted: Sat Oct 03, 2009 8:13 am
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
Re: btTransform * operator giving the inverse ??
Posted: Sat Oct 03, 2009 8:39 am
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
Re: btTransform * operator giving the inverse ??
Posted: Mon Oct 27, 2014 5:33 pm
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