Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

12045 Posts in 1593 Topics- by 593 Members - Latest Member: zhang

25. May 2013, 07:21:22 pm
Xith3D CommunityXith3D InternalsDeveloper discussion (Moderators: Marvin Fröhlich, 'n ddrylliog)Picking
Pages: [1]
Print
Author Topic: Picking  (Read 1883 times)
William Sellick
Just dropped in

Offline Offline

Posts: 9


View Profile Email
« on: 18. May 2007, 11:05:58 pm »

I'm currently implementing picking in my project and am interested to know if there is a better way of achieving what I am trying to do.

I have extended InputAdapterRenderLoop and am using the method below to call a listener to process picking

Code:
    public void onMouseButtonReleased(MouseDevice mouse, int button, int x, int y){
      PickingLibrary.pickNearest(mainGroup, canvas, button, x, y, worldPickListener);
    }

Where worldPickListener is a custom class that implements NearestPickListener.

Now as I am making an RTS I was planning to process the picking in the following manner

1) User selects a single or group of units
2) The listener stores this list of units and waits for the actual command
3) The user makes a choice of action (lets say move) which means they click somewhere else on the map
4) A new action is created to perform the action (in this case it is to move the unit from its current position to the new coordinates)

My problem currently lies in step 3. When the user clicks on a blank space to move a unit from their current position to the new picked coordinate the listener is called but on the 'onPickingMissed' method (makes sense as nothing is there to pick) but this does not contain the translated coordinates the user clicked on. This presents a problem when trying to move a unit to a coordinate. Now I'm wondering if I missed a simpler way of doing this or maybe am I using a method in the wrong way? But basically I need the coordinates on a picking miss, should I be using a different type of listener?

Any advice or guidance?
Logged
'n ddrylliog
Moderator
Guru
*****
Offline Offline

Posts: 1188



View Profile WWW Email
« Reply #1 on: 19. May 2007, 12:11:00 pm »

To do picking on a unit is really a bad idea. Why ? :
 - For group selection, you are forced to click on every unit you want to select (and you'd better not miss one Smiley or the half you'd have already selected would move)
 - It's ssssssssssslow, e.g. if you have 100-200 polys / units, you'd better pick on the bounding box/sphere/ellipsoid anyway
 - You can't have any coordinate when you don't pick on the unit (the problem you reported).

So how should it be done ? Just make a quad/plane (Xith3D geometry) which is nearly-infinite in all directions (-X, +X, -Y, +Y) (be careful about very big numbers as they can lead to inaccuracies or worse, crashes) and do picking on it. With that you can do e.g. a selection rectangle. Then you'd like to know which units are in this rectangle. Well write a "point-in-polygon" test algorithm. And after that, add commands to select all units with one key (e.g. "A") and orders. And you'll get Stratagem Alpha 1 Smiley (assuming you have some good animated models and a heightmapped terrain, of course Smiley )

May I remind you that the stratagemengine code is open-source ? All you ask here has been implemented. It is not as clean as I'd like it to (not too much time to clean it up right now) but it works.
Logged
Marvin Fröhlich
Xith Lord
Administrator
Guru
*****
Offline Offline

Posts: 4403


May the 4th, be with you...


View Profile
« Reply #2 on: 20. May 2007, 08:12:24 pm »

To do picking on a unit is really a bad idea. Why ? :
 - For group selection, you are forced to click on every unit you want to select (and you'd better not miss one Smiley or the half you'd have already selected would move)
 - It's ssssssssssslow, e.g. if you have 100-200 polys / units, you'd better pick on the bounding box/sphere/ellipsoid anyway
 - You can't have any coordinate when you don't pick on the unit (the problem you reported).

So how should it be done ? Just make a quad/plane (Xith3D geometry) which is nearly-infinite in all directions (-X, +X, -Y, +Y) (be careful about very big numbers as they can lead to inaccuracies or worse, crashes) and do picking on it. With that you can do e.g. a selection rectangle. Then you'd like to know which units are in this rectangle. Well write a "point-in-polygon" test algorithm. And after that, add commands to select all units with one key (e.g. "A") and orders. And you'll get Stratagem Alpha 1 Smiley (assuming you have some good animated models and a heightmapped terrain, of course Smiley )

May I remind you that the stratagemengine code is open-source ? All you ask here has been implemented. It is not as clean as I'd like it to (not too much time to clean it up right now) but it works.

I don't totally agree. I guess, what might cause the above problem is simply, that he didn't put the terrain shape(s) into the pick-tested group(s).

But to optimize the unit picking I would do the following:
  • Disable Polygon-picking in PickingLibrary (static method).
  • Create a java.util.List and store it somewhere accessable by the picking methods.
  • Put the Group in it, that contains the terrain and the one that contains the units.
  • Pass this List to the picking method.
  • Then do regular picking and either the Terrain or one of the units (or nothing) will be reported to the picking listener.
