How would you go about nudging or adding a drifting force (left or right) to an rigid body lifted into the air and gradually falling down (due to gravity).
Would you apply a small central impulse to the object ?
thnx
Drift an object flying in air
-
- Posts: 229
- Joined: Sun Sep 30, 2007 7:58 am
Re: Drift an object flying in air
Hi,
i use ApplyTorqueImpulse.
To stay upward i create a btQuaternion that points up.
Then i use btTransformUtil::calculateVelocity (with 1 second time) to calculate the angular velocity which i then apply each step.
This allows to give good shakes to the objet and it aligns after some time again to the xz axis. Feels very natural.
i use ApplyTorqueImpulse.
To stay upward i create a btQuaternion that points up.
Then i use btTransformUtil::calculateVelocity (with 1 second time) to calculate the angular velocity which i then apply each step.
This allows to give good shakes to the objet and it aligns after some time again to the xz axis. Feels very natural.
-
- Posts: 15
- Joined: Sat Nov 29, 2008 6:34 am
Re: Drift an object flying in air
Hey thanks a bundle.
I sorted it out and wanted to share the result. It works well.
I know a lot of people are looking for a way to keep things upright, like a vehicle. Rather than using an upward constraint, this solution allows for free rotation that interpolates gradually back to the upward position.
Called every second or so when you update your scene.
I sorted it out and wanted to share the result. It works well.
I know a lot of people are looking for a way to keep things upright, like a vehicle. Rather than using an upward constraint, this solution allows for free rotation that interpolates gradually back to the upward position.
Code: Select all
// ====================================================================================== //
//
// ====================================================================================== //
- (void) InterpolateUpward {
btVector3 linVelA, angVelA;
btTransform fromA, toA;
gBV_carChassis->getMotionState()->getWorldTransform( fromA );
btQuaternion point_up( btVector3(0.f, 1.f, 0.f), 0.0f );
btMatrix3x3 fromMat = fromA.getBasis();
btQuaternion orn;
fromA.getBasis().getRotation(orn);
point_up *= orn;
btMatrix3x3 upMat( point_up );
toA.setBasis( upMat );
// timestep 1.0 sec
btTransformUtil::calculateVelocity(fromA, toA, btScalar(1.0f), linVelA, angVelA );
gBV_carChassis->setAngularVelocity( angVelA );
} // InterpolateUpward
Called every second or so when you update your scene.
Code: Select all
if ( (fps_ttotal - gSaveTotalTm) > 1 ) {
[self InterpolateUpward];
gSaveTotalTm = fps_ttotal;
}
-
- Posts: 15
- Joined: Sat Nov 29, 2008 6:34 am
Re: Drift an object flying in air
Here is a slimmed down version, since I am not using the Linear velocity. Essentially parsing down the function btTransformUtil::calculateVelocity to get the necessary info.
Code: Select all
// ====================================================================================== //,,,,,,,,,
//
// ====================================================================================== //
- (void) InterpolateUpward {
btVector3 linVelA, angVelA;
btTransform fromA, toA;
float yaw, pitch , roll;
gBV_carChassis->getMotionState()->getWorldTransform( fromA );
btQuaternion point_up( btVector3(0.f, 1.f, 0.f), 0.0f );
btMatrix3x3 fromMat = fromA.getBasis();
btQuaternion orn;
fromA.getBasis().getRotation(orn);
point_up *= orn;
btMatrix3x3 upMat( point_up );
toA.setBasis( upMat );
btMatrix3x3 dmat = toA.getBasis() * fromA.getBasis().inverse();
btQuaternion dorn;
dmat.getRotation(dorn);
// floating point inaccuracy can lead to w component > 1..., which breaks
dorn.normalize();
btScalar angle = dorn.getAngle();
btVector3 axis = btVector3(dorn.x(), dorn.y(), dorn.z());
// axis[3] = btScalar(0.0f);
btScalar len = axis.length2();
if (len < SIMD_EPSILON * SIMD_EPSILON ) {
axis = btVector3(btScalar(1.0f), btScalar(0.0f), btScalar(0.0f));
} else {
axis /= sqrtf( len );
}
// when timestep == 1.0
angVelA = axis * angle; // otherwise divide by timeStep: angVel = axis * angle / timeStep;
gBV_carChassis->setAngularVelocity( angVelA );
} // InterpolateUpward
-
- Posts: 15
- Joined: Sat Nov 29, 2008 6:34 am
Re: Drift an object flying in air
Scratch what I have above. It is only setting the angular velocity to 0,0,0.
So for now ONLY when the vehicle is in the air, I check for rotation on x and z axis to see if it is greater than a constant threshold. then gradually creep toward the threshold until both x & z angles are below it. This straightens out the vehicle while in flight.
So for now ONLY when the vehicle is in the air, I check for rotation on x and z axis to see if it is greater than a constant threshold. then gradually creep toward the threshold until both x & z angles are below it. This straightens out the vehicle while in flight.
Code: Select all
- (void) InterpolateUpward {
float xv, yv, zv, wv;
btTransform currTrans;
btQuaternion qt1;
bool didChange = false;
gBV_carChassis->getMotionState()->getWorldTransform( currTrans );
currTrans.getBasis().getRotation( qt1 );
xv = qt1.x();
yv = qt1.y();
zv = qt1.z();
wv = qt1.w();
if ( xv > ANGLE_THRESHOLD ) {
xv += -0.01f;
qt1.setX( xv );
didChange = true;
}
if ( xv < -ANGLE_THRESHOLD ) {
xv += 0.01f;
qt1.setX( xv );
didChange = true;
}
if ( zv > ANGLE_THRESHOLD ) {
zv += -0.01f;
qt1.setZ( zv );
didChange = true;
}
if ( zv < -ANGLE_THRESHOLD ) {
zv += 0.01f;
qt1.setZ( zv );
didChange = true;
}
if ( didChange ) {
gBV_carChassis->setAngularVelocity( btVector3( 0.0f, 0.0f, 0.0f ) );
currTrans.setRotation( qt1 );
gBV_carChassis->getWorldTransform().setBasis( currTrans.getBasis() );
}
} // InterpolateUpward