CollisionTest problem

Hi,



I am trying to check for collisions between my player and a sphere I created. Just some basic stuff:


 Sphere s=new Sphere("My sphere",50,50,1f);
        s.setLocalScale(5f);
        s.setLocalTranslation(new Vector3f(263.75204f, 2.1998527f, 1154.8876f));
        s.setModelBound(new BoundingBox());
        s.updateModelBound();
      // Make a node and give it children
        Node n = new Node("My Node");
        n.attachChild(s);
        rootNode.attachChild(n); // Put it in the scene graph



This is where I create the Sphere! Without the collisiontest it works fine! I made a Sphere s and attached it to the new node n. Then attached that to the root node!

Now my collision Test:

/collisions check player and sphere     
        results.clear();
        player.calculateCollisions(n, results);
       
        if(player.hasCollision(n, true)) {
         logger.info("hasCollision also reports true");
      }



This is where the error (java:lang.NullPointerException) appears...

Don't really get why there is a problem!

Thanks for any help ;)

On what line does the NullPointerException occur? Where do you initialize player and results?

The Exception occurs in this line:


 player.calculateCollisions(n, results);



I initialize the Player with buildPlayer() in initGame().  In that method is also the result initialization.

  results = new BoundingCollisionResults() {
         public void processCollisions() {
            if (getNumber() > 0) {
               System.out.println("Collision: YES");
            } else {
               System.out.println("Collision: NO");
            }
         }
      };

its generally a good idea to copy and paste the stack traces…

Are you using an IDE like Eclipse? If so, put a breakpoint on that line throwing the exception, and you should be able to see what is null.

You mean this?


