OSDN Git Service

Generalization of collision booleans to bitmasks
authorblaine.dev <blaine.dev@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Sat, 29 Aug 2009 02:28:57 +0000 (02:28 +0000)
committerblaine.dev <blaine.dev@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Sat, 29 Aug 2009 02:28:57 +0000 (02:28 +0000)
git-svn-id: http://jmonkeyengine.googlecode.com/svn/trunk@4640 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

17 files changed:
junit/com/jme/scene/CollisionMaskTest.java [new file with mode: 0644]
src/com/jme/curve/BezierCurve.java
src/com/jme/curve/CatmullRomCurve.java
src/com/jme/curve/PolylineCurve.java
src/com/jme/scene/Geometry.java
src/com/jme/scene/Line.java
src/com/jme/scene/MorphingTriMesh.java
src/com/jme/scene/Node.java
src/com/jme/scene/Point.java
src/com/jme/scene/QuadMesh.java
src/com/jme/scene/SharedMesh.java
src/com/jme/scene/Spatial.java
src/com/jme/scene/SwitchNode.java
src/com/jme/scene/Text.java
src/com/jme/scene/TriMesh.java
src/com/jmex/effects/particles/ParticleLines.java
src/com/jmex/model/ogrexml/MeshCloner.java

diff --git a/junit/com/jme/scene/CollisionMaskTest.java b/junit/com/jme/scene/CollisionMaskTest.java
new file mode 100644 (file)
index 0000000..2cec460
--- /dev/null
@@ -0,0 +1,115 @@
+package com.jme.scene;
+
+import com.jme.scene.shape.Sphere;
+import com.jme.bounding.BoundingSphere;
+import static org.junit.Assert.*;
+
+/**
+ * @author Blaine Simpson (blaine dot simpson at admc dot com)
+ */
+public class CollisionMaskTest {
+    public CollisionMaskTest() {}
+
+    protected Node n;
+    protected Sphere a, b, c;
+
+    @org.junit.Before
+    public void setupScene() {
+        a = new Sphere("a", 8, 8, 1f);
+    /*
+     * Disabling this because the Bounding volumes never get initialized
+     * correctly.
+     * I must be missing something very obvious, because the
+     * updateGeometricState call below should do everything that's needed
+     * (since I previously allocated the Bounding* objects).
+        b = new Sphere("b", 8, 8, 1f);
+        c = new Sphere("c", 8, 8, 1f);
+        //a.setModelBound(new BoundingSphere());
+        //b.setModelBound(new BoundingSphere());
+        //c.setModelBound(new BoundingSphere());
+        b.getLocalTranslation().setX(.1f);
+        c.getLocalTranslation().setX(20f);
+        n = new Node("n");
+        n.attachChild(a);
+        n.attachChild(b);
+        n.attachChild(c);
+        n.setModelBound(new BoundingSphere());
+        //a.updateWorldBound();
+        //b.updateWorldBound();
+        //c.updateWorldBound();
+        n.updateGeometricState(0, true);
+        System.err.println("BOunds of a = " + a.getWorldBound());
+    }
+
+    /*
+    @org.junit.After
+    public void cleanupScene() {
+        a.removeFromParent();
+        b.removeFromParent();
+        c.removeFromParent();
+        a = b = c = null;
+        n = null;
+    */
+    }
+
+    @org.junit.Test
+    public void bitOps() {
+        a.setCollisionMask(-1);
+        assertTrue(a.isCollidable(0));
+        a.setCollisionMask(0);
+        assertTrue(a.isCollidable(0));
+        assertFalse(a.isCollidable(-1));
+        a.setCollisionMask(9999);
+        assertFalse(a.isCollidable(-1));
+        a.setCollisionMask(-9999);
+        assertFalse(a.isCollidable(-1));
+        a.setCollisionMask(10);
+        assertTrue(a.isCollidable(10));
+        a.setCollisionMask(11);
+        assertTrue(a.isCollidable(10));
+        a.setCollisionMask(10);
+        assertFalse(a.isCollidable(11));
+    }
+
+    /*
+    See comment in the 'setupScene' method above.
+    @org.junit.Test
+    public void geoGeoCollisions() {
+        // Use requiredOnBits of 0 to just test whether the Spatials touch
+        assertTrue(a.hasCollision(b, false, 0));
+        assertTrue(b.hasCollision(a, false, 0));
+        assertFalse(a.hasCollision(c, false, 0));
+        assertFalse(c.hasCollision(b, false, 0));
+        assertFalse(b.hasCollision(c, false, 0));
+        assertFalse(c.hasCollision(a, false, 0));
+
+        // These should all fail because a does not have 2 in its bit mask.
+        b.setCollisionMask(3);
+        c.setCollisionMask(-1);
+        assertFalse(a.hasCollision(b, false, 2));
+        assertFalse(b.hasCollision(a, false, 2));
+        assertFalse(a.hasCollision(c, false, 2));
+        assertFalse(c.hasCollision(b, false, 2));
+        assertFalse(b.hasCollision(c, false, 2));
+        assertFalse(c.hasCollision(a, false, 2));
+
+        // Flip on the needed 2 bit for a.
+        a.setCollisionMask(2);
+        assertTrue(a.hasCollision(b, false, 2));
+        assertTrue(b.hasCollision(a, false, 2));
+        assertFalse(a.hasCollision(c, false, 2));
+        assertFalse(c.hasCollision(b, false, 2));
+        assertFalse(b.hasCollision(c, false, 2));
+        assertFalse(c.hasCollision(a, false, 2));
+
+        // Turn up a couple more bits too.
+        a.setCollisionMask(10);
+        assertTrue(a.hasCollision(b, false, 2));
+        assertTrue(b.hasCollision(a, false, 2));
+        assertFalse(a.hasCollision(c, false, 2));
+        assertFalse(c.hasCollision(b, false, 2));
+        assertFalse(b.hasCollision(c, false, 2));
+        assertFalse(c.hasCollision(a, false, 2));
+    }
+    */
+}
index a641308..8e827fd 100644 (file)
@@ -216,19 +216,21 @@ public class BezierCurve extends Curve {
         * @see com.jme.scene.Spatial#hasCollision(com.jme.scene.Spatial,
         *      com.jme.intersection.CollisionResults)
         */
