Some problems with collisions

Hi again.



Yesterday, I was trying for hours and hours to let my computer calculate if two objects collide, but I just didn't manage.

I tried it in different ways, I checked if the boundingVolumes of the two objects collide or if the objects themselves collide, but nothing worked…



I've got a model of an animated ninja with a blade. The blade is accessable without the ninja, so i gave them different boundingVolumes, a boundingBox for the ninja and a boundingCapsule for the blade.

When I watch my app, I can clearly see that the two objects DO collide, but I just don't manage that my app also notizes this…



Thats my code now, I changed it a thousand times yesterday:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;

import com.jme.app.AbstractGame;
import com.jme.app.SimpleGame;
import com.jme.bounding.*;
import com.jme.image.Texture;
import com.jme.intersection.BoundingCollisionResults;
import com.jme.intersection.CollisionResults;
import com.jme.intersection.TriangleCollisionResults;
import com.jme.light.PointLight;
import com.jme.light.SimpleLightNode;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.scene.state.TextureState;
import com.jme.util.TextureManager;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.converters.*;
import com.jmex.model.util.ModelLoader;


public class SimpleGameTut extends SimpleGame {


Node medley;
Box box1;
CollisionResults results;
public BoundingCapsule boundingBlade = new BoundingCapsule();
public BoundingBox boundingBox = new BoundingBox();


   public static void main(String[] args)
   {
   SimpleGameTut main = new SimpleGameTut();
   main.setDialogBehaviour(AbstractGame.ALWAYS_SHOW_PROPS_DIALOG);
   main.start();
   }

   protected void simpleInitGame()
   {
   results = new BoundingCollisionResults() {
public void processCollisions() {
if (getNumber() > 0) {
System.out.println("Collision: YES");
} else {
System.out.println("Collision: NO");
}
}
};
   
   // Point to a URL of my model
   URL model = ModelLoader.class.getClassLoader().getResource("ninja.ms3d");
//    URL model = ModelLoader.class.getClassLoader().getResource("mod/medley.max");
   
   // Create something to convert .max format to .jme
   FormatConverter converter = new MilkToJme();
   // Point the converter to where it will find the .mtl file from
   converter.setProperty("mtllib", model);
   
   // This byte array will hold my .jme file
   ByteArrayOutputStream BO = new ByteArrayOutputStream();

   // load and create a texture for the model
   URL texLoc;
   texLoc = ModelLoader.class.getClassLoader().getResource("nskinwh.jpg");
   TextureState tsMipMap = display.getRenderer().createTextureState();
   Texture tex = TextureManager.loadTexture( texLoc, Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
   tsMipMap.setTexture( tex );
   
   try {
   // Use the format converter to convert .max to .jme
   converter.convert(model.openStream(), BO);
   medley = (Node)BinaryImporter.getInstance().load( new ByteArrayInputStream(BO.toByteArray()));

   medley.setRenderState( tsMipMap );
   
   medley.getChild(0).setModelBound(new BoundingBox());
   medley.getChild(1).setModelBound(boundingBlade);
   medley.updateModelBound();
   // Put it on the scene graph
   rootNode.attachChild(medley);
   
   } catch (IOException e) { //Just in case anything happens
   //logger.logp(Level.SEVERE, this.getClass().toString(), "simpleInitGame()","Exception", e);
   System.exit(0);
   }
   /*
       // I will rotate this pivot to move my light
       Node pivot=new Node("Pivot node");

       // This light will rotate around my sphere.  Notice I don't give it a position
       PointLight pl=new PointLight();
       // Color the light red
       pl.setDiffuse(ColorRGBA.yellow.clone());
       // Enable the light
       pl.setEnabled(true);
       // Remove the default light and attach this one
   lightState.detachAll();
   lightState.attach(pl);
   
       // This node will hold my light
   SimpleLightNode ln=new SimpleLightNode("A node for my pointLight",pl);
       // I set the light's position thru the node
       ln.setLocalTranslation(new Vector3f(20,-100,30));
       // I attach the light's node to my pivot
       pivot.attachChild(ln);
       */
   
   box1 = new Box("Box1", new Vector3f(3,5,0),1,1,1);
   box1.setModelBound(boundingBox);
   box1.updateModelBound();
   rootNode.attachChild(box1);
   rootNode.updateWorldBound();
   }
   
   public void simpleUpdate() {
//    System.out.println(boundingBox.intersects(boundingBlade));
   results.clear();
   medley.getChild(1).calculateCollisions(box1, results);
   System.out.println(results.getNumber());
   if (results.getNumber() > 0) {
   System.out.println("KOLLISION");
   }
   
//    System.out.println(results.getCollisionData(0));
   }
}

Can anyone help me making a working collisionDetection?

Thanks for your help!



Edit:
Hmm, I found out that the collision detection only works when I take my whole object medley.
As soon as I want to check the collision with a child of medley, the blade, it doesn't work anymore.
But it's really important that my app knows that the blade had a collision and not the whole model!!!
Can anyone help me here please?

Have you tried using something else instead of the BoundingCapsule for collisions?  I've heard that there are some problems with it.

Wow, thanks, you're right!!

With a normal boundingBox, it works!



But there's just one big problem, I have to use a BoundingVolume, which fits better around my sword.

The boundingCapsule makes every movement the sword does and the Box just grows…

I'd need a boundingBox which has the same behaviour as a boundingCapsule.

I think this should be orientedBoundingBox, but I can't figure out any difference between this one and the normal boundingBox…