Ball on a plane issues

Hey,



I have some issues with a simple application. I’m drawing a plane and a ball coming on it. I’d like to move the plane (using the keyboard keys) so that the ball roll around on it. But the application is returning errors that I don’t get… here is my code so you can test :

[java]import com.jme3.app.SimpleApplication;

import com.jme3.bullet.BulletAppState;

import com.jme3.bullet.control.RigidBodyControl;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.AnalogListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Matrix3f;

import com.jme3.math.Vector3f;

import com.jme3.renderer.queue.RenderQueue.ShadowMode;

import com.jme3.scene.Geometry;

import com.jme3.scene.Node;

import com.jme3.scene.shape.*;

import com.jme3.shadow.BasicShadowRenderer;



public class HelloTest extends SimpleApplication {



private BulletAppState bulletAppState;

private Geometry floorGeometry;

private AnalogListener analogListener = new AnalogListener() {

public void onAnalog(String name, float value, float tpf) {

float a = value * speed;

if (name.equals(“Right”)) {

floorGeometry.rotate(0, 0, value * speed);

}

if (name.equals(“Left”)) {

floorGeometry.rotate(0, 0, -value * speed);

}

if (name.equals(“Up”)) {

floorGeometry.rotate(-value * speed, 0, 0);

}

if (name.equals(“Down”)) {

floorGeometry.rotate(value * speed, 0, 0);

}



}

};



public static void main(String[] args) {

HelloTest test = new HelloTest();

test.start();

}



@Override

public void simpleInitApp() {

initKeys();

initShadows();

initCamera();

bulletAppState = new BulletAppState();

stateManager.attach(bulletAppState);

makeBall(1, new Vector3f(0, 5f, 0));

makeFloor(5, new Vector3f(0, 0, 0));

}



public void makeBall(float radius, Vector3f position) {

Sphere sphere = new Sphere(100, 100, radius, true, false);

Geometry sphereGeometry = new Geometry(“Sphere”, sphere);

Material sphereMaterial = new Material(assetManager,

“Common/MatDefs/Misc/SolidColor.j3md”);

sphereMaterial.setColor(“m_Color”, ColorRGBA.Blue);

sphereGeometry.setMaterial(sphereMaterial);

sphereGeometry.setShadowMode(ShadowMode.CastAndReceive);

sphereGeometry.setLocalTranslation(position);

RigidBodyControl spherePhysics = new RigidBodyControl(1f);

sphereGeometry.addControl(spherePhysics);

bulletAppState.getPhysicsSpace().add(spherePhysics);

rootNode.attachChild(sphereGeometry);

}



public void makeFloor(float size, Vector3f position) {

Box floor = new Box(size, 0, size);

Geometry floorGeometry = new Geometry(“floor”, floor);

Material floorMaterial = new Material(assetManager,

“Common/MatDefs/Misc/SolidColor.j3md”);

floorMaterial.setColor(“m_Color”, ColorRGBA.Red);

floorGeometry.setMaterial(floorMaterial);

floorGeometry.setShadowMode(ShadowMode.CastAndReceive);

floorGeometry.setLocalTranslation(position);

RigidBodyControl floorPhysics = new RigidBodyControl(0f);

floorGeometry.addControl(floorPhysics);

bulletAppState.getPhysicsSpace().add(floorPhysics);

rootNode.attachChild(floorGeometry);

}



private void initShadows() {

BasicShadowRenderer bSR = new BasicShadowRenderer(assetManager, 1024);

bSR.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());

viewPort.addProcessor(bSR);

// bSR.setCompareMode(CompareMode.Software);

rootNode.setShadowMode(ShadowMode.Off);

}



private void initKeys() {

// inputManager.clearMappings();

inputManager.addMapping(“Left”, new KeyTrigger(KeyInput.KEY_J));

inputManager.addMapping(“Right”, new KeyTrigger(KeyInput.KEY_L));

inputManager.addMapping(“Up”, new KeyTrigger(KeyInput.KEY_I));

inputManager.addMapping(“Down”, new KeyTrigger(KeyInput.KEY_K));



// inputManager.addListener(actionListener, new String[] { });

inputManager.addListener(analogListener, new String[] { “Left”,

“Right”, “Up”, “Down” });

}



private void initCamera() {

cam.setLocation(new Vector3f(0, 10f, 10f));

cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0));

cam.setFrustumFar(50);

}

}[/java]



Thx for any help !

It would be helpful to post the errors too :slight_smile:

True ^_^… actually it returns the error only when I press one of the keys I have configured :


SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
at com.jme3test.hellotest.HelloTest$1.onAnalog(HelloTest.java:33)
at com.jme3.input.InputManager.invokeAnalogs(InputManager.java:219)
at com.jme3.input.InputManager.invokeUpdateActions(InputManager.java:189)
at com.jme3.input.InputManager.update(InputManager.java:601)
at com.jme3.app.Application.update(Application.java:453)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:223)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:158)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:203)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:221)
at java.lang.Thread.run(Thread.java:680)

Your floorGeometry is null … ever

in the makeFloor-method, you must change

[java]Geometry floorGeometry = new Geometry("floor", floor);[/java]

to

[java]floorGeometry = new Geometry("floor", floor);[/java]

to write the object into the class-wide variable

Oh yes… that’s what happen when you change things in your code again and again ^_^.



So here is another question now. How can I do for my ball (no joke in this) to roll according to the floor pitch/yaw/roll ? Because fo now my plane rotate through my ball. =S

you want the ball to roll off the plane if you pitch/roll/yaw the plane?

Than you have to add physics to ball and plane - you already did it I see :slight_smile:

You should add collision-shapes to plane and ball:

in the constructors of your RigidBodyControls add the CollisionShapes (SphereCollisionShape for ball, BoxCollisionShape for floor)

Yes that’s exactly what I want.

What mean the parameters for the BoxCollisionShape ? because my ball fall through my plane now… :smiley:

I guess I have to put size of my plane in it. If it’s the case i tried and there is still no updates when I pitch/yaw/roll my plane.

I don’t know what the parameter means. :smiley:

I think it means the halve length of your three sizes (width,length,height). You also could call

[java]bulletAppState.getPhysicsSpace().enableDebug(assetManager);[/java]

in the simpleInitApp()-method, so you see the bounding volumes. Now you could try and error to fit the parameter of the BoxCollisionShape.

With BoxCollisionShape(new Vector3f(size/2, 0, size/2)) :







The 0 value seems not to be considered so I tried with MeshCollisionShape(floor) :







The collision shape seems better but there is still no interaction between the sphere and the plane.

Hello!



Fixed it up. Code below.



Two issues:

The float a = value * speed; wasn’t even being used, but besides that, it would be much much better to specify a constant or a variable that you can change, and multiply it by the tpf to make the rotation frame independent. I’m not sure what the analog value * speed would really give you, other than a REALLY small number.



You needed to set the floor to kinematic mode to be able to manipulate it with the rotate methods of it’s spatial. Only rigidBodies in kinematic mode can be affected by moves and rotates (and setLocalTranslation etc etc).



EDIT: Oh and one other thing I almost forgot. I gave the plane some meat to it. The physics volume was really weird with it being completely flat. This actually is a common thing if you’re specifying a geometry. Unless it’s just a quad, where you have no backfaces, make sure you at least give it a little depth. I chose .25f, but if you want to give the illusion that it’s just a plane, just make it something really tiny, like .001f or so. Or just use a quad I guess, but I’m not sure how well that would respond to the physics.



Have fun!

~FlaH



[java]

