husky
July 4, 2012, 5:43pm
1
Is there a way to make objects hover by applying a force to compensate for the gravity? A simple testcase does not what I expected it to do:
[java]package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.PhysicsTickListener;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.light.AmbientLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
/**
test
@author normenhansen
/
public class Main extends SimpleApplication implements PhysicsTickListener
{
Node ship;
RigidBodyControl ship_phy;
public static void main(String[] args) {
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp() {
BulletAppState bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.getPhysicsSpace().addTickListener(this);
bulletAppState.getPhysicsSpace().setMaxSubSteps(4);
bulletAppState.getPhysicsSpace().setGravity(new Vector3f(0f,-10f,0f));
ship = new Node();
Box b = new Box(Vector3f.ZERO, 1, 0.1f, 1);
Geometry geom = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue);
geom.setMaterial(mat);
Box bx = new Box(new Vector3f(0, 1, 0), 0.1f, 0.1f, 0.1f);
Geometry geomx = new Geometry("Box", bx);
Material matx = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
matx.setColor("Color", ColorRGBA.Red);
geomx.setMaterial(matx);
AmbientLight al = new AmbientLight();
al.setColor(ColorRGBA.White.mult(1.3f));
rootNode.addLight(al);
ship.attachChild(geomx);
ship_phy = new RigidBodyControl(1f);
ship.addControl(ship_phy);
rootNode.attachChild(ship);
bulletAppState.getPhysicsSpace().add(ship_phy);
ship_phy.setPhysicsLocation(new Vector3f(0, 0.5f, 0));
rootNode.attachChild(geom);
}
@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
public void prePhysicsTick(PhysicsSpace space, float f)
{
ship_phy.applyForce(new Vector3f(0,10f,0), ship_phy.getPhysicsLocation());
//ship_phy.applyImpulse(new Vector3f(0,0.1f,0), new Vector3f(0,0,0));
}
public void physicsTick(PhysicsSpace space, float f)
{
//throw new UnsupportedOperationException("Not supported yet.");
}
}
[/java]
The red box will be pushed up, while the force applied to it is equal to the force of gravity. I assume it is not as easy as in real world, but can somebody explain to me why this is happening? Normally, I would say that the force to compensate for the gravity would be m g, but in this case this does not work. I have set g to -10, mass to 1 and the counterforce to 10, but still the box is pushed up.
zarch
July 4, 2012, 5:51pm
2
Try 10f*f instead of 10f in prePhysicsTick.
1 Like
husky
July 4, 2012, 5:58pm
3
Darn!
Almost works, just had to do applyImpuls instead of applyForce, together with the 10ff @zarch suggested:
[java]ship_phy.applyImpulse(new Vector3f(0,10f f,0), new Vector3f(0,0,0));[/java]
This makes the block perfectly steady in the air.
I have been fiddling around a lot with applyImpulse, just not added the f! :roll:
Now back to the drawing board of the ship simulator to work on the buoyance a little bit more
1 Like
zarch
July 4, 2012, 6:46pm
4
Yeeh. I don’t know the physics system but in real system a force has to be applied over time to do anything.
I guessed that the incoming f was the physics equivalent of tpf and applied it to the force
yh f is tpf, I applied a patch to this a few weeks ago, as usual I just get ignored normen <3
here it is again, hopefully the file hasn’t changed as I just copy and pasted it from my other post:
[patch]
This patch file was generated by NetBeans IDE
It uses platform neutral UTF-8 encoding and n newlines.
— Base (BASE)
+++ Locally Modified (Based On LOCAL)
@@ -1,5 +1,5 @@
/*
Copyright © 2009-2010 jMonkeyEngine
Copyright © 2009-2012 jMonkeyEngine
All rights reserved.
*
Redistribution and use in source and binary forms, with or without
@@ -42,13 +42,13 @@
@param space the physics space
@param tpf the time per frame in seconds
*/
public void prePhysicsTick(PhysicsSpace space, float f);
public void prePhysicsTick(PhysicsSpace space, float tpf);
/**
Called after the physics has been stepped, use to check for forces etc.
@param space the physics space
@param tpf the time per frame in seconds
*/
public void physicsTick(PhysicsSpace space, float f);
public void physicsTick(PhysicsSpace space, float tpf);
}
[/patch]
1 Like
I just want to call attention to this, it seems to be a bug. Like @husky , I had to use applyimpulse() instead of applyforce(). Is this a bug?
Correct me if I’m wrong. I want to know if this is a bug so we fix this.
Edit: This is not a bug. See the following post.
pspeed
May 29, 2013, 10:11pm
7
@Pixelapp said:
I just want to call attention to this, it seems to be a bug. Like @husky, I had to use applyimpulse() instead of applyforce(). Is this a bug?
Correct me if I’m wrong. I want to know if this is a bug so we fix this.
Well, a force of 10 is a teeny tiny force by any standards and certainly no where near large enough to counteract gravity… which would mass * 10 as a force.
F = ma… so forces must include mass.
Yes, with mass = 400 and gravity = 10 this works.
public void prePhysicsTick(PhysicsSpace space, float tpf)
{
player.applyForce(new Vector3f(0,400*10,0f), new Vector3f(0,0,0));
}
Thanks for the explanation. @pspeed :).
Just a sidenote, why not just set the Gravity to 0,0,0 ? does the same actually without applying gravity and couterforce for each tick
This leads me to consider a thrust vectoring controller class that can be added to a spatial where you can then tinker with impulse points as offsets from the local position of the spatial and the thrust vector values themselves. Could make for a handy class for lunar landers and beyond. :roll: