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 / object selection

Author
Message
pictionaryjr
15
Years of Service
User Offline
Joined: 12th Mar 2009
Location:
Posted: 8th Jun 2010 10:51 Edited at: 8th Jun 2010 10:54
Alright, I've been working on object selection and I can do a group selection just by using screen x and screen y and checking mouse value, but when i just try to select one object, im not going to perfectly click that object position. so i was trying to do a type of polygon collision or something to select it, but i can't get the angle.

Here are some screenshots to better explain what i'm trying

Group selection:


Single selection:


I can't figure out how to select the circled object, its not directly in front of the camera and i don't want to make it so the player always does group select. think of age of empires how you can click on one object or select a group. how could i achieve that effect

Dia
19
Years of Service
User Offline
Joined: 16th Jan 2005
Location:
Posted: 8th Jun 2010 13:28
is this 3d?

if so check out the PICK OBJECT command

This is not the Sig you are looking for....
Robert The Robot
17
Years of Service
User Offline
Joined: 8th Jan 2007
Location: Fireball XL5
Posted: 8th Jun 2010 13:51
Isn't Pick Object is a DBpro command?

I have a theory - if you're dealing with spheres only, then you know the radius in 3D units. Position two test objects (plains) at the 3D XYZ coordinate of the sphere. Now move them so that they are a the edges of the sphere you're clicking on (not too sure how to do this, probably using turn object left/right, move object).

Get the screen coordinates of these two test objects (Object screen X, object Screen Y), find the magnitude of this distance (or approximate using whichever x or y is larger) nd you have the pixel diameter of the sphere. Now check if the mouse pointe x coord is inside a region of this size, that is centered over te sphere's screen coords.

It's a complex method, and probably quiteslow, but i'm sure ther are optimisations you could add, depending on where the camera was placed, how often the camera moved (which would change the apparen pixel size)


More simply, you could just use a 3D cursor, so that as the mouse moves a hidden Cube moves around the 3D world. Say the Z-axis doesn't matter, if the x or y coord of the 3D object is in range of the cube then you could say it's been "clicked".

hope this helps!

"I wish I was a spaceman, the fastest guy alive. I'd fly you round the universe, in Fireball XL5..."
Dia
19
Years of Service
User Offline
Joined: 16th Jan 2005
Location:
Posted: 8th Jun 2010 16:18
oh yeah my bad, really should check what forum section I am in *sigh*

This is not the Sig you are looking for....
LBFN
17
Years of Service
User Offline
Joined: 7th Apr 2007
Location: USA
Posted: 8th Jun 2010 17:02
You need to look at object screen x(obj) and object screen y(obj). Here is some example code:



LB
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 8th Jun 2010 18:41
Using Object screen x() and y has limited use. You can't always count on the objects pivot being at the center of it's verts, and object screen x and y will report on 3d object positions that are behind the camera as well as in front of it.

I think a better method is to project a 3d ray or object from the mouse position into the screen. You can use collision testing to return the object that is intersected by the projection. This isn't as hard as it sounds. Because a monitor view is 2d, you can use right triangle math to get the necessary ratios for the mouse position from 2d to 3d, and matrix rotation math to figure out the projection. Here's a pretty decent example:

object select

Enjoy your day.
TheComet
16
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 8th Jun 2010 20:04
maybe you will find some help here:

http://forum.thegamecreators.com/?m=forum_view&t=160347&b=10

TheComet

pictionaryjr
15
Years of Service
User Offline
Joined: 12th Mar 2009
Location:
Posted: 10th Jun 2010 01:14 Edited at: 10th Jun 2010 02:25
alright. i tried getting the a pick object type command using sparky's and casting a ray. everything seems to be right, but i'm just confused how i would take the camera's rotation and position into matter.

Here's what I have so far any help would be appreciated



What i did is got the distance from the eye to the screen by using half the fov and half the screen width.


Then i got the tangent angle to the mouse position by dividing the eye to screen distance by the distance that u get from subtracting the mouse and half the screen


