Gravity force not applied correctly?

Hi guys,

I just encountered a problem with the gravitation force. I’m applying a “anti-gravity force” in order to compensate the gravity. These two forces should cancel each other out, but my character raises from the ground and starts to float upwards.
Does anybody have an idea where the resulting upward movement comes from?
I printed the applied forces and they were exactly equal…
Additionally, I printed the current velocity and against the expectation it increased.

Here is a small test class to demonstrate the problem:

package start;

import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AppState;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.PhysicsTickListener;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.objects.PhysicsRigidBody;
import com.jme3.math.Vector3f;

public class GravityTest extends SimpleApplication implements
PhysicsTickListener {

public GravityTest() {
}

public GravityTest(AppState... initialStates) {
	super(initialStates);
}

public static void main(String[] args) {
	GravityTest app = new GravityTest();
	app.start();
}

private CollisionShape shape = new BoxCollisionShape(new Vector3f(1, 1, 1));
private float mass = 100;
private PhysicsRigidBody player = new PhysicsRigidBody(shape, mass);
private Vector3f gravity = new Vector3f(0f, -9.81f, 0f);
// force = acceleration * mass
private Vector3f antiGravForce = gravity.mult(-mass);
private boolean antigravActive = true;

@Override
public void simpleInitApp() {
	player.setGravity(gravity);
	player.setAngularFactor(0);
	BulletAppState bulletAppState = new BulletAppState();
	stateManager.attach(bulletAppState);
	bulletAppState.getPhysicsSpace().addTickListener(this);
	bulletAppState.getPhysicsSpace().add(player);
}

@Override
public void physicsTick(PhysicsSpace space, float tpf) {
	System.out.println("V post physics: " + player.getLinearVelocity());
}

@Override
public void prePhysicsTick(PhysicsSpace space, float tpf) {
	System.out.println("==========================");
	System.out.println("V pre physics: " + player.getLinearVelocity());
	if (antigravActive) {
		// counter gravitational force
		player.applyCentralForce(antiGravForce);
		System.out.println("countering gravity " + player.getGravity()
				+ " with antigrav force " + antiGravForce);
		// getGravity() actually returns gravity * mass
	}
}

}

Thx 4 help :smile:

Make antiGravForce = gravity.mult(-1);

Curious: is the implication then that “force” in applyCentralForce() is not an actual “force” as in “force = mass * acceleration”?

…because otherwise the math looked right to me.

Idk, lets see what the result is.

I tried. The body falls then.

I tried some different values, though, using my antiGravForce = gravity.mult(-mass);

mass = 200000
gravity = new Vector3f(0f, -10, 0f);

To me it seems that the physics engine miscalculates. I get physic ticks of standstill and ticks of movement in discrete 1/6 units. Example:

V post physics: (0.0, 0.0, 0.0)
V post physics: (0.0, 0.16666667, 0.0)
V post physics: (0.0, 0.5, 0.0)
V post physics: (0.0, 1.0, 0.0)
V post physics: (0.0, 1.0, 0.0)
V post physics: (0.0, 1.1666666, 0.0)
V post physics: (0.0, 1.5, 0.0)
V post physics: (0.0, 1.5, 0.0)
V post physics: (0.0, 1.6666666, 0.0)
V post physics: (0.0, 1.6666666, 0.0)
V post physics: (0.0, 1.6666666, 0.0)
V post physics: (0.0, 1.6666666, 0.0)
V post physics: (0.0, 1.6666666, 0.0)
V post physics: (0.0, 1.6666666, 0.0)
V post physics: (0.0, 1.6666666, 0.0)
V post physics: (0.0, 1.8333333, 0.0)
V post physics: (0.0, 1.8333333, 0.0)
V post physics: (0.0, 1.8333333, 0.0)
V post physics: (0.0, 1.9999999, 0.0)
V post physics: (0.0, 1.9999999, 0.0)
V post physics: (0.0, 1.9999999, 0.0)

:anguished: defaq?
I did the same test with other masses… same result

Well why don’t you simply set the gravity for that one object to zero?

Because the gravity information is then lost and has to be managed externally (boooh!).
I know that problem :stuck_out_tongue:

I thought the point of this is to get rid of the gravity?

The goal is to defy gravity not to delete it :wink:
Because if a hover jet is turning off the engines it still should fall

Okay but I guess a hover jet rather looks at its own velocity and changes the applied force based on that instead of assuming a certain gravity and mass combination…

Compensating it is not the same as removing it.
But yeah, there are several ways to work around it. Still would be great if the physics engine was able to combine forces with an uncertainty of less than 1/6. Also, considering that the mass doesn’t seem to have any effect, it’s probably an algorithmic bug, not a float uncertainty (or maybe both).

EDIT: Tried applying both gravity and anti-gravity forces manually each tick. That works as expected, as in the resulting velocity is 0 and stays at 0. So whatever the bullet engine does with the gravity vector, it does NOT apply it as a force to the body.

Well, if it’s like other physics engines then gravity will be an acceleration and not a force… ie: mass independent.

Ok, let me rephrase my last sentence:
So whatever the bullet engine does with the gravity vector, it does NOT accelerate falling bodies by applying a gravitational force g * m to the body via its own applyCentralForce method.

And let me rephrase my response similarly…

Well, if it’s like other physics engines then gravity will be treated as an acceleration applied to the velocity directly and not as a force, ie: not g * m just g, ie: mass independent.

Because gravity doesn’t make any sense as a force.

If gravity would be applied as an acceleration why is there no method applyAcceleration(…) ? :hushed: Yet there are applyImpulse(…) and applyForce(…) …

Well I’m sorry to disappoint you, but of course does gravity “make sense” as a force, because in general acceleration only can occur if an object with mass gets moved by a force. :smiley:

Either way, it should be consistent with applying forces. Setting gravity g and applying a force -g*m should result in a velocity of zero. That’s how real physics are if I’m not mistaken.

Yes, that much is true… so it must be the order of operations or something.

In the world of fake physics, you can accelerate all kinds of objects without mass. Gravity doesn’t make sense as a force because it is mass independent. It is pure acceleration.

In my own physics engines, objects can have a base acceleration and that is where gravity is set. I have no idea how bullet does it… but apparently not the same.

For example, the following would be perfectly sensible:
accel = gravity;
accel = accel + forces * inverseMass;
vel = vel + accel * tpf;
pos = pos + vel * tpf;

That’s my basic physics integration copied over a half dozen times now. (I left impulses out.)

You’d probably have to look into the bullet sources to figure out how they do their body integration and where gravity is applied and how.

Oh :sweat_smile: I was talking about real physics.
In fake physics you are absolutely right. One can move objects by whatever source one likes, acceleration, force, impulse or setting the velocity. During the programming process I was taking the whole movement thing as to be more realistic but ran into some inconsistencies, like:

  • PhysicsRigidBody.getGravity() actually returns the gravitational force instead of the gravitation constant one can actually put in by calling PhysicsRigidBody.setGravity(…)
  • a non-zero velocity when applying an anti-grav force to defy gravity (as described in the first post in this very topic :wink:)

In the meantime I tried out to set the body physics to 0 and compute my own gravitation in the prePhysicsTick() simply by apply the gravitational force with PhysicsRigidBody.applyCentralForce(…).
Works fine. (as expected :wink:)
Then I went and tried the “anti-grav-force” thing again. It worked! :smiley:
So now as a consequence my only idea is that something is wrong with the calculation of the forces in the physics tick or does anybody have an idea what could be the problem?

http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=1655&view=previous

Before you ask, no, you can’t change these parameters in jME.