object picking

Started by fireside, March 20, 2009, 03:28:39 PM

Previous topic - Next topic

fireside

I'm trying to figure out how to do simple object picking where the cursor goes over and object and I add an additional color while it's over it.  I did a search but couldn't find anything.
click here->Fireside 7 Games<-

fireside

It was interact2d.  I remember now.  I'll give it a try and then ask questions when I mess it up. ;D
click here->Fireside 7 Games<-

EgonOlsen

Either the pickPolygon-methods from Interact2D or ray-polygon collision detection (or calcMinDistance as a variant of that). The former works in camera space (faster, easier to use), the latter in world space (slower, more complex to use...but compatible with the upcoming compiled objects).

fireside

Hmm.  Maybe I'll try the ray thing, then.  I just plan on doing this game with software rendering but it still might be a good idea.
click here->Fireside 7 Games<-

paulscode

I was actually wondering about this same question, but hadn't gotten around to asking it yet.

For my MapMaker program when I click on a map cell, I use:

1) Interact2D.reproject2D3D to convert mouse coordinates into camera coordinates
2) SimpleVector.matMul and SimpleVector.add to converted that to world coordinates
3) SimpleVector.calcSub and SimpleVector.normalize to calculate the direction
4) World.calcMinDistance to obtain the length
5) SimpleVector.add to obtain the 3D coordinates of what the mouse is over.
6) Division on x and z to convert that into the map-cell coordinates the mouse is over.

But this doesn't give an actual polygon, and would not work for anything more complex than a map.  To obtain the polygon, I suppose I would stop after step #4, and instead use CollisionEvent.getTargets() and CollisionEvent.getPolygonIDs().  These should both return arrays with length=1, indicating the object and polygon that the mouse is over.  The problem is, how to I know that a particular CollisionEvent was caused by my call to World.calcMinDistance and not something else (like another object colliding with the object in question or other calls to calcMinDistance elsewhere in the program)?  It seems there should be a way to "flag" potential collision-causing methods to be able to link them with the CollisionEvent's they generate.  Any ideas?

fireside

I guess it would depend on what the collision event returned as the source.  I take it CalcMinDistance causes a collision?
click here->Fireside 7 Games<-

paulscode

I assume the source would be null (javaDoc says "getSource() returns the source of the collision if it's an Object3D, or null otherwise").  That would help differentiate between a CollisionEvent generated by a call to calcMinDistance vs. one generated by an actual collision.  However it would not differentiate between different calls to calcMinDistance (say you wanted to use calcMinDistance for other things in your game too, not only just for mouse-over - for example, changing the textures of a terrain as a vehicle's wheels drive over it, determining wheel orientations while driving over a rough terrain, firing lasers that draw damage-textures on a target where it was hit, etc.)

I guess another alternative would be to fire an invisible Object3D "bullet" rather than using calcMinDistance - that would produce an actual CollisionEvent source.  This seems a bit hackish to me, though.

EgonOlsen

The event will be called right after the collision, i.e. if you are doing a calcMinDistance and are receiving the event, there can't be any other source than your call to calcMinDistance at that time.

paulscode

Aha!  So right before I call clacMinDistance(), I can set a global "id" varriable, and retrieve that at the top of the CollisionListener's collision() method to know which calcMinDistance I'm dealing with.  Then I'd reset that id at the end of the collision() method.

EgonOlsen

Quote from: paulscode on March 21, 2009, 09:13:42 PM
Aha!  So right before I call clacMinDistance(), I can set a global "id" varriable, and retrieve that at the top of the CollisionListener's collision() method to know which calcMinDistance I'm dealing with.  Then I'd reset that id at the end of the collision() method.
Something like that. Not very elegant, but it should do the trick.