Ray query with MOGRE
From Ogre Wiki
The MOGRE classes and its members are different to the Ogre API, especially at the ray tracing. This was very confusing to me. Also there are generally only few informations about Mogre. So I simplified my code to show other Mogre users how to do. --Beauty
For example with a ray from a person into depth you can clamp the person to the ground.
Notice:
- only the bounding boxes (AABB) will be hit, not the object itself (see picture)
- unvisible objects can be hit, too
- at least one frame must be rendered to get a result
- for rays related to a SceneNode you should use WorldPosition and WorldOrientation to set ray Origin and Direction
- this code was tested with Terrain Scene Manager (if it also works with other ones, please add a note here)
Code snippet
//-- set params --
Vector3 startPosition = new Vector3(0, 0, 0);
Vector3 rayDirection = new Vector3(0, -1, 0); // here: ray into depth
// OR use position and orientation of a SceneNode
//SceneNode someNode = mScene.Smgr.GetSceneNode("name_of_node");
//Vector3 startPosition = someNode.WorldPosition;
//Vector3 rayDirection = someNode.WorldOrientation.XAxis; // in this case: base quaternion direction is along XAxis
Ray myRay = new Ray(startPosition, rayDirection);
RaySceneQuery raySQuery = mScene.Smgr.CreateRayQuery(myRay);
// optionally sort the results
raySQuery.SetSortByDistance(true); // second possible parameter: maxResults
//-- calculate --
Vector3 rayHitPoint;
Single rayDistance;
String rayHitPointName = "";
RaySceneQueryResult raySQResult = raySQuery.Execute();
RaySceneQueryResultEntry raySQREntry;
for (Int16 i = 0; i < raySQResult.Count; i++) // for all hits
{
raySQREntry = raySQResult[i];
rayDistance = raySQREntry.distance;
rayHitPoint = myRay.Origin + (myRay.Direction * rayDistance); // calculate hit point
// save names of objects (or world fragment) that was hit
if (raySQREntry.worldFragment != null)
rayHitPointName = raySQREntry.worldFragment.ToString();
if (raySQREntry.movable != null)
rayHitPointName = raySQREntry.movable.Name;
// Also bounding boxes of terrains can be hit.
// Skip them to prevent hits on strange places ("just in the air").
if (rayHitPointName.StartsWith("tile[")) // e.g. "tile[1][1,1]"
continue;
// ... do something with the hit ...
if (raySQREntry.worldFragment != null)
{
// ... only do something with hits to terrain
}
if (raySQREntry.movable != null)
{
// ... only do something with hits to other objects
}
// If you just want to find a special hit, you can leave the for() loop.
// The results will be stored in the variables (rayHitPoint, raySQREntry etc.)
if (this_is_your_hit)
break;
} // for
//-- if nothing was hit --
if (raySQResult.IsEmpty)
{
// ... do something ...
// e.g. prevent null values
rayHitPoint = Vector3.ZERO;
rayDistance = 0;
rayHitPointName = "no_hitPoint";
}
See also
- Ray classes in MOGRE
- RaySceneQuery Class Reference
- MOGRE Line 3D (to show the ray line)
- Raycasting to the polygon level (Mogre) (to avoid incorrect hits)
Keywords: rays rayquery rayscenequery query


