Bullet physics applyImpulse() trouble (and fix)
by David Wyand · in Torque 3D Professional · 12/04/2013 (11:06 pm) · 3 replies
Greetings!
I'm not sure how many have been using the Bullet physics library with T3D but I've made use of it in my Rift/Hydra demo for the shooting range. It turns out that applyImpulse() is broken while using this library, and always has been.
Traditionally in T3D applyImpulse(pos, amount_vector) as called from script uses a world position and vector. Default T3D physics and PhysX work with this just fine. However, Bullet requires a local position and world vector, and the code was not taking this into account. Here is my fix for T3D/physics/bullet/btBody.cpp:
Before submitting this fix to the repo I was wondering if anyone out there is even using Bullet, and if so have they had any issues with applyImpulse() before? The original code has been there ever since Bullet support was implemented. Without this fix I'm getting very strange results from an impulse (as you would expect) and now my tin cans are flying up in the air as anticipated when shot.
- Dave
I'm not sure how many have been using the Bullet physics library with T3D but I've made use of it in my Rift/Hydra demo for the shooting range. It turns out that applyImpulse() is broken while using this library, and always has been.
Traditionally in T3D applyImpulse(pos, amount_vector) as called from script uses a world position and vector. Default T3D physics and PhysX work with this just fine. However, Bullet requires a local position and world vector, and the code was not taking this into account. Here is my fix for T3D/physics/bullet/btBody.cpp:
void BtBody::applyImpulse( const Point3F &origin, const Point3F &force )
{
AssertFatal( mActor, "BtBody::applyImpulse - The actor is null!" );
AssertFatal( isDynamic(), "BtBody::applyImpulse - This call is only for dynamics!" );
// Convert the world position to local
MatrixF trans = btCast<MatrixF>( mActor->getCenterOfMassTransform() );
trans.inverse();
Point3F localOrigin( origin );
trans.mulP( localOrigin );
if ( mCenterOfMass )
{
Point3F relOrigin( localOrigin );
mCenterOfMass->mulP( relOrigin );
Point3F relForce( force );
mCenterOfMass->mulV( relForce );
mActor->applyImpulse( btCast<btVector3>( relForce ), btCast<btVector3>( relOrigin ) );
}
else
mActor->applyImpulse( btCast<btVector3>( force ), btCast<btVector3>( localOrigin ) );
if ( !mActor->isActive() )
mActor->activate();
}Before submitting this fix to the repo I was wondering if anyone out there is even using Bullet, and if so have they had any issues with applyImpulse() before? The original code has been there ever since Bullet support was implemented. Without this fix I'm getting very strange results from an impulse (as you would expect) and now my tin cans are flying up in the air as anticipated when shot.
- Dave
About the author
A long time Associate of the GarageGames' community and author of the Torque 3D Game Development Cookbook. Buy it today from Packt Publishing!
#2
I swapped the code in/out to see the differences. The fix does seem much nicer to work with. Things seem to react a bit more predictably to the values, I think? I had it setup to apply impulses based on collisions from within source but tried calling it from script as well.
On the topic of Bullet issues, a 'major' one I've encountered is the lack of ability to toggle player collisions in ray casting. "BtPlayer::enableCollision()" and "BtPlayer::disableCollision()"; the code is commented out. I spent a lot of time trying to figure it out but it's just beyond me. Ended up just teleporting the player out of the way during ray casting. That, and terrain holes being solid, but I've yet to look into that one.
Thank you for the fix, I'll keep using it and update if I start seeing anything odd.
12/05/2013 (6:52 am)
I'm using Bullet in a current project. Been using it since T3D 3.0 and it's now updated with T3D 3.5. Right now it's just the player bumping into boxes and balls. I've noticed it could be a little fickle in how objects react to impulses sometimes but didn't really notice how off it is until now.I swapped the code in/out to see the differences. The fix does seem much nicer to work with. Things seem to react a bit more predictably to the values, I think? I had it setup to apply impulses based on collisions from within source but tried calling it from script as well.
On the topic of Bullet issues, a 'major' one I've encountered is the lack of ability to toggle player collisions in ray casting. "BtPlayer::enableCollision()" and "BtPlayer::disableCollision()"; the code is commented out. I spent a lot of time trying to figure it out but it's just beyond me. Ended up just teleporting the player out of the way during ray casting. That, and terrain holes being solid, but I've yet to look into that one.
Thank you for the fix, I'll keep using it and update if I start seeing anything odd.
#3
12/22/2013 (6:27 pm)
I ran into this issue when trying to do buoyancy stuff. Whenever I would call applyImpulse it would cause my object to spin out of control, but the same code with PhysX worked fine.I think it even does this with the default physicsShape. If you lower the damping, it just causes the shape to spin in the water.I'm guessing what you did fixes that.
J0linar
it was actually odd but that is some time ago when i tested Bullet
and am sure ppl are using Bullet as its after all the best solution for indies. (am at least gonna use Bullet)
I remember that i tested it with PhysX and Bulle and PhysX worked without problems but with Bullet it ended being a real pain to get something flyin around.
Thanks Dave for investigating