Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Discussion / 3d mouse clicking

Author
Message
Area 51
19
Years of Service
User Offline
Joined: 3rd Feb 2006
Location: UNKNOWN
Posted: 16th Nov 2007 23:38
Hi. I'm currently creating an RTS with DBC, but only one problem. I don't know how to use the mouse for clicking in 3d. can any of you help me?

Are we alone?
luke810
18
Years of Service
User Offline
Joined: 4th Sep 2006
Location: United States
Posted: 17th Nov 2007 00:12
Use Sparky's vector based collision DLL with the 3d Matrix Selection function on the UnderWare Design website.
Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 17th Nov 2007 01:35 Edited at: 9th Dec 2007 02:15
@luke810

I've tried many methods and most are successful, but some only to a point... I rotate the camera on it's x axis, most methods bail. I wonder if it has to do with SET CAMERA ROTATION XYZ or ZYX? Does your method account for rotation of the camera on all of it's axis? I'm assuming that the vectors are found from the camera position and angles...

Enjoy your day.
luke810
18
Years of Service
User Offline
Joined: 4th Sep 2006
Location: United States
Posted: 18th Nov 2007 19:14
I didn't write the actual function to calclate to endpoints of the ray, it was Kevin Picone, but it takes into account rotation of the camera around any axis. Its a pretty common method of calculating mouse positions in 3D. If you search for it in google you'll probably find an example for c++ or visual basic.
Libervurto
18
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 18th Nov 2007 22:36
I've been experimenting with 3D -> 2D co-ordinates and I've found that spheres (only shape I've tested) appear to be their 3D size in 2D when the camera is 200 away.

That makes no sense so here's an example:
I make a sphere that is 32 units large, it is positioned at 0,0,0
I then position the camera at 0,0,-200 and point camera at 0,0,0
If I now draw a circle in the middle of the screen sized 200, it appears to outline the sphere.

This seems like it could be useful but I can't work out how to use this information.

"You must be someone's friend to make comments about them." - MySpace lied.
Bluestar4
19
Years of Service
User Offline
Joined: 19th Dec 2005
Location: USA
Posted: 7th Dec 2007 08:34
If i understand you correctly you want to know how to detect whether a 3d object on the screen is being clicked on ? ? Since this is one of those questions that would consume many of your happy proramming hours I have decided to donate to this thread. First, pull out your manual and look up these commands : object exist(), object screen x(),object screen y(), mousex() , mousey()




Libervurto
18
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 7th Dec 2007 09:20
Sorry my earlier post had a mistake.

I make a sphere that is 30 units large, it is positioned at 0,0,0
I then position the camera at 0,0,-200 and point camera at 0,0,0
If I now draw a circle in the middle of the screen sized 30, it appears to outline the sphere.


can anyone tell me how I can use that?

"You must be someone's friend to make comments about them." - MySpace lied.
Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 7th Dec 2007 14:46
@BlueStar4

This is a viable solution if the camera view and distance to the objects never changes - because then their size in relation to 2d screen coordinates also wouldn't change, but I have run into many drawbacks in the past. One major drawback that isn't immediately apparent is object screen x() and object screen y() can return values even when they are behind the camera out of view. Trying to compensate by using object in screen() works to a degree, but it isn't as accurate as it needs to be... especially if you rotate the camera on all 3 axes.

It's not advisable to use a consistant area to check. The following snippet uses your example to show that:
a) your proposed method does work but
b) the area it checks may not apply and has to be adjusted for each object. The blue squares on the cubes shows the area that is being checked for a RIGHT click.


With some trig, you can figure out where the extremes of the object are in 3d and convert those to 2d screen coordinates. An easier way still using your method is just to make a drag box while holding a mouse botton and if the area selection captures object screen x() and object screen y(). That way, the size of the area to check is controlled dynamically without much math.

@Obese87

There's something I think you may be overlooking. If you make a sphere of size 30, it's radius is 15. If you draw a 2d circle with a radius of 30, well, the radius is 30. It's not a 1 to 1 relationship. Also, at that small of a size with 640x480 resolution, the two seem to match up. If you make each larger, you can see a bit of the difference:



However, what you are close to is finding the viewing plane which is the calculated distance the camera is to everything you see drawn. Loosely, this distance is the distance where 2d screen coordinates match with the horizontal and vertical units of the 3d objects. With this information, you can draw 2d circles or boxes around objects and use a 3d_click method similar to BlueStar4's suggestion.

Enjoy your day.
Libervurto
18
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 7th Dec 2007 23:00
3D is complicated

