Problem changing the rotation of a kinematic body

Post Reply
Proctoid
Posts: 18
Joined: Fri Apr 21, 2006 3:04 pm
Location: uk

Problem changing the rotation of a kinematic body

Post by Proctoid »

I can change the position of a kinematic body with no problem by reading the current transformation matrix and updating the position and then setting the new transformation.
If i change the rotation by a largish step then that is ok too.
But, if i do a rotation change that is very small any dynamic rigid bodies that touch the kinematic instantly goto infinity - any suggestions or a code snippet would be really appreciated.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Problem changing the rotation of a kinematic body

Post by Erwin Coumans »

Proctoid wrote:I can change the position of a kinematic body with no problem by reading the current transformation matrix and updating the position and then setting the new transformation.
If i change the rotation by a largish step then that is ok too.
But, if i do a rotation change that is very small any dynamic rigid bodies that touch the kinematic instantly goto infinity - any suggestions or a code snippet would be really appreciated.
This is a bug, probably in the btTransformUtil class. Can you reproduce it in a Bullet demo and attach it to the forum?

Thanks for the feedback,
Erwin
Proctoid
Posts: 18
Joined: Fri Apr 21, 2006 3:04 pm
Location: uk

Re: Problem changing the rotation of a kinematic body

Post by Proctoid »

Thanks i shall modify one of the demos to replicate the problem - currently ive downloaded the new 2.57 but my vc6 is complaining of new and delete being missing a few hundred times during link stage (LNK2001) so i need to sort that first.

for now this is a description of how it was going wrong in v 254 but line numbers probably no use now for v256 v257...



i use a btDiscreteDynamicsWorld with btCollisionDispatcher,
btAxisSweep3 & btSequentialImpulseConstraintSolver - same as
ccd physics demo.

i create a sphere to use as my floor (each triangles vertices
order is reversed so that my play area will be within the shpere)

i create a btBvhTriangleMeshShape mesh shape for the collision,
flag the body as kinematic etc and put it at 0,0,0 in the
dynamics world.

i drop a few object primitives into my sphere world
- box shape cone cylinder etc and they all collide off each other
and off the sphere sides etc and come to rest as expected -
so far so good...

i begin to x/y/z rotate the sphere around its origin with 6 keyboard inputs
and everything is as expected (although at large rotational speeds
the cone primitives do tend to penetrate the sphere shell and fly away
(but i trap that occurance anyway at stick them back at 0,0,0 for now))

this example code is used to set the position (always 0,0,0)
& new orientation of the kinematic sphere
(i have lots of checks to ensure angles are within valid ranges and normalize the quaternion before doing the setWorldTransform() and
all visually appears to function ok)

void IPhysics::setKinematicPhysicsPositionAndOrientation( const D3DXVECTOR3* pvPos, const D3DXQUATERNION* pqOrientation )
{
btVector3 pos( pvPos->x, pvPos->y, pvPos->z );
btQuaternion rot( pqOrientation->x, pqOrientation->y, pqOrientation->z, pqOrientation->w );
btTransform newTransform( rot, pos );
m_pRigidBody->getMotionState()->setWorldTransform( newTransform );
}

i leave the keys alone and the rotational forces are reduced
each game loop so that eventually the sphere will come to a stop

here comes the problem... just when the globe slows to rotating so
very slowy you can hardly see it moving the error occurs
(only happens some of the time - 75% say)
i can begin spinning the sphere again and drop new primitives in it and
they are ok again until the sphere comes to a rest again where it may
again go wrong.

anyway, when it goes wrong,
in release mode, the objects within the sphere get sent to infinity
and in debug mode the assert(s != btScalar(0.0)) line 134
in btQuaternion& operator/=(const btScalar& s)
occurs during processing the primitives in the sphere.
the motion state of the primitive was already at -NaN so the error
actually occurred before this.

i added a similiar assert to the btQuaternion& normalize()
and re-ran the app... it asserted here but still motionstate was already bad

i then added the: int _matherr( struct _exception *except )
and got the following from vc6:

