Windows EXE does not build after switching to 3.1 alpha

BoundingBox cannot be collided with BoundingBox.

I am basicly doing this:

planet.nodeCol.collideWith(null, results);

What I am saying is that the stack trace in 3.0 is different than in 3.1 and maybe that is why I get a crash on 3.1 when trying to collide a node with the bounding volume of a sphere.

I really think there is a real bug here. If this info does not help I guess I can provide a test case.

I can’t see the 3.0 stack trace so I can’t say what’s different.

Edit: missed the stack trace… sorry.

I’m not sure what collideWith(null) is supposed to do exactly… perhaps you should be passing a bounding sphere.

There is no bug here except in your code… the old code threw a different exception but they are both telling you that your passing a bad value.

The stack trace you show now looks different than the one you posted before.

But anyway, the old 3.0 code is the one with the bug because it was throwing an NPE when trying to create this exception:
throw new UnsupportedCollisionException("With: " + other.getClass().getSimpleName());

…because null.getClass() will throw an NPE.

Ok, but when I replace null with boundingVolume (of a sphere) I get an exception. (only on 3.1)

Since the sphere is probly fine, is there anything a node can contain that would it throw an exception?

You assume the bounding volume of a sphere is a sphere… that is probably a really poor assumption.

The real question is why it ever worked… as it seems to have nothing directly to do with 3.0 or 3.1.

Sphere.java has always had a BB bounding volume… in 3.0 and in 3.1. So unless you were setting a BoundingSphere yourself, it’s never had a sphere bounding volume.

Nope :smiley:

    BoundingSphere bs = new BoundingSphere(radius, p);
    CollisionResults results = new CollisionResults();        
    planet.nodeCol.collideWith(bs, results);

Sep 09, 2015 11:44:52 AM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
com.jme3.collision.UnsupportedCollisionException: With: BoundingSphere
at com.jme3.bounding.BoundingBox.collideWith(BoundingBox.java:822)
at com.jme3.scene.Node.collideWith(Node.java:579)
at game.planetPack.Collision.checkObjMapForCollision(Collision.java:280)
at game.player.PlayerCollisions.handleCollisions(PlayerCollisions.java:33)
at game.player.PlayerMovement.moveCamera(PlayerMovement.java:120)
at game.input.Keyboard$1.onAnalog(Keyboard.java:132)

Why is node being replaced with a bounding box?

I’m kind of tired of playing the code shell game here as it feels like it keeps moving underneath me.

Please find some code that actually worked in 3.0 and verify that it worked in 3.0 and then post that. Then we’ll have something to talk about.

There may have been some path that changed but it’s hard to tell because none of the code seems to have ever supported bounding spheres (so I was wrong about that I guess). The utility of such a case is so extremely limited that I’m not even sure it would be worth adding.

One thing to look into is the BIHTree early exclusion stuff. Maybe something in the simpler intersection tests has changed. (Like not the stuff that actually does collision but the stuff to see if it should even take some branch of the BIHTree.)

See, I remember spheres working against regular meshes but I don’t remember if I’m hitting those meshes directly or doing collideWith(). I added code to do proper sphere->triangle collisions at some point and it would be a shame if it isn’t being used just because some simpler check was needlessly dumbed down.

I narrowed it down, I will post a testcase in a few min

You are right on, problem is when putting custom model in the node

Here goes, I made a test app for 3.1

Walk forward and see the sphere you are holding change color if it hits the box infront of you.

At start, the custom model is not loaded.

Just take the // off of:

//coll.attachChild(model);

And you will get the exception.

If you create a new project in 3.0 and add assets and Main.java to it , it will work fine.

Get the 1.5Mb project here:

CollisonFailTest

https://onedrive.live.com/redir?resid=1D410909D7B5BFF0!1008

So… Did you check it out? would you like me to create a new topic for this?

I don’t really have time to debug both code trees right now… but since you have both setup you could step through each and see what has changed a thousand times easier than I could.

There were some “optimizations” to the collision stuff in 3.1… you could also try checking out a version before those changes were made and see if the issue is still there.

um… do I need to download sourcecode of jme3 and jme3.1 for that? Cuz when I go down the tree it shows compiled code

Pretty sure that the SDK includes the JME source code. I’ve never used the debugger so I don’t really know how to set it up.

Good news! I found something easy for you to check!

Starting from goto decleration of: Node.collideWith(BoundingVolume, CollisionResults);

3.0

public int collideWith(Collidable other, CollisionResults results){
    int total = 0;
    for (Spatial child : children.getArray()){
        total += child.collideWith(other, results);
    }
    return total;
}

3.1

public int collideWith(Collidable other, CollisionResults results){
    int total = 0;
    
    // optimization: try collideWith BoundingVolume to avoid possibly redundant tests on children
    // number 4 in condition is somewhat arbitrary. When there is only one child, the boundingVolume test is redundant at all. 
    // The idea is when there are few children, it can be too expensive to test boundingVolume first.
    if (children.size() > 4)
    {
      BoundingVolume bv = this.getWorldBound();
      if (bv==null) return 0;

      // collideWith without CollisionResults parameter used to avoid allocation when possible
      if (bv.collideWith(other) == 0) return 0;
    }
    for (Spatial child : children.getArray()){
        total += child.collideWith(other, results);
    }
    return total;
}

Notice the “if (children.size() > 4)”

I redid the testcase WITHOUT my costom model, only boxes and spheres

If that node has more then 3 children the Exception gets thrown regardless, which is what would happen with this code in there:

BoundingVolume bv = this.getWorldBound();
  if (bv==null) return 0;

  // collideWith without CollisionResults parameter used to avoid allocation when possible
  if (bv.collideWith(other) == 0) return 0;

And THAT explains the UnsupportedCollisionException: With: BoundingBox, there is clearly a bounding volume colliding another bounding volume which mean this “optimisation” was not tested.

I want to replace

if (children.size() > 4)
{
  BoundingVolume bv = this.getWorldBound();
  if (bv==null) return 0;

  // collideWith without CollisionResults parameter used to avoid allocation when possible
  if (bv.collideWith(other) == 0) return 0;
}

with

and it should work fine but when I open the jar I get “Compile Code” and I don’t feel like downloading the source.

Could you please make the modification, run .Main below (no assets needed) and see if it works?

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.bounding.BoundingVolume;
import com.jme3.collision.CollisionResults;
import com.jme3.light.AmbientLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;

/**
 * test
 * @author Eric Bourque
 */
public class Main extends SimpleApplication {

public static void main(String[] args) {
    Main app = new Main();
    app.start();
}

Node coll = new Node();

//Nb of boxes. Exception is not thrown if < 4
final int nBoxes = 4;    

@Override
public void simpleInitApp() {       
    
    AmbientLight am = new AmbientLight();
    rootNode.addLight(am);
    
    Mesh mesh2 = new Sphere(10, 10, 0.5f);
    Geometry geom2 = new Geometry("TestCol", mesh2);
    Material m2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    m2.setColor("Color", ColorRGBA.Gray);
    geom2.setMaterial(m2);        
    coll.attachChild(geom2); 
    
    rootNode.attachChild(coll);       
    
    for(int i = 0; i < nBoxes ; i++){
        Mesh meshx = new Box(1, 1, 1);
        Geometry geomx = new Geometry("Box"+String.valueOf(i), meshx);
        geomx.setLocalTranslation(i*3,1,5);
        Material mx = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mx.setColor("Color", ColorRGBA.LightGray);
        geomx.setMaterial(mx);
        coll.attachChild(geomx); 
    }
    
}

@Override
public void simpleUpdate(float tpf) {
    
    Geometry g = (Geometry)coll.getChild("TestCol");
    g.setLocalTranslation(super.cam.getLocation().add(super.cam.getDirection().mult(3)));
    
    BoundingVolume bv = g.getWorldBound();           
    
    CollisionResults results = new CollisionResults();  
    //System.out.println(coll.getChildren().size());
    coll.collideWith(bv, results);     
    
    if (results.size() > 0) {
        String collName = results.getFarthestCollision().getGeometry().getName();
        System.out.println(collName);
        Geometry box = (Geometry)coll.getChild(collName);
        if(collName.contains("Box")){                
            box.getMaterial().setColor("Color", ColorRGBA.Red);
        }else{
            for(int i = 0; i < nBoxes ; i++){
                box = (Geometry)coll.getChild("Box"+String.valueOf(i));
                box.getMaterial().setColor("Color", ColorRGBA.Blue);
            }           
        }
    }        
}

@Override
public void simpleRender(RenderManager rm) {
    //TODO: add render code
}

}

1 Like

Edit:

I download the source. How can I convert the Node.java to Node.class ?

You check out the source code from github… then you run gradlew dist or whatever. There are instructions around somewhere I think.

If you check it out from github then it’s nicer because then you can send a pull request for your change.

Personally, I don’t mind removing that code as it’s always been a bit wonky. I understand the idea but it was implemented poorly (like why do a full collideWith() when an intersects() would do?) And perhaps even intersects() wouldn’t have the issue.

The funny thing is that other strange changes were made to optimize this “collideWith when I mean intersect” change and those should probably also be suspect as well.

I did the pull request

Hope someone improves it :chimpanzee_closedlaugh:

Edit: Oups, did that all worng. I tried again…