01.04.2009 20:51:35 com.jme.app.BaseGame start
INFO: Application started.
01.04.2009 20:51:35 com.jme.system.PropertiesIO <init>
INFO: PropertiesIO created
01.04.2009 20:51:35 com.jme.system.PropertiesIO load
INFO: Read properties
01.04.2009 20:51:36 com.jme.system.PropertiesIO save
INFO: Saved properties
01.04.2009 20:51:36 prototyp1.TestIsland initSystem
INFO: jME version 1.0
01.04.2009 20:51:36 com.jme.input.joystick.DummyJoystickInput <init>
INFO: Joystick support is disabled
01.04.2009 20:51:36 com.jme.system.lwjgl.LWJGLDisplaySystem <init>
INFO: LWJGL Display System created.
01.04.2009 20:51:37 com.jme.renderer.lwjgl.LWJGLRenderer <init>
INFO: LWJGLRenderer created. W:  800H: 600
01.04.2009 20:51:37 prototyp1.TestIsland initSystem
INFO: Running on: nv4_disp
Driver version: 6.14.11.7580
NVIDIA Corporation - GeForce 9200M GS/PCI/SSE2 - 2.1.2
01.04.2009 20:51:37 com.jme.renderer.AbstractCamera <init>
INFO: Camera created.
01.04.2009 20:51:37 com.jme.util.lwjgl.LWJGLTimer <init>
INFO: Timer resolution: 1000 ticks per second
01.04.2009 20:51:37 com.jme.scene.Node <init>
INFO: Node created.
01.04.2009 20:51:37 com.jme.scene.Node attachChild
INFO: Child (Terrain) attached to this node (rootNode)
01.04.2009 20:51:37 com.jme.scene.Node <init>
INFO: Node created.
01.04.2009 20:51:37 com.jme.scene.Node <init>
INFO: Node created.
01.04.2009 20:51:37 com.jme.scene.Node <init>
INFO: Node created.
01.04.2009 20:51:37 com.jme.scene.Node <init>
INFO: Node created.
01.04.2009 20:51:37 com.jme.scene.Node <init>
INFO: Node created.
01.04.2009 20:51:37 com.jme.scene.Node <init>
INFO: Node created.
01.04.2009 20:51:37 com.jme.scene.Node <init>
INFO: Node created.
01.04.2009 20:51:37 com.jme.scene.Node <init>
INFO: Node created.
01.04.2009 20:51:37 com.jme.scene.Node <init>
INFO: Node created.
01.04.2009 20:51:37 com.jme.scene.Node <init>
INFO: Node created.
01.04.2009 20:51:37 com.jme.scene.Node attachChild
INFO: Child (TDS Scene) attached to this node (Player Node)
01.04.2009 20:51:37 com.jme.scene.Node attachChild
INFO: Child (Player Node) attached to this node (rootNode)
01.04.2009 20:51:37 com.jme.scene.Node attachChild
INFO: Child (My sphere) attached to this node (rootNode)
01.04.2009 20:51:37 com.jme.scene.Node <init>
INFO: Node created.
01.04.2009 20:51:37 com.jme.scene.Node <init>
INFO: Node created.
01.04.2009 20:51:37 com.jme.scene.Node attachChild
INFO: Child (north) attached to this node (skybox)
01.04.2009 20:51:37 com.jme.scene.Node attachChild
INFO: Child (south) attached to this node (skybox)
01.04.2009 20:51:37 com.jme.scene.Node attachChild
INFO: Child (east) attached to this node (skybox)
01.04.2009 20:51:37 com.jme.scene.Node attachChild
INFO: Child (west) attached to this node (skybox)
01.04.2009 20:51:37 com.jme.scene.Node attachChild
INFO: Child (up) attached to this node (skybox)
01.04.2009 20:51:37 com.jme.scene.Node attachChild
INFO: Child (down) attached to this node (skybox)
01.04.2009 20:51:38 com.jme.scene.Node attachChild
INFO: Child (skybox) attached to this node (reflectNode)
01.04.2009 20:51:38 com.jme.scene.Node attachChild
INFO: Child (reflectNode) attached to this node (rootNode)
01.04.2009 20:51:38 com.jme.renderer.lwjgl.LWJGLTextureRenderer <init>
INFO: FBO support detected.
01.04.2009 20:51:38 com.jme.renderer.lwjgl.LWJGLTextureRenderer initCamera
INFO: Init RTT camera
01.04.2009 20:51:38 com.jme.renderer.AbstractCamera <init>
INFO: Camera created.
01.04.2009 20:51:38 com.jme.renderer.lwjgl.LWJGLTextureRenderer setupTexture
INFO: setup fbo tex with id 8: 200,150
01.04.2009 20:51:38 com.jme.renderer.lwjgl.LWJGLTextureRenderer setupTexture
INFO: setup fbo tex with id 9: 200,150
01.04.2009 20:51:38 com.jme.renderer.lwjgl.LWJGLTextureRenderer setupTexture
INFO: setup fbo tex with id 10: 200,150
01.04.2009 20:51:38 com.jmex.effects.water.WaterRenderPass reloadShader
INFO: Shader reloaded...
01.04.2009 20:51:38 com.jme.scene.Node attachChild
INFO: Child (waterQuad) attached to this node (rootNode)
01.04.2009 20:51:38 class prototyp1.TestIsland start()
SCHWERWIEGEND: Exception in game loop
java.lang.NullPointerException
   at com.jme.scene.Node.findCollisions(Node.java:563)
   at com.jme.scene.Spatial.calculateCollisions(Spatial.java:726)
   at prototyp1.TestIsland.update(TestIsland.java:438)
   at com.jme.app.BaseGame.start(BaseGame.java:79)
   at prototyp1.TestIsland.main(TestIsland.java:124)
01.04.2009 20:51:38 com.jme.app.BaseGame start
INFO: Application ending.

I am using eclipse!



A brakepoint says:  update (float)

Try updating your model bounds after attaching all your nodes.



Also, open up Node.java and go to line 563:

at com.jme.scene.Node.findCollisions(Node.java:563)

What is that specific line of code doing?