"You must be someone's friend to make comments about them." - MySpace lied.
Bluestar4
19
Years of Service
User Offline
Joined: 19th Dec 2005
Location: USA
Posted: 8th Dec 2007 02:54
Quote: "object screen x() and object screen y() can return values even when they are behind the camera out of view"



and this is where you fix up the snippet I gave you and add checks in it to ensure that the object is onscreen before executing.


Quote: "the area it checks may not apply and has to be adjusted for each object"


Now that I know that you have the basics , I'll continue with how to tweak the dectection. There are several ways to tweak it , add checks and such , but there are two main ways to tweak the detection process -
Quote: "With some trig, you can figure out where the extremes of the object"

1) did you notice the +/- 40 in parts of the if statement ?
I set it at 40 was so that you would get the basic idea but
it acts like a global constant for the area of detection !
Replacing every 40 with smaller numbers will give you more accurate detection when there are multiple objects on the screen at the cost of a larger detection area so IF you have many objects on the screen and expect some to overlap,shrink,grow , ect, you may want to decrease every instance to say 25 or even as low as 15. This should take care of most of it. If after adjusting the detection in this way you still need to adjust each one seperately , then I suggest using copy and paste.


*The crowd cheers in aww *

Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 9th Dec 2007 02:30
@BlueStar4
It's a pretty good method as long as it's well managed, don't get me wrong, but with certain camera rotations and positions, object in screen() will report back positive even when the object isn't in the viewable area (object screen x and object screen y can also return misleading values). A sorting routine is also necessary to return objects that are in front of other objects. Plus one has to account for object rotation and the object pivot point which can be way different than where the actual mesh is drawn. In the following snippet, I create an object whose pivot point is offset from the actual mesh. The circle on the screen shows the object's screen x and screen y as reported by DB:



luke810's suggested method is probably one of the best. Sparky's dll casts a ray that upon passing through a mesh or a series of meshes, returns the first one is collides with. Also, the collision DLL is pretty fast. Since it collides with the mesh itself, that eliminates the worry of managing the rotation and the size of the object in 2d. Even if the object's pivot point is offset, the collision detection should still work.

Enjoy your day.
Bluestar4
19
Years of Service
User Offline
Joined: 19th Dec 2005
Location: USA
Posted: 9th Dec 2007 10:24
Quote: "It's a pretty good method as long as it's well managed, don't get me wrong, but with certain camera rotations and positions, object in screen() will report back positive even when the object isn't in the viewable area (object screen x and object screen y can also return misleading values). "


I never touch the camera rotatio so it works every time.

Quote: " A sorting routine is also necessary to return objects that are in front of other objects"

in every 3d game the object in front is usually closer and so it will have the larger area of detection.

Quote: "luke810's suggested method is probably one of the best. Sparky's dll casts a ray that upon passing through a mesh or a series of meshes, returns the first one is collides with"
I thought we were talking about how to make code that detects when an object was clicked on ? I use math routines for colision detection - its fast

demons breath
21
Years of Service
User Offline
Joined: 4th Oct 2003
Location: Surrey, UK
Posted: 9th Dec 2007 14:51
Quote: "Replacing every 40 with smaller numbers will give you more accurate detection when there are multiple objects on the screen at the cost of a larger detection area so IF you have many objects on the screen and expect some to overlap,shrink,grow , ect, you may want to decrease every instance to say 25 or even as low as 15. "


I made a 3d tic tac toe game the other day and I noticed the overlap problem, but to solve it I still used reasonably sized boxes but if the mouse was closer to the center of one box than the other I used the one it was closest to... I'm not very good at explaining it but this was my code:



It was this part of the code that checked the mouse position:

Here it checks the mouse position by cycling through all the boxes. If no box is currently selected and the mouse is within the detection area, then it uses that box as the currently selected one, but if a box is already selected it checks if the new box is closer to the mouse position, and changes the selected box if this is true.

Still not explaining this very well, and I'm not sure how helpful it'll be in your context, but just in case it helps...

Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 9th Dec 2007 18:33
Blue
Quote: "in every 3d game the object in front is usually closer and so it will have the larger area of detection."


Everything you type makes complete sense, so maybe I'm missing your point because what if there is an aircraft carrier behind a row boat? Even though the rowboat is in front, wouldn't the aircraft carrier have a larger area of detection?
Also if you're using the 2d screen coordinates and an area around them, the areas of two or more objects can overlap. In this case, there is no zdepth calculation (unless you make one) so neither of the areas selected would be considered "in front" if they reside at the same 2d location. Finding out which one is in front would be part of the routine you'd have to create. My only point in all this is saying that to use screen object x and y, there is a lot of work that has to go into making it function accurately and consistantly based on the 3d scene and any dynamic changes. If the scene is flat, all the pivot points are dead center on the objects, their size, position, and rotation don't change this method is not complicated to implement. As the scene gets more complicated, animation is introduced, limbs are added, sizes change, distances change, managing this functionality becomes more and more complicated.

