Collision Problem, Box and Model

Hey there,



i would like to test a collision between a box, which is my dummy (will be replaced by a model later), and a Model (a car in this case).



I'd like to exit the game, if the collision is true. I tried it with the intersection command, but it did not work so far :confused:



         if (nissanNode.getModelBound().intersects(b.getModelBound())) {
            System.exit(0);
         }



Eclipse gives me the following message:

"The Method getModelBound() is undefined for the type Node"

Then i tried it with the code below, i can start, but then i get the message afterthe code.


if (nissanNode.getWorldBound().intersects(b.getModelBound())) {
            System.exit(0);
         }



"
SCHWERWIEGEND: Exception in game loop
java.lang.NullPointerException
at drive.simpleInitGame(drive.java:110)
at com.jme.app.BaseSimpleGame.initGame(BaseSimpleGame.java:545)
at com.jme.app.BaseGame.start(BaseGame.java:74)
at drive.main(drive.java:62)
"



Heres my Code so far.


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
 
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.scene.CameraNode;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Box;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.converters.FormatConverter;
import com.jmex.model.converters.ObjToJme;
import java.net.URL;
import java.util.Random;
import java.util.logging.Logger;
 
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingSphere;
import com.jme.image.Texture;
import com.jme.input.KeyInput;
import com.jme.input.action.InputActionEvent;
import com.jme.input.action.KeyInputAction;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Controller;
import com.jme.scene.Skybox;
import com.jme.scene.Spatial;
import com.jme.scene.Text;
import com.jme.scene.TriMesh;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.CullState;
import com.jme.scene.state.MaterialState;
import com.jme.util.TextureManager;
import com.jme.util.resource.ResourceLocatorTool;
import com.jme.util.resource.SimpleResourceLocator;
import com.jmex.audio.AudioSystem;
import com.jmex.audio.AudioTrack;

// Simpel Game erstellen
public class drive extends SimpleGame {
   private static final Logger logger = Logger
      .getLogger(drive.class.getName());
   private Node nissanNode;

   
 // Konfigurationsfenster am Anfang

Jun 9, 2010 8:39:51 PM class org.nothing.drive start()

SEVERE: Exception in game loop

java.lang.NullPointerException

at org.nothing.drive.simpleInitGame(drive.java:92)

at com.jme.app.BaseSimpleGame.initGame(BaseSimpleGame.java:545)

at com.jme.app.BaseGame.start(BaseGame.java:75)

at org.nothing.drive.main(drive.java:65)

Jun 9, 2010 8:39:51 PM com.jme.app.BaseSimpleGame cleanup

INFO: Cleaning up resources.

Jun 9, 2010 8:39:51 PM com.jme.app.BaseGame start

INFO: Application ending.



that's this line for me:

      converter.convert(modelNissan.openStream(), BO);


apparently I need that file Nissan.obj
Maybe you can include it in your post ... after you click Additional Options you can Attach file :)

Hey, thanks.



Here it is. But to big for the Attach File Option :confused:



fileuploadx.de


I'm having problems loading that Nissan.obj file, probably because I don't know much lol

But here

     URL modelNissan = drive.class.getClassLoader().getResource("Nissan.obj");


right after that line, I see that modelNissan is not null, but modelNissan.toString() causes a java.lang.NullPointerException
and obviously so does that modelNissan.openStream() on this line:

         converter.convert(modelNissan.openStream(), BO);



I put that obj file in bin and src folders, near that .java and .class files, but apparently it's not loaded?
Still trying lol
EDIT: This is weird

      URL modelNissan = drive.class.getClassLoader().getResource("./Nissan.obj");
      assert modelNissan != null;
      if (null == modelNissan) {
         System.exit(11)   ;
      }


If I run that, it will exit, but shouldn't it throw AssertionError first? I'm confused :)
I run it in normal and in Debug mode, same thing. Then I delete the drive.class file and run it again in Debug mode and I get some kind of class not found error, so naturally it was using the same class for both modes, which means maybe I messed up my environment by having both JDK 32bit and 64bit installed... So ignore what I said so far, until I fix that...
java.lang.NoClassDefFoundError: org/nothing/drive
Caused by: java.lang.ClassNotFoundException: org.nothing.drive
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)

Hm, but the Programm works fine if i onle remove the interception command…