Then i got the position for the ray by adding the distance i want the ray to be casted to the distance from the eye to the screen and dividing it by the tangent angle i go to the mouse position


BN2 Productions
20
Years of Service
User Offline
Joined: 22nd Jan 2004
Location:
Posted: 10th Jun 2010 03:34 Edited at: 10th Jun 2010 03:43
You can use a rotation matrix.

DBC doesn't support matrices so here is what it boils down to:



Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
pictionaryjr
15
Years of Service
User Offline
Joined: 12th Mar 2009
Location:
Posted: 10th Jun 2010 03:45
what exactly is a rotation matrix?

BN2 Productions
20
Years of Service
User Offline
Joined: 22nd Jan 2004
Location:
Posted: 10th Jun 2010 04:00
Its hard to do in ASCII, but I will try:

A way to rotate a vector through angle theta is using the rotation matrix like so:


What you do is take the transpose of the vector (to turn it into a matrix) and multiply it by the rotation matrix. That looks like this:
V=<x,y>
(V is the vector Vt means the transpose)


The transpose of a matrix is essentially mirroring it along a 45 degree line. For example:


Back to the math of the op:

If you multiply Vt*[R] (the rotation matrix) it will yield a matrix with results of the new locations after rotating.

Here is the math (assume that the ray extends from your position to 3 units ahead). I don't know how to do this in 3 dimensions, but you can pull it off in 2, where the vector V=<x,z> (which I put in a matrix form for the example here)


Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 10th Jun 2010 05:03 Edited at: 17th Jun 2010 17:27
@pictionaryjr
Quote: "Here's what I have so far any help would be appreciated"



Your xwidth and ywidth seem to be fixed for a 640x480 resolution. Maybe this diagram will help with conversion of 2d screen positions to 3d positions:



[EDIT]
y3d# is in error on the chart. it should read

y3d#=((distance from camera)*((screen height()/2)-y2d))/zdist#
[/EDIT]