Node.java says:


   if (getWorldBound() != null && isCollidable && scene.isCollidable()) {



Here is the whole method!

 public void findCollisions(Spatial scene, CollisionResults results) {
        if (getWorldBound() != null && isCollidable && scene.isCollidable()) {
            if (getWorldBound().intersects(scene.getWorldBound())) {
                // further checking needed.
                for (int i = 0; i < getQuantity(); i++) {
                    getChild(i).findCollisions(scene, results);
                }
            }
        }


Looks to me like the scene parameter is null. Put your breakpoint on that line and when eclipse stops there, hover over scene. If its null, then that's your problem, your node 'n' is null at that point.



Paste your whole class if you don't get it figured out.

Did not figure it out yet… still trying :wink:



So here is the code:



public class TestIsland extends BaseGame {
           private Surfboard player;
           private CollisionResults results;
           private float agl;
           private Node rootNode, n;
           //.....
}



@Override
   protected void initGame() {
      pManager = new BasicPassManager();
      rootNode = new Node( "rootNode" );

        ZBufferState buf = display.getRenderer().createZBufferState();
        buf.setEnabled( true );
        buf.setFunction( ZBufferState.CF_LEQUAL );
        rootNode.setRenderState( buf );

        PointLight light = new PointLight();
        light.setDiffuse( new ColorRGBA( 0.75f, 0.75f, 0.75f, 0.75f ) );
        light.setAmbient( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1.0f ) );
        light.setLocation( new Vector3f( 100, 100, 100 ) );
        light.setEnabled( true );

        lightState = display.getRenderer().createLightState();
        lightState.setEnabled( true );
        lightState.attach( light );
        rootNode.setRenderState( lightState );

        timer.reset();
       
        cam.setFrustumPerspective( 45.0f, (float) display.getWidth() / (float) display.getHeight(), 1f, farPlane );
      cam.setLocation( new Vector3f( 100, 50, 100 ) );
      cam.lookAt( new Vector3f( 0, 0, 0 ), Vector3f.UNIT_Y );
      cam.update();

      setupKeyBindings();

      setupFog();
      buildTerrain();
      buildPlayer();
      buildInput();
      buildChaseCamera();
      buildSphere();
      
      Node reflectedNode = new Node( "reflectNode" );

      buildSkyBox();
      reflectedNode.attachChild( skybox );
      rootNode.attachChild( reflectedNode );

      waterEffectRenderPass = new WaterRenderPass( cam, 4, false, true );
      waterEffectRenderPass.setWaterPlane( new Plane( new Vector3f( 0.0f, 1.0f, 0.0f ), 0.0f ) );

      waterQuad = new Quad( "waterQuad", 1, 1 );
      FloatBuffer normBuf = waterQuad.getNormalBuffer( 0 );
      normBuf.clear();
      normBuf.put( 0 ).put( 1 ).put( 0 );
      normBuf.put( 0 ).put( 1 ).put( 0 );
      normBuf.put( 0 ).put( 1 ).put( 0 );
      normBuf.put( 0 ).put( 1 ).put( 0 );

      waterEffectRenderPass.setWaterEffectOnSpatial( waterQuad );
      rootNode.attachChild( waterQuad );

      waterEffectRenderPass.setReflectedScene( reflectedNode );
      waterEffectRenderPass.setSkybox( skybox );
      pManager.add( waterEffectRenderPass );

      RenderPass rootPass = new RenderPass();
      rootPass.add( rootNode );
      pManager.add( rootPass );

      rootNode.setCullMode( SceneElement.CULL_NEVER);
      rootNode.setRenderQueueMode( Renderer.QUEUE_OPAQUE );
       
        rootNode.updateGeometricState( 0.0f, true );
        rootNode.updateRenderState();
        timer.reset();

        results = new BoundingCollisionResults() {
         public void processCollisions() {
            if (getNumber() > 0) {
               System.out.println("Collision: YES");
            } else {
               System.out.println("Collision: NO");
            }
         }
      };
   }



@Override
   protected void update(float interpolation) {
      timer.update();
        tpf = timer.getTimePerFrame();      
       
          Vector3f transVec2 = new Vector3f(player.getLocalTranslation());
        Vector3f heightTerrain = new Vector3f(0,0,0);
        tb.localToWorld(transVec2, heightTerrain);     
        if ( tb.getHeight(player.getLocalTranslation())  > 8.4 ){
           //System.out.println("heightTerrain.y:" +  tb.getHeight(player.getLocalTranslation()));
              player.setVelocity(-1f);
             }
        input.update( tpf );
        chaser.update(tpf);

       
     //collisions check player and sphere     
        results.clear();
        player.calculateCollisions(n, results);
       
        if(player.hasCollision(n, true)) {
         logger.info("hasCollision also reports true");
      }
              

        GameTaskQueueManager.getManager().getQueue(GameTaskQueue.UPDATE).execute();
       
        if ( KeyBindingManager.getKeyBindingManager().isValidCommand( "exit",
                false ) ) {
            finished = true;
        }
        skybox.getLocalTranslation().set( cam.getLocation() );
      skybox.updateGeometricState( 0.0f, true );

      Vector3f transVec = new Vector3f( cam.getLocation().x, waterEffectRenderPass.getWaterHeight(), cam.getLocation().z );

      setTextureCoords( 0, transVec.x, -transVec.z, textureScale );

      setVertexCoords( transVec.x, transVec.y, transVec.z );
      
      //We don't want the chase camera to go below the world, so always keep
        //it 2 units above the level.
        if(cam.getLocation().y < (tb.getHeight(cam.getLocation()))) {
            cam.getLocation().y = tb.getHeight(cam.getLocation()) ;
            cam.update();
        }
        //make sure that if the player left the level we don't crash. When we add collisions,
        //the fence will do its job and keep the player inside.
        float characterMinHeight = 0.0f + agl;
        if (!Float.isInfinite(characterMinHeight) && !Float.isNaN(characterMinHeight)) {
            player.getLocalTranslation().y = characterMinHeight;
        }
        //get the normal of the terrain at our current location. We then apply it to the up vector
        //of the player.
        tb.getSurfaceNormal(player.getLocalTranslation(), normal);
        if(normal != null) {
            player.rotateUpTo(normal);
        }
      
       
      rootNode.updateGeometricState(tpf, true);
      pManager.updatePasses(tpf);
   }




Now the buildPlayer() and buildSphere()

private void buildPlayer(){
       Spatial model = null;
           try {
               java.net.URL bikeFile = TestIsland.class.getClassLoader().getResource("data/model/bike.jme");
               BinaryImporter importer = new BinaryImporter();
               model = (Spatial)importer.load(bikeFile.openStream());
               model.setModelBound(new BoundingBox());
               model.updateModelBound();
               //scale it to be MUCH smaller than it is originally
               model.setLocalScale(.015f);
           } catch (IOException e) {
               logger
                       .throwing(this.getClass().toString(), "buildPlayer()",
                               e);
           }
          
           //set the vehicles attributes (these numbers can be thought
           //of as Unit/Second).
           player = new Surfboard("Player Node", model);
           player.setAcceleration(15);
           player.setTurnSpeed(4.5f);
           player.setWeight(25);
           player.setMaxSpeed(155);
           player.setMinSpeed(0);
           player.setLocalRotation(new Matrix3f(0,0,1.0f,0,1.0f,0,-1.0f,0,0));
           player.setLocalTranslation(new Vector3f(0,0, (float)display.getWidth()* 1.4f));
           rootNode.attachChild(player);
           rootNode.updateGeometricState(0, true);
           //we now store this initial value, because we are rotating the wheels the bounding box will
           //change each frame.
           agl = ((BoundingBox)player.getWorldBound()).yExtent;
           player.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
   }




private void buildSphere(){
      // Make a box
        Sphere s=new Sphere("My sphere",50,50,1f);
        s.setLocalScale(5f);
        s.setLocalTranslation(new Vector3f(263.75204f, 2.1998527f, 1154.8876f));
        s.setModelBound(new BoundingBox());
        s.updateModelBound();
      // Make a node and give it children
        rootNode.updateWorldBound();
        rootNode.attachChild(s); // Put it in the scene graph
   }






It must be the node n! It is built in the   buildSphere()  

In all of that I don't see where you initialize the variable 'n'; in buildSphere() you initialize 's' …

waaaaaahhhh… and that was the problem!!! Had to create the Node n in Sphere! No wonder it did not work…



Thanks for the help!