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
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.
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