_matherr(_exception * 0x0012f518) line 587
MSVCRTD! _matherr + 22 bytes
MSVCRTD! _87except + 318 bytes
MSVCRTD! _startOneArgErrorHandling + 41 bytes
MSVCRTD! acos + 181 bytes
btAcos(float 1.00000) line 113 + 18 bytes
btQuaternion::getAngle() line 166 + 12 bytes
btTransformUtil::calculateDiffAxisAngle(const btTransform & {...}, const btTransform & {...}, btVector3 & {...}, float & -1.07374e+008) line 124 + 8 bytes
btTransformUtil::calculateVelocity(const btTransform & {...}, const btTransform & {...}, float 0.0166667, btVector3 & {...}, btVector3 & {...}) line 106 + 21 bytes
btRigidBody::saveKinematicState(float 0.0166667) line 157 + 42 bytes
btDiscreteDynamicsWorld::saveKinematicState(float 0.0166667) line 102
btDiscreteDynamicsWorld::stepSimulation(float 0.0310000, int 1, float 0.0166667) line 233
CPhysicsWrapper::stepSimulation() line 594 + 30 bytes
CMyApp::Process3dObjects() line 600
CMyApp::ProcessNormal() line 553
CAppBase::Process() line 1240 + 11 bytes
GameLoop(unsigned long 1) line 169 + 19 bytes
DoProcessing() line 921 + 9 bytes
MessageLoop() line 552
CWindowsApplication::WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00141f2f, int 1) line 547 + 5 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00141f2f, int 1) line 398 + 26 bytes
WinMainCRTStartup() line 330 + 54 bytes
KERNEL32! 7c816fd7()

this occurs on my kinematic sphere collision shape 0 and is before the asserts for my primitive collision shapes 1 onwards occurs
as you can see it is trying to do acos of the m_unusedw variable 1.0
which returns -NaN which from then on all primitives in the sphere go to infinity
i did a print screen of the dmat and dorn it created (see below) but not of the two transforms - i did look at the transforms and they both looked ok)

static void calculateDiffAxisAngle(const btTransform& transform0,const btTransform& transform1,btVector3& axis,btScalar& angle)
{
btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse();

dmat
m_el
[0]
btQuadWord
m_x = 1.00000
m_y = 2.99513e-005
m_z = -8.06451e-005
m_unusedw = 0.000000
[1]
btQuadWord
m_x = -2.99513e-005
m_y = 1.00000
m_z = 7.74562e-005
m_unusedw = 0.000000
[2]
btQuadWord
m_x = 8.06749e-005
m_y = -7.74860e-005
m_z = 1.00000
m_unusedw = 0.000000

dorn
btQuadWord
m_x = -3.87356e-005
m_y = -4.03300e-005
m_z = -1.49757e-005
m_unusedw = 1.000000
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Problem changing the rotation of a kinematic body

Post by Erwin Coumans »

Proctoid wrote:Thanks i shall modify one of the demos to replicate the problem - currently ive downloaded the new 2.57 but my vc6 is complaining of new and delete being missing a few hundred times during link stage (LNK2001) so i need to sort that first.

for now this is a description of how it was going wrong in v 254 but line numbers probably no use now for v256 v257...
Yes, if you can provide a modified sample for Bullet 2.57 or Bullet 2.54 that would be very helpfull. Please only attach a the .cpp file of a demo (that reproduces the problem directly) to this topic. I haven't verified 2.57 with VC6 yet, so if you have fixes, they will get integrated into Bullet 2.58.

Thanks again!
Erwin
Proctoid
Posts: 18
Joined: Fri Apr 21, 2006 3:04 pm
Location: uk

Re: Problem changing the rotation of a kinematic body

Post by Proctoid »

here is the modified BasicDemo.cpp from v257 which shows the bug
Attachments
BasicDemo.zip
BasicDemo.cpp
(3.42 KiB) Downloaded 273 times
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Problem changing the rotation of a kinematic body

Post by Erwin Coumans »

It was a de-normalized quaternion, causing acosf to fail. It is fixed in SVN, and should go in Bullet 2.59.

Thanks for the report!
Erwin
Post Reply