public class RotatePlane extends SimpleApplication {



private static final float ROT_AMT = 1f;



private BulletAppState bulletAppState;

private Geometry floorGeometry;

private AnalogListener analogListener = new AnalogListener() {

public void onAnalog(String name, float value, float tpf) {

System.out.println(value);

float a = ROT_AMT * tpf;

if (name.equals(“Right”)) {

floorGeometry.rotate(0, 0, a);

}

if (name.equals(“Left”)) {

floorGeometry.rotate(0, 0, -a);

}

if (name.equals(“Up”)) {

floorGeometry.rotate(-a, 0, 0);

}

if (name.equals(“Down”)) {

floorGeometry.rotate(a, 0, 0);

}

}

};



public static void main(String[] args) {

RotatePlane test = new RotatePlane();

test.start();

}



@Override

public void simpleInitApp() {

initKeys();

initShadows();

initCamera();

bulletAppState = new BulletAppState();

stateManager.attach(bulletAppState);

makeBall(1, new Vector3f(0, 5f, 0));

makeFloor(5, new Vector3f(0, 0, 0));

bulletAppState.getPhysicsSpace().enableDebug(assetManager);

}



@Override

public void simpleUpdate(float tpf) {

super.simpleUpdate(tpf);



}



public void makeBall(float radius, Vector3f position) {

Sphere sphere = new Sphere(100, 100, radius, true, false);

Geometry sphereGeometry = new Geometry(“Sphere”, sphere);

Material sphereMaterial = new Material(assetManager,

“Common/MatDefs/Misc/SolidColor.j3md”);

sphereMaterial.setColor(“m_Color”, ColorRGBA.Blue);

sphereGeometry.setMaterial(sphereMaterial);

sphereGeometry.setShadowMode(ShadowMode.CastAndReceive);

sphereGeometry.setLocalTranslation(position);

RigidBodyControl spherePhysics = new RigidBodyControl(1f);

sphereGeometry.addControl(spherePhysics);

bulletAppState.getPhysicsSpace().add(spherePhysics);

rootNode.attachChild(sphereGeometry);

}



public void makeFloor(float size, Vector3f position) {

Box floor = new Box(size, .25f, size);

floorGeometry = new Geometry(“floor”, floor);

Material floorMaterial = new Material(assetManager,

“Common/MatDefs/Misc/SolidColor.j3md”);

floorMaterial.setColor(“m_Color”, ColorRGBA.Red);

floorGeometry.setMaterial(floorMaterial);

floorGeometry.setShadowMode(ShadowMode.CastAndReceive);

floorGeometry.setLocalTranslation(position);

RigidBodyControl floorPhysics = new RigidBodyControl(0f);

floorGeometry.addControl(floorPhysics);

bulletAppState.getPhysicsSpace().add(floorPhysics);

floorPhysics.setKinematic(true);

rootNode.attachChild(floorGeometry);

}



private void initShadows() {

BasicShadowRenderer bSR = new BasicShadowRenderer(assetManager, 1024);

bSR.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());

viewPort.addProcessor(bSR);

// bSR.setCompareMode(CompareMode.Software);

rootNode.setShadowMode(ShadowMode.Off);

}



private void initKeys() {

// inputManager.clearMappings();

inputManager.addMapping(“Left”, new KeyTrigger(KeyInput.KEY_J));

inputManager.addMapping(“Right”, new KeyTrigger(KeyInput.KEY_L));

inputManager.addMapping(“Up”, new KeyTrigger(KeyInput.KEY_I));

inputManager.addMapping(“Down”, new KeyTrigger(KeyInput.KEY_K));



// inputManager.addListener(actionListener, new String[] { });

inputManager.addListener(analogListener, new String[] { “Left”,

“Right”, “Up”, “Down” });

}



private void initCamera() {

cam.setLocation(new Vector3f(0, 10f, 10f));

cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0));

cam.setFrustumFar(50);

}

}

[/java]

Nice :slight_smile: thank you !

One more thing :), any idea of how I could port this on Android ?

still use jmonkey engine! (perhaps there is a method to export it as android package somewhere in jMP)

But I don’t think, the jbullet physics works so well on android :slight_smile:

doe300 said:(...) I don't think, the jbullet physics works so well on android :)

It reportedly does not.

Even for just a Ball rolling on a plane ?

s4milli4 said:
Even for just a Ball rolling on a plane ?


heh, a lot goes on just to do that :p Physics simulations are intense, to say the least.

~FlaH

An what if I’m planning to port this for new android devies generation ? Their CPU’s/GPU’s should be upgraded and so on…

Btw, I saw some 3D games working well on android and using physics much more than I do. Any idea of why then ? Better physics engine ?

No, simpler physics simulation. As for android devices getting faster, you’re right.

s4milli4 said:
An what if I'm planning to port this for new android devies generation ? Their CPU's/GPU's should be upgraded and so on...

But why would you set your aim for something that difficult right off the bat? If you can't make it work now it's a very bad idea to assume that you can probably make it work later. If it turns out the "next generation" you're waiting for isn't gonna be around for another 6 months, are you just gonna sit tight and wait?..

Btw, I saw some 3D games working well on android and using physics much more than I do. Any idea of why then ? Better physics engine ?

First of all, don't base your plans on what other people have accomplished unless you've actually figured out how they did it.

Yes, they had a better physics engine. They might have managed to use Bullet natively, but rather than that, I would guess they just made their own custom physics engine made especially for their game, for optimal performance.
But why would you set your aim for something that difficult right off the bat?


Because that's actually my internship graduation topic ^_^'... I'm currently in a start up that develop apps for Android devices and they want to develop an innovative game app aiming the next Android devices generation. It's gonna include 3D (objects and autosteroscopic), move reco, and so on. So my role is to check the available technologies and to evaluate their capacities. That's why I'm dealing with jME3 which seems to be the best open source/free physics engine I managed to find.

First of all, don’t base your plans on what other people have accomplished unless you’ve actually figured out how they did it.


That's part of my job to find out this "how". So I was asking in case you guys know it as I assume that you must be much more experienced than me in this field.