Optimizations:
  • The PickingLibrary should get a replaceable polygon-tester (work in progress).
  • Do a pickAll(), but not a pickNearest() on the BoundingSheres only. If only one unit is picked (or the terrain), it is ok. If more than one unit is picked, do a pickNearest() on only them (PL should take a List of Nodes, work in progress) with polygon-test enabled.
  • For the terrain, I would suggest to place a Fog into the scene to make the borders of the plane disappear.

I hope, this helps you.

Marvin
Logged
William Sellick
Just dropped in

Offline Offline

Posts: 9


View Profile Email
« Reply #3 on: 20. May 2007, 10:52:56 pm »

Thanks both of you for your advice. I've been working on it a bit today and think I'm getting there. Smiley I am implementing something close to what Amos spoke about with the opimizations Marvin mentioned. I have decided to extend InputListener and attach this to the input manager of the environment.

On a side note, I ran into a bit of a problem earlier today when I was implementing mouse elements in the inputlistener and was wondering if anyone else has had this problem. It seems the onMouseMoved method in my listener does not get called when a mouse button is clicked. I thought this was quite strange and so wrote a simple test where I just extended InputListener with only System.out's but I got the same result. The method works fine if I don't press a button. I had a look at the Stratagem code and it seems to use an InputListener onMouseMoved method while a button is clicked. Is this a possible problem with my system?
Logged
Marvin Fröhlich
Xith Lord
Administrator
Guru
*****
Offline Offline

Posts: 4403


May the 4th, be with you...


View Profile
« Reply #4 on: 21. May 2007, 01:51:37 am »

On a side note, I ran into a bit of a problem earlier today when I was implementing mouse elements in the inputlistener and was wondering if anyone else has had this problem. It seems the onMouseMoved method in my listener does not get called when a mouse button is clicked. I thought this was quite strange and so wrote a simple test where I just extended InputListener with only System.out's but I got the same result. The method works fine if I don't press a button. I had a look at the Stratagem code and it seems to use an InputListener onMouseMoved method while a button is clicked. Is this a possible problem with my system?

Did you register your InputListener to the InputManager? InputAdapterRenderLoop does that automatically.

Marvin
Logged
William Sellick
Just dropped in

Offline Offline

Posts: 9


View Profile Email
« Reply #5 on: 21. May 2007, 10:13:53 am »

Quote
Did you register your InputListener to the InputManager? InputAdapterRenderLoop does that automatically.

Yes I did register the listener and I have proved this works as it registers mouse movement (but just not when a button is not clicked) The listener registers button presses and releases. I'm guessing it should still register movement when a button is clicked?
Logged
Marvin Fröhlich
Xith Lord
Administrator
Guru
*****
Offline Offline

Posts: 4403


May the 4th, be with you...


View Profile
« Reply #6 on: 21. May 2007, 01:02:59 pm »

Yes I did register the listener and I have proved this works as it registers mouse movement (but just not when a button is not clicked) The listener registers button presses and releases. I'm guessing it should still register movement when a button is clicked?

Oh. Now I understand. Yes, it should. This is a bug, which was fixed one or two weeks ago (in HIAL). Are you sure, you're using the latest SVN trunk (resp. the latest checked-in HIAL jar)?

Marvin
Logged
William Sellick
Just dropped in

Offline Offline

Posts: 9


View Profile Email
« Reply #7 on: 21. May 2007, 10:09:53 pm »

Thanks for that Marvin, my library was just out of date. Problem fixed
Logged
Marvin Fröhlich
Xith Lord
Administrator
Guru
*****
Offline Offline

Posts: 4403


May the 4th, be with you...


View Profile
« Reply #8 on: 21. May 2007, 10:46:42 pm »

The PickingLibrary should get a replaceable polygon-tester (work in progress).

You can now replace polygon testing by implementing the GeometryPickTester interface and use the setGeometryPickTester() method of PickingLibrary to use your own one. By default an instance of DefaultGeometryPickTester class is used.

...(PL should take a List of Nodes, work in progress)...

This is not simple, I must admit. But I have a good solution for this now. Just use the new class DummyGroupNode and add your Nodes (Shapes, Groups) to it. DummyGroupNode does NOT care about scenegraph integrity so it doesn't handle the parents, etc. You can simply add Nodes to it, which are already child of a Group. But never add an instance of DummyGroupNode to the scenegraph. It is solely meant for situations like picking.

Marvin
Logged
'n ddrylliog
Moderator
Guru
*****
Offline Offline

Posts: 1188



View Profile WWW Email
« Reply #9 on: 22. May 2007, 06:55:42 pm »

Hey, one more bug fixed before it's reported Smiley

Just make Xith3D throw an exception if ever a DummyGroupNode is added to the scenegraph !
Logged
Marvin Fröhlich
Xith Lord
Administrator
Guru
*****
Offline Offline

Posts: 4403


May the 4th, be with you...


View Profile
« Reply #10 on: 22. May 2007, 08:23:22 pm »

Just make Xith3D throw an exception if ever a DummyGroupNode is added to the scenegraph !

Done.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic