Ray query with MOGRE

From Ogre Wiki

Jump to: navigation, search

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)

Image:Rays and BoundingBox 1a.gif

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

Keywords: rays rayquery rayscenequery query

Personal tools
administration