Box stays on edge/rotates up to be on corner.

Please don't post Bullet support questions here, use the above forums instead.
Buzzer
Posts: 7
Joined: Mon Feb 05, 2007 6:08 pm

Box stays on edge/rotates up to be on corner.

Post by Buzzer »

I have a simple, handmade physics code.
Basically I have a concave heightfield for the ground, and box that I'm trying to drop on it.

For simplicities sake, I decided only the corners of the box were substainatal. I binary search through time in order to find the collision point(s).

Once I do, I go through each corner, and, if it is within a certain distance of the ground it is directly over, I compute the following

Code: Select all

ComponentOfLinearVelocityFromAngular = AngularVelocity cross ArmInWorldSpace
LinearVelocity = PureLinearVelocity + ComponentOfLinearVelocityFromAngular
NormalVelocity = LinearSpeed projected onto Normal.
TangentalVelocity = LinearVelocity - NormalVelocity

CorrectionVelocity = -1.5 * NormalVelocity;
CorrectionTorque = ArmInWorldSpace cross CorrectionVelocity
I sum these over any corners that are touching an take the average. This works a good potion of the time, but often the box rotates up to rest on one corner, or less frequently on an edge.

Any ideas?[/i][/code]
bone
Posts: 231
Joined: Tue Feb 20, 2007 4:56 pm

Re: Box stays on edge/rotates up to be on corner.

Post by bone »

Buzzer wrote:

Code: Select all

CorrectionTorque = ArmInWorldSpace cross CorrectionVelocity
[/i][/code]
It appears that you are trying to create an impulse, but this isn't quite the right equation to do so.

One way to do it is to determine the "effective mass" (my terminology but probably not the correct terminology) when trying to push your object away from the collision at the collision point. Then you divide the CorrectionVelocity by the effective mass to create an impulse. Then apply the impulse as you assumably are doing now.

This is how I compute the effective mass given a world offset and world normal:

cross1 = CrossProduct( worldOffset, worldNormal )
temp = I^-1 * cross1 // I^-1 being the inverse inertia tensor
cross2 = CrossProduct( temp, worldOffset )
effMass = DotProduct( cross2, worldNormal ) + 1/mass

so then: impulse = correctionVelocity / effMass

I believe the above method includes the gyro terms which many game physics engines ignore ... I'm not exactly sure how to remove the gyro term from this method, but it's undoubtedly faster if you do.
bone
Posts: 231
Joined: Tue Feb 20, 2007 4:56 pm

Post by bone »