-       public void findCollisions(Spatial scene, CollisionResults results) {
+       public void findCollisions(
+            Spatial scene, CollisionResults results, int requiredOnBits) {
                // TODO Auto-generated method stub
 
        }
        
-       public boolean hasCollision(Spatial scene, boolean checkTriangles) {
+       public boolean hasCollision(
+            Spatial scene, boolean checkTriangles, int requiredOnBits) {
                return false;
        }
 
        /* (non-Javadoc)
         * @see com.jme.scene.Spatial#doPick(com.jme.math.Ray, com.jme.intersection.PickResults)
         */
-       public void findPick(Ray toTest, PickResults results) {
+       public void findPick(Ray toTest, PickResults results, int requiredOnBits) {
                // TODO Auto-generated method stub
                
        }
index a3bd4fc..045a633 100644 (file)
@@ -262,7 +262,8 @@ public class CatmullRomCurve extends Curve {
         * com.jme.intersection.CollisionResults)
         */
        @Override
-       public void findCollisions(Spatial scene, CollisionResults results) {
+       public void findCollisions(
+            Spatial scene, CollisionResults results, int requiredOnBits) {
        } // findCollisions
 
 
@@ -272,7 +273,8 @@ public class CatmullRomCurve extends Curve {
         * @see com.jme.scene.Spatial#hasCollision(com.jme.scene.Spatial, boolean)
         */
        @Override
-       public boolean hasCollision(Spatial scene, boolean checkTriangles) {
+       public boolean hasCollision(
+            Spatial scene, boolean checkTriangles, int requiredOnBits) {
                return false;
        }
 
@@ -284,7 +286,8 @@ public class CatmullRomCurve extends Curve {
         * com.jme.intersection.PickResults)
         */
        @Override
-       public void findPick(Ray toTest, PickResults results) {
+       public void findPick(
+            Ray toTest, PickResults results, int requiredOnBits) {
 
        } // findPick
 } // CatmullRomCurve
index e5fc1ab..6bfc449 100644 (file)
@@ -185,13 +185,15 @@ public class PolylineCurve extends Curve {
 
 
   @Override
-  public void findCollisions(Spatial scene, CollisionResults results) {
+  public void findCollisions(
+          Spatial scene, CollisionResults results, int requiredOnBits) {
     // TODO Auto-generated method stub
   }
 
 
   @Override
-  public boolean hasCollision(Spatial scene, boolean checkTriangles) {
+  public boolean hasCollision(
+          Spatial scene, boolean checkTriangles, int requiredOnBits) {
     // TODO Auto-generated method stub
     return false;
   }
@@ -202,7 +204,8 @@ public class PolylineCurve extends Curve {
    * 
    * @see com.jme.scene.Spatial#doPick(com.jme.math.Ray, com.jme.intersection.PickResults)
    */
-  public void findPick(Ray toTest, PickResults results) {
+  public void findPick(
+          Ray toTest, PickResults results, int requiredOnBits) {
     // TODO Auto-generated method stub
 
   }
index 842d911..e6b09f3 100644 (file)
@@ -634,15 +634,16 @@ public abstract class Geometry extends Spatial implements Serializable, Savable
     /**
      * Check if this geometry intersects the ray if yes add it to the results.
      * 
-     * @param ray
-     *            ray to check intersection with. The direction of the ray must
+     * @param ray ray to check intersection with. The direction of the ray must
      *            be normalized (length 1).
+     * @param requiredOnBits Collision will only be considered if 'this'
+     *        has these bits of its collision mask set.
      * @param results
      *            result list
      */
     @Override
-    public void findPick(Ray ray, PickResults results) {
-        if (getWorldBound() == null || !isCollidable()) {
+    public void findPick(Ray ray, PickResults results, int requiredOnBits) {
+        if (getWorldBound() == null || !isCollidable(requiredOnBits)) {
             return;
         }
         if (getWorldBound().intersects(ray)) {
index 9b94c7f..6fca16d 100644 (file)
@@ -201,7 +201,8 @@ public class Line extends Geometry {
      * @see com.jme.scene.Spatial#hasCollision(com.jme.scene.Spatial,
      *      com.jme.intersection.CollisionResults)
      */
-    public void findCollisions(Spatial scene, CollisionResults results) {
+    public void findCollisions(
+            Spatial scene, CollisionResults results, int requiredOnBits) {
         // unsupported
     }
 
@@ -210,7 +211,8 @@ public class Line extends Geometry {
      * 
      * @return always false for lines
      */
-    public boolean hasCollision(Spatial scene, boolean checkTriangles) {
+    public boolean hasCollision(
+            Spatial scene, boolean checkTriangles, int requiredOnBits) {
         return false;
     }
 
index e22ed60..a82b7d8 100644 (file)
@@ -269,7 +269,7 @@ public class MorphingTriMesh extends TriMesh implements MorphingGeometry {
         setLightCombineMode(base.getLocalLightCombineMode());
         setRenderQueueMode(base.getRenderQueueMode());
         setNormalsMode(base.getLocalNormalsMode());
-        setIsCollidable(base.isCollidable());
+        setCollisionMask(base.getCollisionMask());
         setRenderQueueMode(base.getLocalRenderQueueMode());
         for (RenderState.StateType rsType : RenderState.StateType.values()) {
             clearRenderState(rsType);
index 771cf93..b9b44dd 100644 (file)
@@ -86,6 +86,10 @@ public class Node extends Spatial implements Serializable, Savable {
      */
     public Node(String name) {
         super(name);
+        setCollisionMask(-1);
+        // Newly constitued (not reconsituted) Nodes should allow for maximum
+        // collision nesting.  If anything other than -1, the node would block
+        // collisions for all descendant Spatials.
         logger.info("Node created.");
     }
 
@@ -578,28 +582,33 @@ public class Node extends Spatial implements Serializable, Savable {
     }
 
     @Override
-    public void findCollisions(Spatial scene, CollisionResults results) {
-        if (getWorldBound() != null && isCollidable() && scene.isCollidable()) {
+    public void findCollisions(
+            Spatial scene, CollisionResults results, int requiredOnBits) {
+        if (getWorldBound() != null && isCollidable(requiredOnBits)
+                && scene.isCollidable(requiredOnBits)) {
             if (getWorldBound().intersects(scene.getWorldBound())) {
                 // further checking needed.
                 for (int i = 0; i < getQuantity(); i++) {
-                    getChild(i).findCollisions(scene, results);
+                    getChild(i).findCollisions(scene, results, requiredOnBits);
                 }
             }
         }
     }
 
     @Override
-    public boolean hasCollision(Spatial scene, boolean checkTriangles) {
+    public boolean hasCollision(
+            Spatial scene, boolean checkTriangles, int requiredOnBits) {
         if (this == scene) return false;  // No Collision with "self"
-        if (getWorldBound() != null && isCollidable() && scene.isCollidable()) {
+        if (getWorldBound() != null && isCollidable(requiredOnBits)
+                && scene.isCollidable(requiredOnBits)) {
             if (getWorldBound().intersects(scene.getWorldBound())) {
                 if(children == null && !checkTriangles) {
                     return true;
                 }
                 // further checking needed.
                 for (int i = 0; i < getQuantity(); i++) {
-                    if (getChild(i).hasCollision(scene, checkTriangles)) {
+                    if (getChild(i).hasCollision(
+                            scene, checkTriangles, requiredOnBits)) {
                         return true;
                     }
                 }
@@ -610,11 +619,11 @@ public class Node extends Spatial implements Serializable, Savable {
     }
 
     @Override
-    public void findPick(Ray toTest, PickResults results) {
+    public void findPick(Ray toTest, PickResults results, int requiredOnBits) {
         if(children == null) {
             return;
         }
-        if (getWorldBound() != null && isCollidable()) {
+        if (getWorldBound() != null && isCollidable(requiredOnBits)) {
             if (getWorldBound().intersects(toTest)) {
                 // further checking needed.
                 for (int i = 0; i < getQuantity(); i++) {
index 8556c5b..9a86476 100644 (file)
@@ -145,11 +145,13 @@ public class Point extends Geometry {
         * @see com.jme.scene.Spatial#hasCollision(com.jme.scene.Spatial,
         *      com.jme.intersection.CollisionResults)
         */
-       public void findCollisions(Spatial scene, CollisionResults results) {
+       public void findCollisions(
+            Spatial scene, CollisionResults results, int requiredOnBits) {
                ; // unsupported
        }
        
-       public boolean hasCollision(Spatial scene, boolean checkTriangles) {
+       public boolean hasCollision(
+            Spatial scene, boolean checkTriangles, int requiredOnBits) {
                return false;
        }
 
index a20ca5b..d4e1b5f 100644 (file)
@@ -379,12 +379,14 @@ public class QuadMesh extends Geometry implements Serializable {
     }
 
     @Override
-    public void findCollisions(Spatial scene, CollisionResults results) {
+    public void findCollisions(
+            Spatial scene, CollisionResults results, int requiredOnBits) {
         ; // unsupported
     }
 
     @Override
-    public boolean hasCollision(Spatial scene, boolean checkTriangles) {
+    public boolean hasCollision(
+            Spatial scene, boolean checkTriangles, int requiredOnBits) {
         return false;
     }
 }
index 18f253b..8fc2949 100644 (file)
@@ -449,17 +449,18 @@ public class SharedMesh extends TriMesh {
      * This function checks for intersection between the target trimesh and the
      * given one. On the first intersection, true is returned.
      * 
-     * @param toCheck
-     *            The intersection testing mesh.
+     * @param toCheck The intersection testing mesh.
+     * @param requiredOnBits Collision will only be considered if both 'this'
+     *        and 'toCheck' have these bits of their collision masks set.
      * @return True if they intersect.
      */
     @Override
-    public boolean hasTriangleCollision(TriMesh toCheck) {
+    public boolean hasTriangleCollision(TriMesh toCheck, int requiredOnBits) {
         target.setLocalTranslation(worldTranslation);
         target.setLocalRotation(worldRotation);
         target.setLocalScale(worldScale);
         target.updateWorldBound();
-        return target.hasTriangleCollision(toCheck);
+        return target.hasTriangleCollision(toCheck, requiredOnBits);
     }
 
     /**
index 8bcf88c..76d763e 100644 (file)
@@ -916,16 +916,29 @@ public abstract class Spatial implements Serializable, Savable {
     }
 
     /**
+     * Convenience wrapper for
+     * calculateCollisions(Spatial, CollisionResults, int) using default
+     * collidability (first bit of the collidable bit mask).
+     *
+     * @see #calculateCollisions(Spatial, CollisionResults, int)
+     */
+    final public void calculateCollisions(
+            Spatial scene, CollisionResults results) {
+        calculateCollisions(scene, results, 1);
+    }
+
+    /**
      * <code>calculateCollisions</code> calls findCollisions to populate the
      * CollisionResults object then processes the collision results.
      * 
-     * @param scene
-     *            the scene to test against.
-     * @param results
-     *            the results object.
+     * @param scene the scene to test against.
+     * @param results the results object.
+     * @param requiredOnBits considered a collision only if these bits are 'on'
+     *    in both 'this' and the 'scene' spatial.
      */
-    public void calculateCollisions(Spatial scene, CollisionResults results) {
-        findCollisions(scene, results);
+    final public void calculateCollisions(
+            Spatial scene, CollisionResults results, int requiredOnBits) {
+        findCollisions(scene, results, requiredOnBits);
         results.processCollisions();
     }
 
@@ -944,42 +957,94 @@ public abstract class Spatial implements Serializable, Savable {
     public abstract void setModelBound(BoundingVolume modelBound);
 
     /**
+     * Convenience wrapper for
+     * findCollisions(Spatial, CollisionResults, int) using default
+     * collidability (first bit of the collidable bit mask).
+     *
+     * @see #findCollisions(Spatial, CollisionResults, int)
+     */
+    final public void findCollisions(Spatial scene, CollisionResults results) {
+        findCollisions(scene, results, 1);
+    }
+
+    /**
      * checks this spatial against a second spatial, any collisions are stored
      * in the results object.
      * 
-     * @param scene
-     *            the scene to test against.
-     * @param results
-     *            the results of the collisions.
+     * @param scene the scene to test against.
+     * @param results the results of the collisions.
+     * @param requiredOnBits considered a collision only if these bits are 'on'
+     *    in both 'this' and the 'scene' spatial.
      */
-    public abstract void findCollisions(Spatial scene, CollisionResults results);
+    public abstract void findCollisions(
+            Spatial scene, CollisionResults results, int requiredOnBits);
+
+    /**
+     * Convenience wrapper for
+     * hasCollision(Spatial, CollisionResults, int) using default
+     * collidability (first bit of the collidable bit mask).
+     *
+     * @see #hasCollisionsSpatial, CollisionResults, boolean)
+     */
+    final public boolean hasCollision(Spatial scene, boolean checkTriangles) {
+        return hasCollision(scene, checkTriangles, 1);
+    }
 
     /**
      * Checks this spatial against a second spatial for collisions.
      * 
-     * @param scene
-     *            the scene to test against.
-     * @param checkTriangles
-     *            check for collisions on triangle accuracy level
+     * @param scene the scene to test against.
+     * @param checkTriangles check for collisions on triangle accuracy level
+     * @param requiredOnBits considered a collision only if these bits are 'on'
+     *    in both 'this' and the 'scene' spatial.
      * @return true if any collision were found
      */
-    public abstract boolean hasCollision(Spatial scene, boolean checkTriangles);
+    public abstract boolean hasCollision(
+            Spatial scene, boolean checkTriangles, int requiredOnBits);
 
-    public void calculatePick(Ray ray, PickResults results) {
-        findPick(ray, results);
+    /**
+     * Convenience wrapper for
+     * calculatePick(Ray, PickResults, int) using default
+     * collidability (first bit of the collidable bit mask).
+     *
+     * @see #calculatePick(Ray, PickResults, int)
+     */
+    final public void calculatePick(Ray ray, PickResults results) {
+        calculatePick(ray, results, 1);
+    }
+
+    /**
+     * @param requiredOnBits considered a collision only if these bits are 'on'
+     *    in 'this' spatial.
+     */
+    final public void calculatePick(
+            Ray ray, PickResults results, int requiredOnBits) {
+        findPick(ray, results, requiredOnBits);
         results.processPick();
     }
 
     /**
+     * Convenience wrapper for
+     * findPick(Ray, PickResults, int) using default
+     * collidability (first bit of the collidable bit mask).
+     *
+     * @see #findPick(Ray, PickResults, int)
+     */
+    final public void findPick(Ray toTest, PickResults results) {
+        findPick(toTest, results, 1);
+    }
+
+    /**
      * Tests a ray against this spatial, and stores the results in the result
      * object.
      * 
-     * @param toTest
-     *            ray to test picking against
-     * @param results
-     *            the results of the picking
+     * @param toTest ray to test picking against
+     * @param results the results of the picking
+     * @param requiredOnBits considered a collision only if these bits are 'on'
+     *    in 'this' spatial.
      */
-    public abstract void findPick(Ray toTest, PickResults results);
+    public abstract void findPick(
+            Ray toTest, PickResults results, int requiredOnBits);
 
     /**
      * Stores user define data for this Spatial.
@@ -1130,6 +1195,14 @@ public abstract class Spatial implements Serializable, Savable {
         return name;
     }
 
+    public void setCollisionMask(int collisionBits) {
+        this.collisionBits = collisionBits;
+    }
+
+    public int getCollisionMask() {
+        return collisionBits;
+    }
+
     /**
      * Sets if this Spatial is to be used in intersection (collision and
      * picking) calculations. By default this is true.
@@ -1154,7 +1227,14 @@ public abstract class Spatial implements Serializable, Savable {
      *         false otherwise.
      */
     public boolean isCollidable() {
-        return (collisionBits & 1) != 0;
+        return isCollidable(1);
+    }
+
+    /**
+     * @returns true if this Spatial matches all set bits in the specified value
+     */
+    public boolean isCollidable(int requiredOnBits) {
+        return ((requiredOnBits & collisionBits) ^ requiredOnBits) == 0;
     }
 
     /**
index fefb9c5..979330f 100644 (file)
@@ -100,11 +100,11 @@ public class SwitchNode extends Node {
                        activeChild = SN_INVALID_CHILD;
                } else {
             if(activeChildData != null) {
-                activeChildData.setIsCollidable(false);
+                activeChildData.setCollisionMask(0);
             }
             this.activeChild = child;
                        activeChildData = getChild(activeChild);
-            activeChildData.setIsCollidable(true);
+            activeChildData.setCollisionMask(getCollisionMask());
                }
    }
 
@@ -123,7 +123,7 @@ public class SwitchNode extends Node {
      */
     @Override
     public int attachChild(Spatial child) {
-        child.setIsCollidable(false);
+        child.setCollisionMask(0);
         return super.attachChild(child);
     }
     
@@ -135,7 +135,7 @@ public class SwitchNode extends Node {
      */
     @Override
     public int attachChildAt(Spatial child, int index) {
-        child.setIsCollidable(false);
+        child.setCollisionMask(0);
         return super.attachChildAt(child, index);
     }
 
@@ -159,14 +159,16 @@ public class SwitchNode extends Node {
      * collisions are checked for the currently active child.
      */
     @Override
-    public void findCollisions(Spatial scene, CollisionResults results) {
-        if (this == scene || !isCollidable() || !scene.isCollidable()) {
+    public void findCollisions(
+            Spatial scene, CollisionResults results, int requiredOnBits) {
+        if (this == scene || !isCollidable(requiredOnBits)
+                || !scene.isCollidable(requiredOnBits)) {
             return;
         }
 
         if (activeChild != SN_INVALID_CHILD) {
             if (activeChildData != null) {
-                activeChildData.findCollisions(scene, results);
+                activeChildData.findCollisions(scene, results, requiredOnBits);
             }
         }
     }
@@ -175,23 +177,26 @@ public class SwitchNode extends Node {
      * collisions are checked for the currently active child.
      */
     @Override
-    public boolean hasCollision(Spatial scene, boolean checkTriangles) {
-        if (this == scene || !isCollidable() || !scene.isCollidable()) {
+    public boolean hasCollision(
+            Spatial scene, boolean checkTriangles, int requiredOnBits) {
+        if (this == scene || !isCollidable(requiredOnBits)
+                || !scene.isCollidable(requiredOnBits)) {
             return false;
         }
 
         if (activeChild != SN_INVALID_CHILD) {
             if (activeChildData != null) {
-                return activeChildData.hasCollision(scene, checkTriangles);
+                return activeChildData.hasCollision(
+                        scene, checkTriangles, requiredOnBits);
             }
         }
         return false;
     }
     
-    public void findPick(Ray toTest, PickResults results) {
+    public void findPick(Ray toTest, PickResults results, int requiredOnBits) {
         if (activeChild != SN_INVALID_CHILD) {
             if (activeChildData != null) {
-                activeChildData.findPick(toTest, results);
+                activeChildData.findPick(toTest, results, requiredOnBits);
             }
         }
     }
index 42a1bd3..79f578a 100644 (file)
@@ -163,11 +163,13 @@ public class Text extends Geometry {
      * @see com.jme.scene.Spatial#hasCollision(com.jme.scene.Spatial,
      *      com.jme.intersection.CollisionResults)
      */
-    public void findCollisions(Spatial scene, CollisionResults results) {
+    public void findCollisions(
+            Spatial scene, CollisionResults results, int requiredOnBits) {
         //Do nothing.
     }
 
-    public boolean hasCollision(Spatial scene, boolean checkTriangles) {
+    public boolean hasCollision(
+            Spatial scene, boolean checkTriangles, int requiredOnBits) {
         return false;
     }
 
index 4ad8506..fc10812 100644 (file)
@@ -253,15 +253,18 @@ public class TriMesh extends Geometry implements Serializable {
      * determines if a collision between this trimesh and a given spatial occurs
      * if it has true is returned, otherwise false is returned.
      */
-    public boolean hasCollision(Spatial scene, boolean checkTriangles) {
-        if (this == scene || !isCollidable() || !scene.isCollidable()) {
+    public boolean hasCollision(
+            Spatial scene, boolean checkTriangles, int requiredOnBits) {
+        if (this == scene || !isCollidable(requiredOnBits)
+                || !scene.isCollidable(requiredOnBits)) {
             return false;
         }
         if (getWorldBound().intersects(scene.getWorldBound())) {
             if (scene instanceof Node) {
                 Node parent = (Node) scene;
                 for (int i = 0; i < parent.getQuantity(); i++) {
-                    if (hasCollision(parent.getChild(i), checkTriangles)) {
+                    if (hasCollision(parent.getChild(i),
+                                checkTriangles, requiredOnBits)) {
                         return true;
                     }
                 }
@@ -273,7 +276,7 @@ public class TriMesh extends Geometry implements Serializable {
                 return true;
             }
 
-            return hasTriangleCollision((TriMesh) scene);
+            return hasTriangleCollision((TriMesh) scene, requiredOnBits);
         }
 
         return false;
@@ -285,8 +288,10 @@ public class TriMesh extends Geometry implements Serializable {
      * the two trimesh OBBTrees are then compared to find the triangles that
      * hit.
      */
-    public void findCollisions(Spatial scene, CollisionResults results) {
-        if (this == scene || !isCollidable() || !scene.isCollidable()) {
+    public void findCollisions(
+            Spatial scene, CollisionResults results, int requiredOnBits) {
+        if (this == scene || !isCollidable(requiredOnBits)
+                || !scene.isCollidable(requiredOnBits)) {
             return;
         }
 
@@ -294,7 +299,7 @@ public class TriMesh extends Geometry implements Serializable {
             if (scene instanceof Node) {
                 Node parent = (Node) scene;
                 for (int i = 0; i < parent.getQuantity(); i++) {
-                    findCollisions(parent.getChild(i), results);
+                    findCollisions(parent.getChild(i), results, requiredOnBits);
                 }
             } else {
                 results.addCollision(this, (Geometry) scene);
@@ -303,21 +308,30 @@ public class TriMesh extends Geometry implements Serializable {
     }
 
     /**
+     * Convenience wrapper for hasTriangleCollision(TriMesh, int) using default
+     * collision mask (bit 1 set).
+     */
+    final public boolean hasTriangleCollision(TriMesh toCheck) {
+        return hasTriangleCollision(toCheck, 1);
+    }
+
+    /**
      * This function checks for intersection between this trimesh and the given
      * one. On the first intersection, true is returned.
      * 
-     * @param toCheck
-     *            The intersection testing mesh.
+     * @param toCheck The intersection testing mesh.
+     * @param requiredOnBits Collision will only be considered if both 'this'
+     *        and 'toCheck' have these bits of their collision masks set.
      * @return True if they intersect.
      */
-    public boolean hasTriangleCollision(TriMesh toCheck) {
+    public boolean hasTriangleCollision(TriMesh toCheck, int requiredOnBits) {
         CollisionTree thisCT = CollisionTreeManager.getInstance()
                 .getCollisionTree(this);
         CollisionTree checkCT = CollisionTreeManager.getInstance()
                 .getCollisionTree(toCheck);
 
-        if (thisCT == null || checkCT == null || !isCollidable()
-                || !toCheck.isCollidable()) {
+        if (thisCT == null || checkCT == null || !isCollidable(requiredOnBits)
+                || !toCheck.isCollidable(requiredOnBits)) {
             return false;
         }
         thisCT.getBounds().transform(worldRotation, worldTranslation,
index 49b34f7..ef6bd62 100644 (file)
@@ -209,12 +209,14 @@ public class ParticleLines extends ParticleSystem {
     }
 
     @Override
-    public void findCollisions(Spatial scene, CollisionResults results) {
+    public void findCollisions(
+            Spatial scene, CollisionResults results, int requiredOnBits) {
         ; // ignore
     }
 
     @Override
-    public boolean hasCollision(Spatial scene, boolean checkTriangles) {
+    public boolean hasCollision(
+            Spatial scene, boolean checkTriangles, int requiredOnBits) {
         return false;
     }
 
index 349a54c..cae98e6 100644 (file)
@@ -75,7 +75,7 @@ public final class MeshCloner {
             target.setRenderState(source.getRenderState(i));
         }
 
-        target.setIsCollidable(target.isCollidable());
+        target.setCollisionMask(target.getCollisionMask());
 
         target.setLocalTranslation(source.getLocalTranslation().clone());
         target.setLocalRotation(source.getLocalRotation().clone());