public override void Dispose() { mRay.Dispose(); mRay = null; mRaySceneQuery.Dispose(); mRaySceneQuery = null; /*if (myLine != null) * { * SceneNode n = mSceneManager.GetSceneNode("Line1"); * if (n!= null) * n.DetachObject(myLine); * myLine.Dispose(); * }*/ myLine.Dispose(); myLine = null; mLog.Dispose(); mLog = null; base.Dispose(); }
public float GetTSMHeightAt(float x, float z) { float y = 0.0f; Ray updateRay = new Ray(); updateRay.Origin = new Vector3(x, 9999, z); updateRay.Direction = Vector3.NEGATIVE_UNIT_Y; RaySceneQuery tsmRaySceneQuery = this.sceneMgr.CreateRayQuery(updateRay); RaySceneQueryResult qryResult = tsmRaySceneQuery.Execute(); RaySceneQueryResult.Iterator i = qryResult.Begin(); if (i != qryResult.End() && i.Value.worldFragment != null) { y = i.Value.worldFragment.singleIntersection.y; } this.sceneMgr.DestroyQuery(tsmRaySceneQuery); tsmRaySceneQuery.Dispose(); return(y); }
public RaycastResult Raycast(Ray ray, uint queryMask) { RaycastResult rr = new RaycastResult(); RaySceneQuery raySceneQuery = this.sceneMgr.CreateRayQuery(new Ray()); raySceneQuery.SetSortByDistance(true); // check we are initialised if (raySceneQuery != null) { // create a query object raySceneQuery.Ray = ray; raySceneQuery.SetSortByDistance(true); raySceneQuery.QueryMask = queryMask; // execute the query, returns a vector of hits if (raySceneQuery.Execute().Count <= 0) { // raycast did not hit an objects bounding box return(null); } } else { // LogManager.Singleton.LogMessage("Cannot raycast without RaySceneQuery instance"); return(null); } // at this point we have raycast to a series of different objects bounding boxes. // we need to test these different objects to see which is the first polygon hit. // there are some minor optimizations (distance based) that mean we wont have to // check all of the objects most of the time, but the worst case scenario is that // we need to test every triangle of every object. // Ogre::Real closest_distance = -1.0f; rr.Distance = -1.0f; Vector3 closest_result = Vector3.ZERO; RaySceneQueryResult query_result = raySceneQuery.GetLastResults(); for (int qridx = 0; qridx < query_result.Count; qridx++) { // stop checking if we have found a raycast hit that is closer // than all remaining entities if ((rr.Distance >= 0.0f) && (rr.Distance < query_result[qridx].distance)) { break; } // only check this result if its a hit against an entity if ((query_result[qridx].movable != null) && (query_result[qridx].movable.MovableType.CompareTo("Entity") == 0)) { // get the entity to check Entity pentity = (Entity)query_result[qridx].movable; // mesh data to retrieve uint vertex_count; uint index_count; Vector3[] vertices; ulong[] indices; // get the mesh information GetMeshInformation( pentity.GetMesh(), out vertex_count, out vertices, out index_count, out indices, pentity.ParentNode._getDerivedPosition(), pentity.ParentNode._getDerivedOrientation(), pentity.ParentNode.GetScale()); // test for hitting individual triangles on the mesh bool new_closest_found = false; for (int i = 0; i < (int)index_count; i += 3) { // check for a hit against this triangle Pair <bool, float> hit = Mogre.Math.Intersects(ray, vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]], true, false); // if it was a hit check if its the closest if (hit.first) { if ((rr.Distance < 0.0f) || (hit.second < rr.Distance)) { // this is the closest so far, save it off rr.Distance = hit.second; new_closest_found = true; } } } // if we found a new closest raycast for this object, update the // closest_result before moving on to the next object. if (new_closest_found) { rr.Target = pentity; closest_result = ray.GetPoint(rr.Distance); } } } this.sceneMgr.DestroyQuery(raySceneQuery); raySceneQuery.Dispose(); // return the result if (rr.Distance >= 0.0f) { // raycast success rr.Position = closest_result; return(rr); } else { return(null); } }
public RaycastResult Raycast(Ray ray, uint queryMask) { RaycastResult rr = new RaycastResult(); RaySceneQuery raySceneQuery = this.sceneMgr.CreateRayQuery(new Ray()); raySceneQuery.SetSortByDistance(true); // check we are initialised if (raySceneQuery != null) { // create a query object raySceneQuery.Ray = ray; raySceneQuery.SetSortByDistance(true); raySceneQuery.QueryMask = queryMask; using (RaySceneQueryResult queryResult = raySceneQuery.Execute()) { // execute the query, returns a vector of hits if (queryResult.Count <= 0) { // raycast did not hit an objects bounding box this.sceneMgr.DestroyQuery(raySceneQuery); raySceneQuery.Dispose(); return(null); } // at this point we have raycast to a series of different objects bounding boxes. // we need to test these different objects to see which is the first polygon hit. // there are some minor optimizations (distance based) that mean we wont have to // check all of the objects most of the time, but the worst case scenario is that // we need to test every triangle of every object. // Ogre::Real closest_distance = -1.0f; rr.Distance = -1.0f; Vector3 closestResult = Vector3.ZERO; for (int qridx = 0; qridx < queryResult.Count; qridx++) { // stop checking if we have found a raycast hit that is closer // than all remaining entities if (rr.Distance >= 0.0f && rr.Distance < queryResult[qridx].distance) { break; } // only check this result if its a hit against an entity if (queryResult[qridx].movable != null && queryResult[qridx].movable.MovableType == "Entity") { // get the entity to check Entity entity = (Entity)queryResult[qridx].movable; // mesh data to retrieve Vector3[] vertices; int[] indices; RenderOperation.OperationTypes opType; // get the mesh information using (MeshPtr mesh = entity.GetMesh()) { opType = mesh.GetSubMesh(0).operationType; Debug.Assert(CheckSubMeshOpType(mesh, opType)); GetMeshInformation( mesh, out vertices, out indices, entity.ParentNode._getDerivedPosition(), entity.ParentNode._getDerivedOrientation(), entity.ParentNode._getDerivedScale()); } int vertexCount = vertices.Length; int indexCount = indices.Length; // test for hitting individual triangles on the mesh bool newClosestFound = false; Pair <bool, float> hit; switch (opType) { case RenderOperation.OperationTypes.OT_TRIANGLE_LIST: for (int i = 0; i < indexCount; i += 3) { hit = Mogre.Math.Intersects(ray, vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]], true, false); if (CheckDistance(rr, hit)) { newClosestFound = true; } } break; case RenderOperation.OperationTypes.OT_TRIANGLE_STRIP: for (int i = 0; i < indexCount - 2; i++) { hit = Mogre.Math.Intersects(ray, vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]], true, true); if (CheckDistance(rr, hit)) { newClosestFound = true; } } break; case RenderOperation.OperationTypes.OT_TRIANGLE_FAN: for (int i = 0; i < indexCount - 2; i++) { hit = Mogre.Math.Intersects(ray, vertices[indices[0]], vertices[indices[i + 1]], vertices[indices[i + 2]], true, true); if (CheckDistance(rr, hit)) { newClosestFound = true; } } break; default: throw new Exception("invalid operation type"); } // if we found a new closest raycast for this object, update the // closest_result before moving on to the next object. if (newClosestFound) { rr.Target = entity; closestResult = ray.GetPoint(rr.Distance); } } } this.sceneMgr.DestroyQuery(raySceneQuery); raySceneQuery.Dispose(); // return the result if (rr.Distance >= 0.0f) { // raycast success rr.Position = closestResult; return(rr); } else { return(null); } } } else { return(null); } }