How to get XZ with mouse?[Solved]

Problems building or running the engine, queries about how to use features etc.
Post Reply
mrmclovin
Gnome
Posts: 324
Joined: Sun May 11, 2008 9:27 pm
x 20

How to get XZ with mouse?[Solved]

Post by mrmclovin »

How can I get the XZ point the mouse is pointing at where intersection Y = 0. Just like if I wanted to place some object at the "floor". I'll show in a picture.

Image
Last edited by mrmclovin on Wed Dec 03, 2008 9:15 pm, edited 1 time in total.
milacao
Goblin
Posts: 231
Joined: Thu May 08, 2008 10:39 am
Location: Barcelona, Spain

Post by milacao »

You can use a ray:

Code: Select all

Ray mouseRay = mCamera->getCameraToViewportRay( e->getX(), e->getY() ); 
Where e is a mouseEvent object.
Then, with this ray you can calculate if it actually intersects the plane Y=0 with its member function:

Code: Select all

std::pair< bool, Real > 	intersects (const Plane &p) const 
The result pair means:
- bool: true if the ray intersects the plane
- Real: the distance along the ray where the intersection is located.

Then, if the intersection is true, you can use the function

Code: Select all

getPoint(Real d)
with the distance to get a Vector3 object with the coordinates of the intersection point, that will be in the form (X, 0, Z).

I hope this is what you need.
Regards.
mrmclovin
Gnome
Posts: 324
Joined: Sun May 11, 2008 9:27 pm
x 20

Post by mrmclovin »

Hey, thanks, that should probably do it! I have a question though. In this case I have a Plane, but what if I didnt? Lets say I'd want to place an object in empty space (no Planes, terrain and so on) on Y = 0 level. Is that not possible?
milacao
Goblin
Posts: 231
Joined: Thu May 08, 2008 10:39 am
Location: Barcelona, Spain

Post by milacao »

That's the same. You can do the same operations although the plane is not "physically" there. You can just "imagine" it.
mrmclovin
Gnome
Posts: 324
Joined: Sun May 11, 2008 9:27 pm
x 20

Post by mrmclovin »

Okey, so you mean that I have to create a Plane (obviously because intersects() takes one as param), but I do not attach a mesh to it?

Another question:
It seems that my scenenodes dont get postioned where the mouse intersect. In what vectorspace does getPoint() return, the camera's?
milacao
Goblin
Posts: 231
Joined: Thu May 08, 2008 10:39 am
Location: Barcelona, Spain

Post by milacao »

I have to create a Plane (obviously because intersects() takes one as param), but I do not attach a mesh to it?
Right.

Regarding spaces, I suppose getPoint returns coordinates in world space. Your scenenodes position will depend on their parent. If this parent is not in (0, 0, 0), your scenenodes will not appear in the right place.
mrmclovin
Gnome
Posts: 324
Joined: Sun May 11, 2008 9:27 pm
x 20

Post by mrmclovin »

The getPoint() returns all kind of funny positions. Even if I don't point at the floor it thinks that the mouse intersects ground floor. Perhaps I've not created the plane properly?

Code: Select all

			Plane plane(Vector3::UNIT_Y, 0);
			Ogre::MeshManager::getSingleton().createPlane("ground",
			   ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
			   plane,
			   1500,1500,
			   20,20,
			   true,
			   1,
			   1500,1500,
			   Vector3::UNIT_Z
			   );
			Entity* ent = mSceneMgr->createEntity("Ground", "ground");
			ent->setMaterialName("GameProject/GroundPlane");
mPlane = &plane;
Here's the code when about to ray:

Code: Select all

		bool LevelEditor::mouseMoved(const OIS::MouseEvent &arg){
			Ray mouseRay = mCamera->getCameraToViewportRay(arg.state.X.abs, arg.state.Y.abs);
			std::pair<bool, Real> result = mouseRay.intersects((*mPlane));
			if(result.first) {
				Vector3 point = mouseRay.getPoint(result.second);
				mCurrentObject->setPosition(point);
			}
			return true;
		}
