OGRE Wiki
Support and community documentation for Ogre3D
Ogre Forums
ogre3d.org
Log in
Username:
Password:
CapsLock is on.
Remember me (for 1 year)
Log in
Home
Tutorials
Tutorials Home
Basic Tutorials
Intermediate Tutorials
Mad Marx Tutorials
In Depth Tutorials
Older Tutorials
External Tutorials
Cookbook
Cookbook Home
CodeBank
Snippets
Experiences
Ogre Articles
Libraries
Libraries Home
Alternative Languages
Assembling A Toolset
Development Tools
OGRE Libraries
List of Libraries
Tools
Tools Home
DCC Tools
DCC Tutorials
DCC Articles
DCC Resources
Assembling a production pipeline
Development
Development Home
Roadmap
Building Ogre
Installing the Ogre SDK
Setting Up An Application
Ogre Wiki Tutorial Framework
Frequently Asked Questions
Google Summer Of Code
Help Requested
Ogre Core Articles
Community
Community Home
Projects Using Ogre
Recommended Reading
Contractors
Wiki
Immediate Wiki Tasklist
Wiki Ideas
Wiki Guidelines
Article Writing Guidelines
Wiki Styles
Wiki Page Tracker
Ogre Wiki Help
Ogre Wiki Help Overview
Help - Basic Syntax
Help - Images
Help - Pages and Structures
Help - Wiki Plugins
Toolbox
Freetags
Categories
List Pages
Structures
Trackers
Statistics
Rankings
List Galleries
Ogre Lexicon
Comments
History: Ray query with MOGRE
View page
Source of version: 10
(current)
The Ray Query class members in Mogre looks a little bit different to the Ogre API. Don't be confused by that. Mogre offers the same functionality. An example for ray usage: A character should walk on terrain. So you need to clamp it to the terrain surface. After each movement, you perform a ray query straight downwards and read out the distance to the terrain. As result you know how to change the heigth value of the characters position. Notes: * Only the ((-AABB|bounding boxes)) (AABB) will be hit, not the object itself (see picture). ** If you need distances on polygon level, look ((Raycasting to the polygon level - Mogre|here)). * Unvisible objects can be hit, too. * At least one frame must be rendered to get a result. * For rays starting from (or pointing to) a ((-SceneNode|SceneNode)) you should call ''myNode._getDerivedPosition()'' and ''myNode._getDerivedOrientation()'' to get the wanted values for ''Ray.Origin'' and ''Ray.Direction''. * If you use the ((Terrain Scene Manager)) (outdated, removed in Ogre 1.8), be aware that the distance is not very precise. ** The returned distance is too long (up to 1 Ogre length unit). A demonstration screenshot is [http://www.ogre3d.org/forums/viewtopic.php?p=444816#p444816|here]. ** An easy to use workaround for precise terrain distances was published [http://www.ogre3d.org/forums/viewtopic.php?p=444900#p444900|here]. ** I repeat again: This issue is only related to the Terrain Scene Manager (and forks). The new Ogre Terrain Component works well by default. {img src="img/wiki_up/Rays_and_BoundingBox_1a.gif" alt="Rays and BoundingBox 1a.gif"} !!Code snippet {CODE(wrap="1", colors="c#")} //-- 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._getDerivedPosition; //Vector3 rayDirection = someNode._getDerivedOrientation.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 {CODE} {CODE(wrap="1", colors="c#")} //-- 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{CODE} {CODE(wrap="1", colors="c#")} //-- if nothing was hit -- if (raySQResult.IsEmpty) { // ... do something ... // e.g. prevent null values rayHitPoint = Vector3.ZERO; rayDistance = 0; rayHitPointName = "no_hitPoint"; }{CODE} !!Query flags Query flags are a simple way to create a filter for ray queries. For this you can define "masks" (flags) to several scene objects (e.g. for enemies, walls, etc.) and for your ray queries you tell Ogre, which objects you want to get or ignore. Here is a pseudo code example: {CODE(wrap="0", colors="c#")} (put this enum in a shared class) [FlagsAttribute] // optional, but it makes clear, that this is a flag enum. enum QueryMasks : uint //Depends on your needs, but I need a lot of flags and bit shifting needs big numbers (int = 32bit = 32 flags, byte = 8 bit = 8 flags, ...). { Ground = 1<<0, //bit shift required (2,4,8,16,32,64,128,256,...) Wall = 1<<1 [...] } (somewhere in your code, e.g. in CreateScene()) Entity Groundent = (...); Groundent.QueryFlags = QueryMask.Ground; //assign a custom query flag (Somewhere in FrameStarted or similar) static CollisionTools ct = new CollisionTools(MySceneMgr); //C# does not support static variables in methods (VB.Net does ;) ), make a global var instead var Result = ct.RaycastFromCamera(RenderWindow, Camera, ScreenPosition, QueryMask.Ground); //search for a specific query flag if (Result != null) { //success, this has to be an entity with the Mask "Ground". } {CODE} For more details about query flags read the ((Intermediate Tutorial 3|#Query_Masks)). {REMARKSBOX(type="note",title="Alternatives",highlight="y",width="30%")}There are of course helper classes to make raycasting easier. Here are some: [https://code.google.com/p/minimal-ogre-collision-toolkit/|MMOC (C# port of MOC)] (used in example above) [http://www.ogre3d.org/forums/viewtopic.php?p=446083#p446083|Beauty's class (Preview release)] Both support ray casting to polygon level (very accurate but slow) Of course, you could just query all AABBs: [http://www.ogre3d.org/docs/api/html/classOgre_1_1RaySceneQuery.html|RaySceneQuery API] That is of course the fastest method but very inaccurate. Another alternative: Most of the physics libraries have ray casting features, e.g. [http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Collision+detection+with+Newton|using Newton] or Physx. {REMARKSBOX} {REMARKSBOX(type="warning",title="Performance")}I never did speed tests but all raycasting to polygone level are brute force attacks. All mentioned classes just iterate through all triangles of the meshes returned by a RayQuery. That's not soooo slow but just use this technique wise: Do you really need to do 20 raycasts to poly level (per frame)? Maybe just do it once and cache the result. Or prefilter the objects (that may need so tweaking of the helper classes), e.g. store all objects in a certain distance to your player and skip the rest. An real alternative could be the "[http://www.ogre3d.org/tikiwiki/Selection+Buffer|Selection buffer]" (only c++): It colors all visible meshes in the scene for one frame in a (random but unique) color and returns the mesh at a specific screen cooridinate. This method (of course) only works for raycasting from the camera... {REMARKSBOX} !!See also * ((Ray classes in MOGRE)) * [http://www.ogre3d.org/docs/api/html/classOgre_1_1RaySceneQuery.html|RaySceneQuery Class Reference] * ((MOGRE Line 3D)) (to show the ray line) * ((Raycasting to the polygon level - Mogre)) (to avoid incorrect hits)
Search by Tags
Search Wiki by Freetags
Latest Changes
FMOD SoundManager
HDRlib
Building Ogre V2 with CMake
Ogre 2.1 FAQ
Minimal Ogre Collision
Artifex Terra
OpenMB
Advanced Mogre Framework
MogreSocks
Critter AI
...more
Search
Find
Advanced
Search Help
Online Users
33 online users