Mouse Picking / scene queries

randomCoder

05-12-2006 16:05:19

Im attempting to translate the c++ mouse picking tutorials into something usable with mogre, but im running into a few problems.

1) i cant seem to create a ray scene query... i cant create a new RaySceneQuery();, as it complains no constructor has been selected/defined. I also cant seem to find a way to set its ray.

2) i cant seem to find a way to set a scene nodes bounding box to be drawn. I can find the property flag that is read only .BoundingBox, but nothing to set/change it.

any help would be appreciated :)

Bekas

05-12-2006 17:48:23

Like this:
RaySceneQuery q = sceneMgr.CreateRayQuery(ray);
//or set ray after creation
q.Ray = ray;

//clear it up
sceneMgr.DestroyQuery(q);

// show bounding box
node.ShowBoundingBox = true;

marc_antoine

11-01-2007 05:56:00

hey randomcoder do you make it work the mouse picking? do you have a simple example code like clicking a mesh and showing a messagebox displaying the name of the mesh? or a bounding box?

randomCoder

16-01-2007 01:28:31

Yeah, I made it work with no problem. Heres the code I use, sinc eI'm far to lazy to create a sample application:

I attach a mouse down event handler on the mogre panel like so (this == the current form im on):
this.mogrePanel.MouseDown += new MouseEventHandler(mogreWin.MouseDownHandler);

and here is my mogreWin.MouseDownHandler

public void MouseDownHandler(object sender, MouseEventArgs e)
{
//this uses the current width/height of the resizeable mogre panel to create the
//0.0 to 1.0 value ogre expects from a mouse
float mx = ((float)e.X) / this.mOgrePanel.Width;
float my = ((float)e.Y) / this.mOgrePanel.Height;

//create and execute the querry
RaySceneQuery raySceneQuery;
Ray mouseRay = camera.GetCameraToViewportRay(mx, my);
raySceneQuery = sceneMgr.CreateRayQuery(mouseRay);
raySceneQuery.SetSortByDistance(true);
RaySceneQueryResult rayResult = raySceneQuery.Execute();

if (e.Button == MouseButtons.Right)
{
//handle right button mouse press
}
else if (e.Button == MouseButtons.Left)
{
//handle the left button mouse press
mTranslationArrows.mouseDown(ref rayResult);
}
sceneMgr.DestroyQuery(raySceneQuery);
}


when i detect a click, im only looking for interaction with my translation arrows at the moment...here is the code i use to check what is actually clicked (from translationArrows.mouseDown()):

mID = a private member variable of type String that holds the GUID of the object, which is placed at the beggining of all the translation Arrows sceneNode names...so the name of its sceneNodes is mID + "ArrowLeftSceneNode".



public bool mouseDown(ref RaySceneQueryResult ray)
{
//iterate through the ray, from closest object to furthest object
//ignore what was hit first, so as long as the mouse clicked over
//this item, it does a mouse click event
for (int a = 0; a < ray.Count; a++)
{
if (ray[a].movable!=null)
{
if (ray[a].movable.ParentSceneNode.Name.Substring(0, mID.Length) == mID)
{
mouseClickEventHandler(ray[a].movable.ParentSceneNode.Name); //clicked! send it the name of the sceneNode in this object that registered the click
return true;
}
}
}
return false;
}


Im tired and have had way to much caffine, so let me know if this was any help -- if its not clear i can write up a sample application when im at work this week.

EDIT:
forgot the sceneMgr.DestroyQuery(raySceneQuery); at the end of the mouse down...fixed now though.