Quick Fix for Rigid Body Jitters
by USC CTIN · in Torque Game Builder · 12/30/2008 (9:39 pm) · 0 replies
Good news! I've figured out a way to get those infamous rigid body jitters to stop, while still retaining pretty decent-looking physics. It essentially consists of switching between BOUNCE and RIGID collision responses, utilizing BOUNCE's stability and RIGID's ability to simulate complex Newtonian physics. Now, it's probably far from perfect, but I think I'm at least onto something.
Here's the behavior. Sorry it's not in 'code snippet' mode -- I couldn't find the option for it on the web page.
//-----------------------------------------------------------------------------
// Rigid Body Object
//-----------------------------------------------------------------------------
if (!isObject(boxBehavior))
{
%template = new BehaviorTemplate(boxBehavior);
%template.friendlyName = "Box Behavior";
%template.behaviorType = "Physics";
%template.description = "Sets up object and applies physics properties.";
}
function boxBehavior::onBehaviorAdd(%this)
{
//SET UP OBJECT
//This is the threshold of velocity that will decide when we apply the "RIGID"
//or "BOUNCE" collision response. Anything below the threshold will cause it
//to be "BOUNCE," and anything above it will cause it to be "RIGID."
%this.velThreshold = 1.3;
//Allow onCollision and onUpdate to be called.
%this.owner.enableUpdateCallback();
%this.owner.setCollisionCallback(true);
//Set the collision and physics properties.
%this.owner.CollisionActiveSend = "true"; //true
%this.owner.CollisionActiveReceive = "true"; //true
%this.owner.CollisionPhysicsSend = "true"; //true
%this.owner.CollisionPhysicsReceive = "false"; //false
//Set up collison detection and response.
%this.owner.CollisionDetectionMode = "POLYGON";
%this.owner.CollisionResponseMode = "BOUNCE";
//Set the restitution.
%this.owner.setRestitution(0.2);
//Store the restitution, in case we want to refer to it later.
%this.baseRestitution = %this.owner.getRestitution();
//Set the gravity.
%this.owner.setConstantForce("0 10");
}
function boxBehavior::onCollision(%this, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contact)
{
//Test to see whether it is being hit by a fast-moving object. If so, we
//say so in the fastCollision flag.
if (mAbs(%dstObj.getLinearVelocityX()) > %this.velThreshold || mAbs(%dstObj.getAngularVelocity()) > 30 || mAbs(%dstObj.getLinearVelocityY()) > %this.velThreshold)
{
%this.fastCollision = true;
}
else
{
%this.fastCollision = false;
}
}
function boxBehavior::onUpdate(%this)
{
//Store the object's linear and angular velocity.
%this.boxVelX = mAbs(%this.owner.getLinearVelocityX());
%this.boxVelY = mAbs(%this.owner.getLinearVelocityY());
%this.boxAngVel = mAbs(%this.owner.getAngularVelocity());
//Test to see whether the object is moving quickly, and check the fastCollision
//flag. If one or both of these are true, then we apply RIGID type collision
//response. If neither are true, then we apply BOUNCE type collision response.
if (%this.boxVelX > %this.velThreshold || %this.boxVelY > %this.velThreshold || %this.boxAngVel > 30 || %this.fastCollision)
{
%this.owner.CollisionResponseMode = "RIGID";
}
else
{
%this.owner.CollisionResponseMode = "BOUNCE";
//For some reason, the object's angular velocity goes a little crazy
//if you don't manually reduce it:
%this.owner.setAngularVelocity(%this.owner.getAngularVelocity()*0.3);
//Feel free to screw with the .3 factor above.
}
}
Here's the behavior. Sorry it's not in 'code snippet' mode -- I couldn't find the option for it on the web page.
//-----------------------------------------------------------------------------
// Rigid Body Object
//-----------------------------------------------------------------------------
if (!isObject(boxBehavior))
{
%template = new BehaviorTemplate(boxBehavior);
%template.friendlyName = "Box Behavior";
%template.behaviorType = "Physics";
%template.description = "Sets up object and applies physics properties.";
}
function boxBehavior::onBehaviorAdd(%this)
{
//SET UP OBJECT
//This is the threshold of velocity that will decide when we apply the "RIGID"
//or "BOUNCE" collision response. Anything below the threshold will cause it
//to be "BOUNCE," and anything above it will cause it to be "RIGID."
%this.velThreshold = 1.3;
//Allow onCollision and onUpdate to be called.
%this.owner.enableUpdateCallback();
%this.owner.setCollisionCallback(true);
//Set the collision and physics properties.
%this.owner.CollisionActiveSend = "true"; //true
%this.owner.CollisionActiveReceive = "true"; //true
%this.owner.CollisionPhysicsSend = "true"; //true
%this.owner.CollisionPhysicsReceive = "false"; //false
//Set up collison detection and response.
%this.owner.CollisionDetectionMode = "POLYGON";
%this.owner.CollisionResponseMode = "BOUNCE";
//Set the restitution.
%this.owner.setRestitution(0.2);
//Store the restitution, in case we want to refer to it later.
%this.baseRestitution = %this.owner.getRestitution();
//Set the gravity.
%this.owner.setConstantForce("0 10");
}
function boxBehavior::onCollision(%this, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contact)
{
//Test to see whether it is being hit by a fast-moving object. If so, we
//say so in the fastCollision flag.
if (mAbs(%dstObj.getLinearVelocityX()) > %this.velThreshold || mAbs(%dstObj.getAngularVelocity()) > 30 || mAbs(%dstObj.getLinearVelocityY()) > %this.velThreshold)
{
%this.fastCollision = true;
}
else
{
%this.fastCollision = false;
}
}
function boxBehavior::onUpdate(%this)
{
//Store the object's linear and angular velocity.
%this.boxVelX = mAbs(%this.owner.getLinearVelocityX());
%this.boxVelY = mAbs(%this.owner.getLinearVelocityY());
%this.boxAngVel = mAbs(%this.owner.getAngularVelocity());
//Test to see whether the object is moving quickly, and check the fastCollision
//flag. If one or both of these are true, then we apply RIGID type collision
//response. If neither are true, then we apply BOUNCE type collision response.
if (%this.boxVelX > %this.velThreshold || %this.boxVelY > %this.velThreshold || %this.boxAngVel > 30 || %this.fastCollision)
{
%this.owner.CollisionResponseMode = "RIGID";
}
else
{
%this.owner.CollisionResponseMode = "BOUNCE";
//For some reason, the object's angular velocity goes a little crazy
//if you don't manually reduce it:
%this.owner.setAngularVelocity(%this.owner.getAngularVelocity()*0.3);
//Feel free to screw with the .3 factor above.
}
}