Quote: "Since this is one of those questions that would consume many of your happy programming hours"

That's true because it's really not as simple as object screen x and object screen y, although those commands are very useful for 3d clicking under non complicated circumstances.

Demon
Quote: "Here it checks the mouse position by cycling through all the boxes. If no box is currently selected and the mouse is within the detection area, then it uses that box as the currently selected one, but if a box is already selected it checks if the new box is closer to the mouse position, and changes the selected box if this is true."


The boxes being next to each other this makes sense. But if there are objects in front of one another they could have the same 2d coordinates and you'd have to sort out which one is actually being clicked on.

Blue
Quote: "I thought we were talking about how to make code that detects when an object was clicked on ? I use math routines for colision detection - its fast"


We are. His proposed method casts a ray from the mouse position and converts it to a 3d vector into 3d space. The collision DLL uses this vector and returns the first object that the ray passes through that you have set up for collision detection. He based his method on an example that Kevin Picone created about selecting points on a matrix. Kevin used algorithms to calculate the ray that would be cast. luke810 combined this with the collision routines from Sparky's DLL and created a mouse 3d object picker that should work at any camera angle or object position.

luke810 2d_3d

Enjoy your day.
demons breath
21
Years of Service
User Offline
Joined: 4th Oct 2003
Location: Surrey, UK
Posted: 9th Dec 2007 18:36
@Latch: Oh yeah, I didn't think about that...

Bluestar4
19
Years of Service
User Offline
Joined: 19th Dec 2005
Location: USA
Posted: 9th Dec 2007 18:46
Quote: "luke810 combined this with the collision routines from Sparky's DLL and created a mouse 3d object picker that should work at any camera angle or object position."

thats good. Truth be known , there are are probably better detection methods then the one I gave you but there is no real right or wrong as long as it gets the job done

Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 9th Dec 2007 19:16 Edited at: 9th Dec 2007 20:34
Agreed! Even though we highjacked area51's thread, thanks for your input - you've given me some things to think about and try.

Enjoy your day.
Bluestar4
19
Years of Service
User Offline
Joined: 19th Dec 2005
Location: USA
Posted: 10th Dec 2007 02:42
the one thing I should point out latch is that that I only rotated the y axis of the camera using rotate camera command , so some of the things that came up was never a problem to me. on the other side of the coin there are the roll,pitch and turn camera commands which are nice , but appeared to have quirks (as you pointed out ) so after much expermentation, trial and many failures, I started using the rotate camera command instead as it appers to work nicely

Area 51
19
Years of Service
User Offline
Joined: 3rd Feb 2006
Location: UNKNOWN
Posted: 26th Feb 2008 01:39
Ok, well, truth be known, I didnt know there was an
object screen x() or y command in DB Classic . Now my problem is going the opposite way. If in my rts, there's buildings to be built in the places the player wants to place them, how do I make the building follow the mouse to the location.

Are we alone?
TDK
Retired Moderator
22
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 26th Feb 2008 01:43
Is it really worth us bothering to answer your new question if you are going to abandon your post for three months again?

TDK_Man

Area 51
19
Years of Service
User Offline
Joined: 3rd Feb 2006
Location: UNKNOWN
Posted: 26th Feb 2008 01:56
srry

Are we alone?
Bluestar4
19
Years of Service
User Offline
Joined: 19th Dec 2005
Location: USA
Posted: 26th Feb 2008 15:14
tdk, that it is actually a very good question he ask - for the benifit of anyone else who might stumble across the thread it would be nice for you to answer him [ I would like to hear your opinion on it ]

TDK
Retired Moderator
22
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 26th Feb 2008 20:06
Here you go - without using Sparky's...



TDK_Man

Libervurto
18
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 26th Feb 2008 21:04
@TDK
How would you calculate the 3D co-ordinate from the mouse position?
I'm assuming it involves things like FOV

TDK
Retired Moderator
22
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 27th Feb 2008 00:12
Calculating the matrix position is only possible with a flat matrix - which limits it's usefulness.

I could never figure out how to use this method on a randomized matrix.



TDK_Man

Login to post a reply

Server time is: 2025-06-04 01:52:42
Your offset time is: 2025-06-04 01:52:42