Enjoy your day.
pictionaryjr
15
Years of Service
User Offline
Joined: 12th Mar 2009
Location:
Posted: 10th Jun 2010 08:55
i've figured out how to get the distance to the monitor, what i'm having trouble with is transfering it to a point in 3d space

Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 10th Jun 2010 10:32
the 3d X value = ((distance from camera)*((mousex()-(screen width()/2)))/zdist#
the 3d Y value = ((distance from camera)*((screen height()/2)-mousey()))/zdist#

The distance from the camera is how far you want to project into the screen. You'll always start your projection from 1 unit in front of the camera - so that would be your first set of values. Then you decide how far into the screen you want to project for your second set of values. The ray is cast from the start to the end.

See BN2's notes for rotating the points according to the camera position, or look at the link I posted a few messages above with a working object select

Enjoy your day.
pictionaryjr
15
Years of Service
User Offline
Joined: 12th Mar 2009
Location:
Posted: 12th Jun 2010 00:33
then how do you get the distance from the camera?

Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 12th Jun 2010 01:22 Edited at: 12th Jun 2010 09:10
You decide on the distance from the camera. You are checking a ray cast from the start of the screen to some units into the screen. You could make your distance whatever you want. If you want to check 10000 units into the screen, then that's the distance. You want to detect collision between your start and end points.

For use with Sparky's, you ultimately want 2 points:

x1,y1,z1

which is the calculated mouse position where distance = 1
the 3d X value = ((1)*((mousex()-(screen width()/2)))/zdist#
the 3d Y value = ((1)*((screen height()/2)-mousey()))/zdist#
the 3d Z=1

and

x2,y2,z2

which is the calculated mouse position where distance = 10000
the 3d X value = ((10000)*((mousex()-(screen width()/2)))/zdist#
the 3d Y value = ((10000)*((screen height()/2)-mousey()))/zdist#
[EDIT]
the 3d Z=10000
[/EDIT]

Once you have these values, you rotate them with the matrix rotation equations. Then you add the camera position to them. Then you plug them into the sparkys collision intersect command.

Make any sense?

In fact, you don't need sparkys or any collision detection. If you get your end points of the ray, you could use an object's Get Object Size() command and offset a bounding box based on it's location. Then you see if your ray passes through the bounding box (this is the start of ray collision detection) - but stick with sparkys for now because it's already done for you.

Hmmm after all this talk, I just got an idea for the DarkPros FPS game....

Enjoy your day.
pictionaryjr
15
Years of Service
User Offline
Joined: 12th Mar 2009
Location:
Posted: 12th Jun 2010 05:26
wait. the z value doesn't change so it wouldn't move outwards to collide with the objects?

Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 12th Jun 2010 09:46 Edited at: 12th Jun 2010 09:50
Quote: "wait. the z value doesn't change so it wouldn't move outwards to collide with the objects?"

ooops! I left the second Z=1; it should be Z=10000 - changed it above.

Just what you needed to make it confusing huh?

And just to hammer the point home, those x,y,z values are the relative values based on location 0,0,0 . You need to start with those and then rotate them based on the camera's angles. Once you rotate them, they will have different values. For example,

point 0,0,10000 rotated 90 degrees around the y axis becomes 10000,0,0

Back to the projected values, after you rotate them based on the camera's angles (around each axis 1 at a time) you then have to add the camera position to the values. Your final points will be projected based on the current camera rotation and position and the mouse screen position.

I'm assuimg a lot with all this, like you really want to know the mechanics of choosing a 3d object with a 2d mouse. So forgive me if you just want something that works most of the time without the coding/math overhead.

If you want to solve this yourself and understand the whole thing, read up on matrix multiplication and rotation. You will need to derive six rotation formulas and use them in sequence. There are actually 9 rotations (3 axes and 3 coordinates = 3x3 = 9) but a rotation around any individual axis doesn't change the value of the relative coordinate (i.e. X doesn't change if you rotate around the x axis, Y doesn't change if you rotate around the y axis, Z doesn't change if you rotate around the z axis).

I highly recommend getting a good understanding of this because you'll be able to apply the principals to any 3d environment where you want to project a 2d coordinate (like the mouse position) straight into the screen.

If this seems like too much work and you just want to select your objects, use OBJECT SCREEN X() and OBJECT SCREEN Y() as others have suggested and you started out with to select your groups.

LBFN posted an example of matching towards the closest object. You could modify it to make a "snap to" so the mouse snaps to the pivot point of the object when clicked near it.

Enjoy your day.
pictionaryjr
15
Years of Service
User Offline
Joined: 12th Mar 2009
Location:
Posted: 12th Jun 2010 09:53 Edited at: 12th Jun 2010 17:47
No what yall gave is perfect. I almost got it working perfectly. I just used repeated right triangle math except without the confusing ratios that yall used and i don't have all that cosine stuff. I knew i would have to rotate it from the camera's angles and I would have never been able to figure out how without yalls rotation matrix help. I'll paste the function as soon as I get it working. may be able to benefit some people. it will use sparky's and what it does is returns the object the mouse collided with. =)

Edit:

Here's the function so far. I've just got to add when you rotate the camera up or down and figure out why the location is just a little off =)

For the function to work, you need sparky's and the object needs to be loaded into sparky's.



Edit:
I got it working perfectly now, besides a y matrix rotation. I'm having a bit of trouble with it.



There is one strange thing about the selection. For some reason when I got the distance for the mouse. I had to multiply them by a random ratio, different number for the height and width. I can't find the numbers relation to the equation tho. I'm not sure if it has to do with ratio's or not. Thats just my guess.

xwidth#=(mx-(screen width()/2))/1.15
ywidth#=(my-(screen height()/2))/1.4

I have no idea what the 1.15 or 1.14 are used for but they make it work.

Edit:

Finally done!

I still don't understand the ratios and would love for someone to explain them, but in the meantime. Here's the function if anyone would like it. you just need sparky's and to set the object up as a collision object.



EdIt:
Just found a bug where if the x and y angles are both changed. the calculations are off. Will fix

This has been a lot of edits. guess you gotta do what it takes to not double post lol

