Make Curves pickable

Requested in http://www.jmonkeyengine.com/jmeforum/index.php?topic=10855.0 this patch removes the findPick(…) overrides which makes the Line that represents the Curve pickable.


Index: src/com/jme/curve/BezierCurve.java
===================================================================
--- src/com/jme/curve/BezierCurve.java   (revision 4259)
+++ src/com/jme/curve/BezierCurve.java   (working copy)
@@ -224,14 +224,6 @@
    public boolean hasCollision(Spatial scene, boolean checkTriangles) {
       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) {
-      // TODO Auto-generated method stub
-      
-   }
-
+   
 }
 
Index: src/com/jme/curve/CatmullRomCurve.java
===================================================================
--- src/com/jme/curve/CatmullRomCurve.java   (revision 4259)
+++ src/com/jme/curve/CatmullRomCurve.java   (working copy)
@@ -275,16 +275,5 @@
    public boolean hasCollision(Spatial scene, boolean checkTriangles) {
       return false;
    }
-
-
-   /*
-    * (non-Javadoc)
-    *
-    * @see com.jme.scene.Spatial#doPick(com.jme.math.Ray,
-    * com.jme.intersection.PickResults)
-    */
-   @Override
-   public void findPick(Ray toTest, PickResults results) {
-
-   } // findPick
+   
 } // CatmullRomCurve



EDIT:

Heres a patch for TestPick that tests the new behavior:

Index: src/jmetest/intersection/TestPick.java
===================================================================
--- src/jmetest/intersection/TestPick.java   (revision 4259)
+++ src/jmetest/intersection/TestPick.java   (working copy)
@@ -43,6 +43,7 @@
 import com.jme.app.SimpleGame;
 import com.jme.bounding.BoundingBox;
 import com.jme.bounding.BoundingCapsule;
+import com.jme.curve.BezierCurve;
 import com.jme.math.FastMath;
 import com.jme.math.Vector3f;
 import com.jme.renderer.ColorRGBA;
@@ -52,6 +53,7 @@
 import com.jme.scene.Text;
 import com.jme.scene.Spatial.TextureCombineMode;
 import com.jme.util.export.binary.BinaryImporter;
+import com.jme.util.geom.BufferUtils;
 import com.jme.util.resource.ResourceLocatorTool;
 import com.jme.util.resource.SimpleResourceLocator;
 import com.jmex.model.animation.JointController;
@@ -154,7 +156,25 @@
       l.setModelBound(new BoundingBox());
       l.updateModelBound();
       l.setLightCombineMode(Spatial.LightCombineMode.Off);
+      
+    //create control Points
+    Vector3f[] points = new Vector3f[4];
+    points[0] = new Vector3f( -400, 0, 0);
+    points[1] = new Vector3f( -200, 300, -200);
+    points[2] = new Vector3f(200, -300, -300);
+    points[3] = new Vector3f(400, 0, 0);
 
+    BezierCurve curve = new BezierCurve("Curve", points);
+    ColorRGBA[] colors = new ColorRGBA[4];
+    colors[0] = new ColorRGBA(0, 1, 0, 1);
+    colors[1] = new ColorRGBA(1, 0, 0, 1);
+    colors[2] = new ColorRGBA(1, 1, 0, 1);
+    colors[3] = new ColorRGBA(0, 0, 1, 1);
+    curve.setColorBuffer(BufferUtils.createFloatBuffer(colors));
+    curve.setModelBound(new BoundingBox());
+    curve.updateModelBound();
+
+    rootNode.attachChild(curve);
       rootNode.attachChild(l);
       rootNode.attachChild(model);
 

When i test it, i can pick far away from the curve and it still registers as a curve pick.

I guess it only checks its BoundindBox which is quite big.



I'm not sure if this is desired.



edit:

on the other hand its the same with a diagonal line, so it doesn't really matter i guess :slight_smile:


you can only pick it if you are outside the curve's bounding volume. its the same behavior as with normal lines (i dont like it that much either  ;))

But did you notice that the boundingbox is much higher, than the actual curve? i wonder why that is.



I'm ok with the patch, but this is a change which should go into 2.1  (after the 2.0 branch is taken which will happen soon).

Core-Dump said:

But did you notice that the boundingbox is much higher, than the actual curve? i wonder why that is.


No, I'll check and see if I can do smth. about it.

Core-Dump said:

I'm ok with the patch, but this is a change which should go into 2.1  (after the 2.0 branch is taken which will happen soon).


OK.
Core-Dump said:

But did you notice that the boundingbox is much higher, than the actual curve? i wonder why that is.


Ok i looked into it and its ok like that i guess because for Curves the method  containAABB(FloatBuffer) is called when calculating the BoundingBox size. This uses the VertexBuffer of the Curve, which are the Control Points of the Curve. In the TestCase above, a BezierCurve is used and that is why the box is much bigger than the visible Curve itself. For the CatmullRomCurve the Box will fit perfectly.

This however raises another issue, there might be many curves that may draw outside of this box (which is defined by the control points), as it can happen with the CatmullRomCurve. This is not very good i think, the picking doesnt work for the BezierCurve because the Box is too big and for the CRC it can be too small, for some Curves it might fit for others maybe not.

If someone has ideas for this go ahead but i think this shouldn't go into jme.

On a related note, we ended up adding code in our application's pick handling to strip line-related pick results entirely.  We were finding that it was a common occurrence for a line to be selected over other objects because the line tests were performed against the bounding box.  I'd love to see the line pick testing replaced.