So the Model works, :slight_smile:



But if you want to see if you have to delete the Light, i only set the light on to see the Box :slight_smile:



Remove the Light and the Interception and it works fine :slight_smile: So i dont think its because of the Model :confused:

Ok, let's see.



I think the main-problem is that you called your class 'drive'


public class drive extends SimpleGame {



There is a check about if the class-name is starting with a capital letter!! *just kidding* Nevertheless it hurts my eyes!  :lol:

There are severall things to consider if working with collisions.

- A node does not have a BoundingVolume, it composes its worldbound from a combination of the attached geometries' bounding-volumes (as they (including box) have a modelbound)
- If you call updateModelBound() on a node it updates every attached geometries' local modelbound, but leaves the node's worldbound as it is. (I know, strange but true) <---this is your problem
- If you want to calculate the worldbound right use updateGeometricState(0,true). (In your case:

nissanNode.updateGeometricState(0, true);

<--this is your solution
- BUT as we 'live' in a scenegraph you should always have your nodes attached to the scenegraph before. It might work if you attach them later but in most of the times as the hierarchy gots deeper it won't.
- do the collision-check in the update-method otherwise it will be called only once. (I know it was just for testing...)
- a last note. rootNode.updateGeometricState(...) is called after each update. So a worldbound should be at each node that is attached to the rootnode. But if you change the position in update and also want to check for collision in the same cycle you have to call updateGeometricState(...) on the node you changed before. Otherwise you will check with old data.
- and a very last one: to check for easy bounding-collision between two nodes use

node1.hasCollision(node2,false)


or
TriangleBased-Collsion:

node1.hasCollision(node2,true)



But your way should be fine as well.

Ok,...hope that makes somethings more clear. Don't hestitate to ask again.

Keep on rocking

Ok, im german sorry, have to read it a couple of times to get it what you mean :wink: I will try it and reply then :slight_smile:



Thank you :wink:





Edit:





Ok, i put my intersection to the simpleUpdate now, just like you said :wink:

And because of that i had to declare it at the top, hope thats ok.



Now, all the things should be at the Scenegraph first, before the collision is tested and the worldbound for my model is updated?



Now here is the new code, but it still does'nt work, sorry but its hard to unterstand what you wanted me to do :wink:

I thought its like this:


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
 
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.scene.CameraNode;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.Line.Mode;
import com.jme.scene.shape.Box;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.converters.FormatConverter;
import com.jmex.model.converters.ObjToJme;
import java.net.URL;
import java.util.Random;
import java.util.logging.Logger;
 
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingSphere;
import com.jme.image.Texture;
import com.jme.input.KeyInput;
import com.jme.input.action.InputActionEvent;
import com.jme.input.action.KeyInputAction;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Controller;
import com.jme.scene.Skybox;
import com.jme.scene.Spatial;
import com.jme.scene.Text;
import com.jme.scene.TriMesh;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.CullState;
import com.jme.scene.state.MaterialState;
import com.jme.util.TextureManager;
import com.jme.util.resource.ResourceLocatorTool;
import com.jme.util.resource.SimpleResourceLocator;
import com.jmex.audio.AudioSystem;
import com.jmex.audio.AudioTrack;

// Simpel Game erstellen
public class drive extends SimpleGame {
   private static final Logger logger = Logger
      .getLogger(drive.class.getName());
   private Node nissanNode;
   private Box b;
   
 // Konfigurationsfenster am Anfang

No problem, I'm german as well :smiley: But collision-detection is not that easy and

playing around with the data is a good training. You really learn most with debugging

and see what is really happening when calling methods (as they don't do every time

what one might think they would do) viva opensource!

Ill try it now again, but i will test the collision of 2 nodes.



I attached my box to a node n, the node an is attached to the rootNode.



Ill try it this way…





Hm, cant get it.



I checked if it works:


System.out.println("MELDUNG" + nissanNode.hasCollision(n,false));



so i got a "false" in my logger window.

But if i write the code below, the programm collapses again, Exception in game loop"

if (nissanNode.hasCollision(n,false)) {
            System.exit(0);
         }



So if i write it in my initGame, there is no error.



But if i write down the command:


if (!(nissanNode.hasCollision(n,false))) {
      System.exit(0);
      }



It opens the window, and closes is instantly, so i thind the Bounding Boxes are colliding all the time.

If i write

if ((nissanNode.hasCollision(n,false))) {
      System.exit(0);
      }



but that makes no sense ;)

Here is a picture of the Bounding boxes, is that right?

Well your first call is asking: are n and nissan NOT colliding (and actually the don't)  the exit is executed.

So the second try is the one to use. What you see in the screenshot is the bounding of rootNode and

its children. So rootNode (as it is a normal node in the end) has composed a worldnode of its own that

includes box and nissan.



…don't forget to place the collison-detection-if in the simpleUpdate() method otherwise nothing will be

done once SimpleGame is running…

but if i put it in the simple update there is the error again



SCHWERWIEGEND: Exception in game loop

java.lang.NullPointerException

at com.jme.scene.Node.hasCollision(Node.java:602)

at com.jme.scene.Spatial.hasCollision(Spatial.java:990)

at drive.simpleUpdate(drive.java:133)

at com.jme.app.SimpleGame.update(SimpleGame.java:60)

at com.jme.app.BaseGame.start(BaseGame.java:84)

at drive.main(drive.java:63)

Hey, I finally found out how to load that Nissan.obj file

since I had a package "org.something.weird" I had to change to this line:

      URL modelNissan = Drive2.class.getClassLoader().getResource(
         "org/something/weird/Nissan.obj");


But now I seem to be needing Nissan.mtl
Could you be so kind to upload it somewhere , please  ;)

If I skip the System.exit on the IOException catch then I also get the NullPointerException at this line
nissanNode.updateGeometricState(0, true);

hm one moment

Well,…the problem is that you got try to access an object that is null! :smiley:



Post some code again, so I can have a look again.

Ok, here it is :slight_smile: I know that something is null, but cant imagine where the error is… sitting here for about 5 hours to solve this probleme and test a collision…




import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
 
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.scene.CameraNode;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.Line.Mode;
import com.jme.scene.shape.Box;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.converters.FormatConverter;
import com.jmex.model.converters.ObjToJme;
import java.net.URL;
import java.util.Random;
import java.util.logging.Logger;
 
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingSphere;
import com.jme.image.Texture;
import com.jme.input.KeyInput;
import com.jme.input.action.InputActionEvent;
import com.jme.input.action.KeyInputAction;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Controller;
import com.jme.scene.Skybox;
import com.jme.scene.Spatial;
import com.jme.scene.Text;
import com.jme.scene.TriMesh;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.CullState;
import com.jme.scene.state.MaterialState;
import com.jme.util.TextureManager;
import com.jme.util.resource.ResourceLocatorTool;
import com.jme.util.resource.SimpleResourceLocator;
import com.jmex.audio.AudioSystem;
import com.jmex.audio.AudioTrack;

// Simpel Game erstellen
public class drive extends SimpleGame {
   private static final Logger logger = Logger
      .getLogger(drive.class.getName());
   public Node nissanNode;
   private Node n;
   
 // Konfigurationsfenster am Anfang

Node n = new Node("My Node");



have to be

n = new Node("My Node");




Oh my god, you are my hero :smiley: it works after 5 hours :smiley:



Could you explain that to me? Just a Syntax mistake? I saw this way in the Tutorial HelloNode and copied it

Node n = new Node("My Node");



This created a local variable n (that only have the same name as the attribute n) that is only visible in the initMethod.

Java-Basics!

ok,glad it finally worked!

Cool! It works for me too lol

But I have to say, that I have to put Nissan.obj and Nissan.mtl files in the output folder which is "bin" here, else if i don't, I get

SEVERE: Exception in game loop

java.lang.NullPointerException

at org.something.weird.Drive3.simpleInitGame(Drive3.java:63)

at com.jme.app.BaseSimpleGame.initGame(BaseSimpleGame.java:545)

at com.jme.app.BaseGame.start(BaseGame.java:75)

at org.something.weird.Drive3.main(Drive3.java:36)

Jun 9, 2010 11:16:55 PM com.jme.app.BaseSimpleGame cleanup

INFO: Cleaning up resources.

Jun 9, 2010 11:16:55 PM com.jme.app.BaseGame start

INFO: Application ending.



that on this line:

         converter.convert(modelNissan.openStream(), BO);



Well good thing :)
Thank you