pictionaryjr
15
Years of Service
User Offline
Joined: 12th Mar 2009
Location:
Posted: 12th Jun 2010 20:17
Ok I'm stumped and in need of help. I understand the transformation matrix, I got it to work where i can rotate the x axis if the y axis hasn't rotated or i can rotate the y axis if the x axis hasn't rotated. but if they've both been rotated it messes up the calculation. Any help and this should be the last time =)



Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 17th Jun 2010 17:21
It seems you're going in a little bit different of a direction than what I was suggesting, that's fine if it works for you.

I'm not sure where you got the 1.5 and 1.4 ratios, and

ywidth#=(my-(screen height()/2))

I think should be changed a bit because y increases as it goes down on the screen in 2d but decreases in 3d (if the camera is oriented to 0,0,0 - I think I made a typo in my chart)

ywidth#=((screen height()/2)-my)

Also you should be doing 3 rotations (Z X and Y) each time. The point has to be completely rotated in 3d world space opposite of the camera orientation.

Hope that helps.

Enjoy your day.
pictionaryjr
15
Years of Service
User Offline
Joined: 12th Mar 2009
Location:
Posted: 21st Jun 2010 07:04
I don't remember what I did, but I reversed that for the ywidth elsewhere in the code.
and I am doing it different. in any example i seemed to get. they were rotating and object from angles they calculated and pointing at a spot in 3d space. or something of the sort. and then they get the 3d point from that. I want to do it without the dummy object. I get it to work correctly with either the x or y angle being 0, but when both are rotated. it screws up.

pictionaryjr
15
Years of Service
User Offline
Joined: 12th Mar 2009
Location:
Posted: 21st Jun 2010 21:15
Yea I am going in a bit of a different direction. Instead of using a dummy object and positioning it. i want to calculate it all with math. and i tried rotating all 3, but it simply does nothing. I only rotate on the x and y axis anyways, so it isn't that big of a deal. The problem is. I can get the rotation to work, when im just rotating the x or the y axis, but when both axis are rotated. the calculations then mess up.

And with the ywidth. i think ireverse it elsewhere in the code

Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 21st Jun 2010 22:47
Here's some pseudo code of the process:




Even if you are just rotating your 3d objects/world on the x and y axis, you have to complete your calculations of the rotations for for your ray on all 3 axes because rotations on any 2 can affect the rotation of a 3rd.

The order of the axis rotation becomes very important when you are making your calculations. Object rotations and camera rotations are actually opposite of each. Since your ray is based on the cmaera angles, your rotation order is X Y Z unless you use SET CAMERA ROTATION ZYX somewhere earlier in your code.

Like I stated before, your rotation calculations will come down to 9 equations (6 actually because rotation of a coordinate around it's own axis doesn't change it's value). 3 equations for each axis you will have to rotate your ray points around. That means 3 rotations for the start of the ray, and 3 rotations for the end of the ray. That will come down to 18 calculations (really 12) to rotate the entire ray.

For example, just rotating the start coordinates around the x axis would be:


Now you'd have to take those results and then rotate them around the y and then the z axis. You'll have to figure out the equations to use for y and z rotation, but you have to rotate the point around all three axes or else the value won't be correct. You may also have to adjust your angles initially because of the direction of rotation.

The best way to test where your points are ending up is to place temporary objects at the ray extremes and see where they end up as you move the mouse. That will give you clues as to what's going right or wrong with your calculations. Once it starts to sink in what you are looking for, you'll get a handle on your projection function. You're almost there!

Enjoy your day.
pictionaryjr
15
Years of Service
User Offline
Joined: 12th Mar 2009
Location:
Posted: 24th Jun 2010 04:43 Edited at: 24th Jun 2010 04:52
FINALLY!!!!!!!!!!!!!!!!!!!!!!!!!!!!
After completely redoing the matrix rotation. Turns out I did too much math. thanks for your help everyone. here's the finished function. i'll have a working example soon to show how it works.



Login to post a reply

Server time is: 2024-04-20 01:18:17
Your offset time is: 2024-04-20 01:18:17