User avatar
volca
Gnome
Posts: 393
Joined: Thu Dec 08, 2005 9:57 pm
x 1
Contact:

Post by volca »

Maybe the mPlane pointer is to a local variable? Then if you use it is is already pointing to invalid data? Try storing Plane mPlane; instead of Plane* mPlane; - you get the point...
Image
mrmclovin
Gnome
Posts: 324
Joined: Sun May 11, 2008 9:27 pm
x 20

Post by mrmclovin »

Oh, you've got a point there.. Ehm, how should I do then? The plane is created in the constructor ! Should I create a new plane every time mouse is moved?

[edit]Of course. Store a Plane mPlane instead.:oops: [/edit]
mrmclovin
Gnome
Posts: 324
Joined: Sun May 11, 2008 9:27 pm
x 20

Post by mrmclovin »

Okey, fix the mPlane now. Should be valid. My object are placed on the ground not in where the mouse is pointing? More hints ..?
User avatar
volca
Gnome
Posts: 393
Joined: Thu Dec 08, 2005 9:57 pm
x 1
Contact:

Post by volca »

Hmm. The arg.state.X.abs/Y is in pixels, and getCameraToViewportRay needs 0-1 range for on-screen. Normalising to 0-1 is needed. May not solve the problem, but should be done. :)
Image
mrmclovin
Gnome
Posts: 324
Joined: Sun May 11, 2008 9:27 pm
x 20

Post by mrmclovin »

Yeah, that did the trick. Thanks! :D
User avatar
volca
Gnome
Posts: 393
Joined: Thu Dec 08, 2005 9:57 pm
x 1
Contact:

Post by volca »

You're welcome!
Image
User avatar
xadhoom
Minaton
Posts: 973
Joined: Fri Dec 28, 2007 4:35 pm
Location: Germany
x 1

Post by xadhoom »

mrmclovin: May I ask you for the resulting code snippet? Maybe this would be a nice piece for the Wiki.
mrmclovin
Gnome
Posts: 324
Joined: Sun May 11, 2008 9:27 pm
x 20

Post by mrmclovin »

Sure! I thought this would be a good time to set up my first wiki page: http://www.ogre3d.org/wiki/index.php/Mouse_ray. I didnt have time to correct the code and spellning so feel free to edit! And I did'nt create a link from the HOWTO and Snippets content page until the code is confirmed working. Night!
User avatar
xadhoom
Minaton
Posts: 973
Joined: Fri Dec 28, 2007 4:35 pm
Location: Germany
x 1

Post by xadhoom »

Thanks! :P

BTW: Why did you divide the absolute cursor position by screen size? Can´t you just use state.X.rel ? (One comment in OIS indicates that relative values do not work with a joystick )
mrmclovin
Gnome
Posts: 324
Joined: Sun May 11, 2008 9:27 pm
x 20

Post by mrmclovin »

Because, at least I think, relative won't tell you where the cursor actually is on the screen but tell you where the cursor is relative to its last position before it was moved. Another reason I used absolute is because the GUI I'm using (MyGUI), the mousecursor's position is injected by absolute values. That means I can be sure of that OIS and MyGUI are synchronized.
User avatar
xadhoom
Minaton
Posts: 973
Joined: Fri Dec 28, 2007 4:35 pm
Location: Germany
x 1

Post by xadhoom »

Got it! :P
User avatar
Jdog
Gnoblar
Posts: 12
Joined: Sun Apr 05, 2009 12:02 pm
Location: Pretoria, South Africa

Re: How to get XZ with mouse?[Solved]

Post by Jdog »

Help! My mouse cursor just seems to jump to the top-left corner and stays there. Why could this be?

