Dynamic extrusion, bounding vol., accurate collision detection & multithreading?

Hi all,

As my project advances I’m beginning to encounter not so easy to solve problems. Here is my current one:



I’m developing a scene where the mouse will be THE main input device. For the time being, I’ve used some code found in the TestTrianglePick testcase with a homemade version of the MousePick class (also in the jmetest.intersection package).



My MousePickHandler uses Ray and a TrianglePickResults to store collision information.



The scene is composed of some “cylinders” with a quarter of a sphere (qos) in front of it. The camera shows the qos and then the cylinders behind: first screenshot.



The purpose of the qos is to display information about database sessions that consume CPU. To do that I assign a face to a session and I extrude this face by the amount of CPU used (since last refresh).



Now I want the user to be able to see objects information on a cursor that when pass over objects change and displays for example its name. To do that I’ve used Bounding Volumes.



The cylinders have BoundingBox while the qos has a BoundingSphere. Because the qos is a dynamic mesh, I call updateModelBound each time it is modified in order to reflect these changes to its BoundingSphere (small one (screenshot 2), larger one (screenshot 3)).



Now my problems:

-1- when the camera is inside the BoundingSphere, and the white cross mouse cursor is over a cylinder and not over any face of the qos, the nearer object (results.getPickData(0)) is not the cylinder but the qos?!? certainly because of the BoundingSphere => solution: walk along results.getPickData(1), then results.getPickData(2)…?



-2- because the vertices move so fast (4 refresh per second), when the mouse is over the extruded faces, no intersections are detected, I mean: results.getPickData(0) == qos but results.getPickData(0).getTargetTris().size() == 0 => please read point 3 for more explanations



-3- regarding the previous problem, I invoke qos.updateModelBound() after faces extrusion but now I think I’ve got a multithreading issue: the mouse cursor collision detection appears to be done inside the OpenGL thread during the GameState update while the extrusions are performed in an other thread… I think the model bound is not up to date when the collision detection is performed but I’ve no way to confirm it yet. And If so what should I do?



note: Culling is set to inherit



Possible solution: I’m thinking of a new way to implement face extrusion: a simple quarter of sphere + numerous Box attached to a Node => one (Oriented?)BoundingBox per Box (but it means recode everything  :|)



Any comments/help regarding these problems appreciated  :smiley: (although I presume they are common).



N.

I spoke too quickly, the session detection still failed. Although it works sometimes. I even tried to use a Semaphore to serialize the process but still it doesn't work…

Moving your extrusion code into the opengl thread should fix the issue, or else you'll have to synchronize access to the cylinders between your worker thread and the opengl thread. Check out GameTaskQueueManager, your code will look something like this:



GameTaskQueueManager.getManager().update(new Callable<Void>() {
    public Void call() throws Exception {
        // your extrusion code

        return null;
    }
});

Niggle said:

I spoke too quickly, the session detection still failed. Although it works sometimes. I even tried to use a Semaphore to serialize the process but still it doesn't work...


I can't really guess at the issue without seeing more code, but if you want to check for a concurrency issue you could always temporarily single thread your stuff. Submitting all work to com.jme.util.GameTaskQueueManager instead of your worker thread pool would at least tell you if that's the problem.

Thanks, for your help :slight_smile:



However, I’ve recoded all from the beginning (Node + quarter of sphere + numerous oriented boxes) and now, it works like a charm, I even wonder if I did not found a bug (but I’ll have to check-out the last svn version for that):



teaser: does mouse face picking handles CullHint? I mean with my current svn version (old) I get ray hit on CullHint.Always objects…



More news to come  :smiley:

It’s working: screenshot


Indeed, I think the Node.findPick method shoukd be different:



Current:

    public void findPick(Ray toTest, PickResults results) {
        if(children == null) {
            return;
        }
        if (getWorldBound() != null && isCollidable) {
            if (getWorldBound().intersects(toTest)) {
                // further checking needed.
                for (int i = 0; i < getQuantity(); i++) {
                    ( children.get(i)).findPick(toTest, results);
                }
            }
        }
    }



Proposed:

    public void findPick(Ray toTest, PickResults results) {
        if(children == null) {
            return;
        }
        if (getWorldBound() != null && isCollidable) {
            if (getWorldBound().intersects(toTest)) {
                // further checking needed.
                for (int i = 0; i < getQuantity(); i++) {
                    final Spatial child = children.get(i);
                    if( child.getCullHint() != Spatial.CullHint.Always ) {
                        child.findPick(toTest, results);
                    }
                }
            }
        }
    }



Any comment?

Hmm…  currently if a spatial is cullhint == always, it is still part of the world boundings…  So it works the same.  It's a behavior change, but I wonder if it would make more sense to pull spatials from world boundings AND pick results, etc. if you've set the hint to ALWAYS cull.



Thoughts anyone?

I think that setting the CullHint to either Never/Always is the only (maybe I’m wrong) way to show/hide an object. Since this concept is not available for Spatial (yet?) – I mean real show() and hide() methods – so hiding (Always) a Spatial means no more collision, no more rendering, in brief no more processing.  8)


Well, I believe it should still process the Spatial in terms of running its controllers and so forth, but not be included in boundings, picking, etc.