Custom AWT picking and accuracy

Hi there,



As you can see in the upcoming code, I’ve implemented a custom way of mouse picking through the AWT interface. While debugging it appeared to me that mouse clicks were indeed transformed into meaningful world coordinates (both X and Y between -0.5 and 0.5). However, when performing mouse picking on a rotated box, finding picks really lacks accuracy and I can get a static box continue rotating even by clicking its surroundings (as depicted in the following image).



I’ve read several topics about triangle picking, but implementing those pieces of code only ends up in null pointer exceptions. What would be a general method for accurately picking any kind of spatial?



Greetings.







SwingTest.java - to start up the application, putting jME in a canvas


import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.logging.Level;

import javax.swing.JFrame;

import jmecanv.InitialScene;

import com.jme.system.DisplaySystem;
import com.jme.util.LoggingSystem;
import com.jmex.awt.JMECanvas;

public class SwingTest extends JFrame implements MouseListener
{
   private static final long serialVersionUID = 1L;

You are using BoundingPickResults combined with BoundingBox which is Axis-Aligned. So, based on that fact and your screenshot, I'd guess that it is in fact hitting the bounding for that box.



Turn on bounding display to see a more accurate picture of what is happening.

As you can see on the screenshot, you were right. Thanks for clearing that up.

However, forgive me my ignorance, but I haven’t got a clue on how to increase the accuracy; simply changing BoundingPickResults into TrianglePickResults is rather useless.



Any thoughts / references?



Thanks.



Hallelujah, OrientedBoundingBox surely did the trick.

Okay, I’ve implemented the triangle picking method from (here), which really improved the accuracy…

well, actually I would say the picking method is too picky now :wink:



As indicated in the image below, picking the red spot fails to produce a triangle intersection, which in turn fails to get the model rotating (or stopping from rotating)… whereas, the closer I get to the center (the green spot), the more ‘luck’ I get.



I hope this isn’t any kind of float imprecision thingy.

Any suggestions? (new code below)



Thanks once again.



The image





The new InitialScene.java class


package jmecanv;

import java.awt.Point;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.LinkedList;

import com.jme.bounding.OrientedBoundingBox;
import com.jme.intersection.TrianglePickResults;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Ray;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.Spatial;
import com.jme.scene.TriMesh;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.XMLparser.Converters.ObjToJme;

public class InitialScene extends SceneCanvasImplementor
{

look at TestOBBPick.java

MrCoder, thanks for the quick reply and useful hint.

Mouse picking now is up and running!



The modified code can be found at the end.



One thing left: is the model.updateCollisionTree(); call necessary?

Leaving it out of the code makes no difference, or does it, for less

general models? What is its use anyway?



Greetings.



The once again modified InitialScene.java class


package jmecanv;

import java.awt.Point;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.LinkedList;

import com.jme.bounding.OrientedBoundingBox;
import com.jme.intersection.PickData;
import com.jme.intersection.PickResults;
import com.jme.intersection.TrianglePickResults;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Ray;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.Spatial;
import com.jme.scene.batch.TriangleBatch;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.XMLparser.Converters.ObjToJme;

public class InitialScene extends SceneCanvasImplementor
{

If your model doesn't change, it's not needed.