Advice on 3D selection

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Abraxas)
Posts: 227
Joined: Sun Oct 18, 2009 7:24 am

Advice on 3D selection

Post by Abraxas) »

Currently I'm using the

Code: Select all

getRayFromScreenCoordinates (position2d<s32>(mousex,mousey)
Then for example I would do:

Code: Select all

	ray = collMan->getRayFromScreenCoordinates (position2d<s32>(mousex,mousey),0);
	selectedSceneNode =	collMan->getSceneNodeAndCollisionPointFromRay(ray, intersection, hitTriangle, 0, 0); 

Way to use my mouse as a pointer. What I've realised is that since the mouse is way behind the screen, if I intersect the ray with a plane such as (0,1,0) the point of intersection is NOT above my mouse, but somewhere halfway between the 'ray start' and where my mouse is.

What this means is that just because my mouse is over a scene node, it doesnt mean getRayFromScreenCoordinates will pass through it :(

I can provide screenshots if what I'm saying sounds like a bug.

Should I hide the windows mouse, and draw a cursor on the actual plane I'm interested as a billboard? Then I would have very good accuracy when doing selections. However, I wouldnt be able to move my 'cursor' to the rightmost and bottommost corners.

Does this sound right? or like something is fundamentally wrong?



(camera) (lets say (0,0,0), V is down on Y, > + on X)
\
-\
--\--(the intersection I find) (something like (5,-5) )
- -\
- --\ (where my mouse appears to be) (8 on X)

so when I do the test, it returns 5, not 8. Make sence? :S

Thanks!

EDIT:

Instead, if I find the ray.end, and cast a line with the negative vector of the camera lookat, from ray.end, would that be my 'offset' by mouse position? I'll try that tommorow when im fresh :P
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

The mouse cursor isn't behind or in front of anything, because the mouse is not rendered in 3d space, it is rendered on top of the window.

A perspective camera has a few attributes that control how the scene displays when looking through it. The view frustum is a truncated pyramid shape that describes these attributes. The camera is at the point of the pyramid, and the bottom corners of the pyramid are the corners of your screen. The function in question casts a ray from the camera position all the way to the back of the view frustum. If used properly, the ray should go through the position where the mousr cursor appears.

Travis
speculatius
Posts: 15
Joined: Wed Nov 28, 2007 12:49 pm

Post by speculatius »

I was doing something similar some time ago. You can think, that mouse cursor is in distance "camera->getNearValue()" from camera. Then you know angle, in which are you looking on scene = "camera->getFOV()". So you can calculate whatever you want using sin, cos etc.

This is from my code I found. May be it will be helpful:

Code: Select all

Cursor3D::OnAnimate() {

    // ...

	//
	// Finding position of 3D-cursor from ordinal mouse-cursor
	//

	// mapping of mouse-cursor's Y position on <-0.5, 0.5>
	core::rect<s32> viewPort = SceneManager->getVideoDriver()->getViewPort();
	core::dimension2d<s32> size = SceneManager->getVideoDriver()->getScreenSize();

	core::position2df mouseRelPos;
	mouseRelPos.X = (f32)(mousePos.X - viewPort.UpperLeftCorner.X) / size.Height;
	mouseRelPos.X -= ((f32)size.Width / size.Height) / 2.0f;
	mouseRelPos.Y = (f32)(mousePos.Y - viewPort.UpperLeftCorner.Y) / size.Height;
	mouseRelPos.Y -= ((f32)size.Height / size.Height) / 2.0f;

    // angles of view
	f32 n = parentCamera->getNearValue() - 0.3; // 0.3 is magic :)
	f32 angleX = atan2(mouseRelPos.X, n);
	f32 angleY = atan2(-mouseRelPos.Y, n);

	// new position of 3D-cursor
	core::vector3df newPos;
	newPos.Z = getPosition().Z; // 3D-cursor will stay in the same distance as before
	newPos.X = newPos.Z * tan(angleX);
	newPos.Y = newPos.Z * tan(angleY);
	setPosition(newPos);

	updateAbsolutePosition();

    // ...
}
Abraxas)
Posts: 227
Joined: Sun Oct 18, 2009 7:24 am

Post by Abraxas) »

I shouldve edited the title, but the reason it wasnt working as advertised was because the farvalue and nearvalue were 8 orders of magnitude apart.

These kinds of limitations are very frustrating, especially when you dont know they are the cause of the error.
Post Reply