My code is below - I'm doing this in the FrameStarted function, but when I tried to reproduce the code in MouseMoved, it cause the exact same effect.

Code: Select all

OIS::MouseState mouseState = mMouse->getMouseState();		

	const MyGUI::IntPoint& mousePos = MyGUI::InputManager::getInstance().getMousePosition();

	Ogre::Real offsetX = mouseState.X.abs / mRoot->getAutoCreatedWindow()->getWidth();
	Ogre::Real offsetY = mouseState.Y.abs / mRoot->getAutoCreatedWindow()->getHeight();

		
	Ray mouseRay = mCamera->getCameraToViewportRay(offsetX, offsetY);

	std::pair<bool, Real> result = mouseRay.intersects(mPlane);
		

	if (result.first)
	{
		Vector3 point = mouseRay.getPoint(result.second);
		char1->getSightNode()->setPosition(point);
	}
I created the plane in another method and I believe this might be the culprit too (becuase well...I don't understand it!) But why would the mouse cursor jump to the top left??
I'm using myGUI and my mouse cursor moves around properly there (at least?)

Also, before I was using a pointer to the plane, as well as the following line:

Code: Select all

Ray mouseRay = mCamera->getCameraToViewportRay(mousePos.left / float(mouseState.width) ,mousePos.top / float(mouseState.height) );
... which created the node on the plane, but it was a bit off - not on the correct spot. Please help, I'm so frustrated right now! :(
User avatar
Jdog
Gnoblar
Posts: 12
Joined: Sun Apr 05, 2009 12:02 pm
Location: Pretoria, South Africa

Re: How to get XZ with mouse?[Solved]

Post by Jdog »

Fixed! The problem was solved by these two lines:

Code: Select all

	Ogre::Real offsetX = float(mouseState.X.abs) / mRoot->getAutoCreatedWindow()->getWidth();
	Ogre::Real offsetY = float(mouseState.Y.abs) / mRoot->getAutoCreatedWindow()->getHeight();
Russel
Gnoblar
Posts: 3
Joined: Sun May 13, 2012 11:27 am

How to get XZ with mouse?[Solved]

Post by Russel »

Hi guys
I am very new to Ogre and have kind of been dropped in the deep end. (Time constraints)
So basically i made use of this code and it works perfectly.
The only problem is that for some reason it only works in the top left corner of the screen. My camera is at
0, 0, 250
My object's starting point is
50, 50, 50
If i click anywhere else in the screen the object moves to the bottom right corner of the block that’s in the top left corner, sorry of that sounds complicated or does not read well, but if i click in the block the object moves to my cursor like its meant to.
The plane i am using is

Code: Select all

Ogre::Plane mPlane(Ogre::Vector3::UNIT_Y, 50);
I have tried setting the object's starting point to
50, 0, 50
and

Code: Select all

Ogre::Plane mPlane(Ogre::Vector3::UNIT_Y, 0); 
but this did not help. There are other things that i am confused about such as what is going to happen when i change the view but that i will learn when i get there.

Am i correct in assuming that if i set my camera to 250 on the Z axis i should be able to see negative 125 to positive 125 on both the x and the y axis?

Any help or pointers to what might be wrong will be much appreciated!
Russel
Gnoblar
Posts: 3
Joined: Sun May 13, 2012 11:27 am

Re: How to get XZ with mouse?[Solved]

Post by Russel »

Sorted it out.
Turns out it was because i was not using a mouse event, so the mouse object did not know how big my screen was. It defaults to 50.
So if anyone else is doing this the same way i was just add

Code: Select all

_Mouse->getMouseState().height = screenHeight;
_Mouse->getMouseState().width = screenWidth;
after

Code: Select all

Ogre::Real screenWidth = Ogre::Root::getSingleton().getAutoCreatedWindow()->getWidth();
Ogre::Real screenHeight = Ogre::Root::getSingleton().getAutoCreatedWindow()->getHeight();
Post Reply