Very simple collision example! (Update)

Hello, I would like you to complete my code. I would like to know how can I detect the collision between the boxes. Can you also place a response to make the movable box become red while it collides?



In my opinion this is a very fundamental example, so placing it in the distribution will give lots of clues to beginners. Thanks!



(I hope I will complete my Pong clone in a few days, to finally post the full source code in here :D)




Here’s the complete source code!!! Thanks for all the help in order to make this :wink:





package jme3test.collision;



import com.jme3.app.SimpleApplication;

import com.jme3.bounding.BoundingBox;

import com.jme3.bounding.BoundingVolume;

import com.jme3.collision.Collidable;

import com.jme3.collision.CollisionResults;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.scene.shape.Box;

import com.jme3.scene.Geometry;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.AnalogListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.material.MatParam;

import com.jme3.shader.VarType;

import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;



public class BoxesCollisionTest extends SimpleApplication {

Geometry geom1, geom2;

Box box1, box2;



public static void main(String[] args) {

BoxesCollisionTest app = new BoxesCollisionTest();

app.start();

}



@Override

public void simpleInitApp() {

// Create two boxes

box1 = new Box(new Vector3f(-2, 0, 0), 1, 1, 1);

box2 = new Box(new Vector3f(2, 0, 0), 1, 1, 1);



geom1 = new Geometry(“Box”, box1);

geom2 = new Geometry(“Box”, box2);



Material m1 = new Material(assetManager, “Common/MatDefs/Misc/SolidColor.j3md”);

Material m2 = m1.clone();



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

m2.setColor(“m_Color”, ColorRGBA.Green);



geom1.setMaterial(m1);

geom2.setMaterial(m2);



rootNode.attachChild(geom1);

rootNode.attachChild(geom2);



// Create input

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

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

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

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



inputManager.addListener(analogListener, new String[]{

“MoveRight”, “MoveLeft”, “MoveUp”, “MoveDown”

});

}



private AnalogListener analogListener = new AnalogListener() {



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

if (name.equals(“MoveRight”))

geom1.move(10 * tpf, 0, 0);



if (name.equals(“MoveLeft”))

geom1.move(-10 * tpf, 0, 0);



if (name.equals(“MoveUp”))

geom1.move(0, 10 * tpf, 0);



if (name.equals(“MoveDown”))

geom1.move(0, -10 * tpf, 0);

}

};



@Override

public void simpleUpdate(float tpf) {

rootNode.updateGeometricState();



BoundingVolume bv1 = geom1.getWorldBound();

BoundingVolume bv2 = geom2.getWorldBound();



if (bv1.intersects((BoundingVolume) bv2) == true)

geom1.getMaterial().setColor(“m_Color”, ColorRGBA.Red);

else

geom1.getMaterial().setColor(“m_Color”, ColorRGBA.Blue);

}







}



There is no overlapping collision support in jme3 for geometry atm, only for rays. You could use the physics GhostNode for overlapping collision tests. See the GhostNode tests in jmetest.bullet.

Cheers,

Normen

Actually you should be able to do collision. You can do bounding volume vs. triangle or bounding volume vs. bounding volume.

Use the “collideWith” method.

Momoko_Fan said:
You can do bounding volume vs. triangle or bounding volume vs. bounding volume.

Oh, really? Cool :)

Thanks for the info, so far I try this but it does not work…



package jme3test.collision;



import com.jme3.app.SimpleApplication;

import com.jme3.bounding.BoundingBox;

import com.jme3.bounding.BoundingVolume;

import com.jme3.collision.Collidable;

import com.jme3.collision.CollisionResults;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.scene.shape.Box;

import com.jme3.scene.Geometry;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.AnalogListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.material.MatParam;

import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;



public class BoxesCollisionTest extends SimpleApplication {

Geometry geom1, geom2;

Box box1, box2;



public static void main(String[] args) {

BoxesCollisionTest app = new BoxesCollisionTest();

app.start();

}



@Override

public void simpleInitApp() {

// Create two boxes

box1 = new Box(new Vector3f(-2, 0, 0), 1, 1, 1);

box2 = new Box(new Vector3f(2, 0, 0), 1, 1, 1);



geom1 = new Geometry(“Box”, box1);

geom2 = new Geometry(“Box”, box2);



Material m1 = new Material(assetManager, “Common/MatDefs/Misc/SolidColor.j3md”);

Material m2 = m1.clone();



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

m2.setColor(“m_Color”, ColorRGBA.Green);



geom1.setMaterial(m1);

geom2.setMaterial(m2);



rootNode.attachChild(geom1);

rootNode.attachChild(geom2);



// Create input

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

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

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

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



inputManager.addListener(analogListener, new String[]{

“MoveRight”, “MoveLeft”, “MoveUp”, “MoveDown”

});

}



private AnalogListener analogListener = new AnalogListener() {



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

if (name.equals(“MoveRight”))

geom1.move(10 * tpf, 0, 0);



if (name.equals(“MoveLeft”))

geom1.move(-10 * tpf, 0, 0);



if (name.equals(“MoveUp”))

geom1.move(0, 10 * tpf, 0);



if (name.equals(“MoveDown”))

geom1.move(0, -10 * tpf, 0);

}

};



@Override

public void simpleUpdate(float tpf) {

if (geom1.getModelBound().intersects(geom2.getModelBound()) == true)

{

System.out.println(tpf);

}

}







}





I have hit an API block now and can’t find the clue.

I haven’t played with collideWith for ages myself, but try that. I don’t think he’s referring to intersects on the bounding volumes directly.



Geometry.collideWith(othergeom?, collisionresult?) something along those lines anyway.

You shouldn’t use model bound, as those are untransformed, e.g in model space. Use the getWorldBound() instead which is in world space.

1 Like

You 're correct I did a debug of getWorldBound() and values changed while moving the blue cube. But now I have another problem, when I try to do an intersection test the program crashes…


SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
at jme3test.collision.BoxesCollisionTest.simpleUpdate(BoxesCollisionTest.java:83)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:177)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:112)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:101)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:166)
at java.lang.Thread.run(Thread.java:619)




Here's the example (replace only the simpleUpdate method).
@Override
public void simpleUpdate(float tpf) {
BoundingVolume bv1 = geom1.getWorldBound();
BoundingVolume bv2 = geom2.getWorldBound();

if (bv1.intersects(bv2) == true)
System.out.println(tpf);
}


Logically this could be a bug right?

The world bound isn’t generated on the first first frame. You have to update the rootNode before accessing the world bound. Put a “rootNode.updateGeometricState();” right before calling getWorldBound().

I tested it and it worked for me with that fix.

First topic updated! Now you can use this thread as a collision detection tutorial. Thank you all guys for the help, keep up the good work!

whoa whoa whoa, I had a throne revelation… So I just realized you said “bounding volume vs. triangle” earlier Momoko? Does this mean we can do simple collisions like back in jme2 now?



Cause all I’m doing is slinging a cylinder bounding volume around to collide with level geometry…

You can’t do bounding volume vs. triangle collision in jME2, so no, I don’t exactly understand your question.

jME1/2 only had bound vs. bound or tri vs. tri. jME3 on the other hand has bound vs. bound and bound vs. tri since those are more commonly used and are faster.

i don’t know if it is the place but how can i download a jar contains jme3test.* packages

You can get them in the jme3 nightly builds