private static RaySceneQueryResult.Enumerator GetRaySceneQuery(double x, double y, out Ray ray) { float width = Engine.Renderer.Camera.Viewport.ActualWidth; float height = Engine.Renderer.Camera.Viewport.ActualHeight; Ray mouseRay = Engine.Renderer.Camera.GetCameraToViewportRay((float)((x - 1) / width), (float)((y - 1) / height)); RaySceneQuery mRaySceneQuery = Engine.Renderer.Scene.CreateRayQuery(mouseRay); mRaySceneQuery.QueryTypeMask = SceneManager.ENTITY_TYPE_MASK | SceneManager.STATICGEOMETRY_TYPE_MASK | SceneManager.USER_TYPE_MASK_LIMIT | SceneManager.FRUSTUM_TYPE_MASK | SceneManager.FX_TYPE_MASK | SceneManager.LIGHT_TYPE_MASK | SceneManager.WORLD_GEOMETRY_TYPE_MASK; mRaySceneQuery.SetSortByDistance(true, 16); RaySceneQueryResult result = mRaySceneQuery.Execute(); RaySceneQueryResult.Enumerator itr = (RaySceneQueryResult.Enumerator)(result.GetEnumerator()); ray = mouseRay; return(itr); }
private VanillaNonPlayer GetSelectedNPC() { RaySceneQuery raySceneQuery = this.mStateMgr.SceneMgr.CreateRayQuery(this.mStateMgr.Camera.GetCameraToViewportRay(0.5f, 0.5f)); raySceneQuery.SetSortByDistance(true); foreach (RaySceneQueryResultEntry raySQREntry in raySceneQuery.Execute()) { if (raySQREntry.movable != null) { string name = raySQREntry.movable.Name; if (!name.Contains("CharacterEnt_")) { continue; } int id = int.Parse(name.Split('_')[1]); VanillaNonPlayer npc = this.mStateMgr.MainState.CharacMgr.GetCharacterById(id) as VanillaNonPlayer; if (npc != null) { return(npc); } } } return(null); }
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; using (RaySceneQuery tsmRaySceneQuery = this.sceneMgr.CreateRayQuery(updateRay)) { using (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); } return(y); }
public void onLeftPressed(MouseEvent evt) { if (m_pCurrentObject != null) { m_pCurrentObject.ShowBoundingBox = false; m_pCurrentEntity.GetSubEntity(1).SetMaterial(m_pOgreHeadMat); } Ray mouseRay = m_pCamera.GetCameraToViewportRay(AdvancedMogreFramework.Singleton.m_pMouse.MouseState.X.abs / (float)evt.state.width, AdvancedMogreFramework.Singleton.m_pMouse.MouseState.Y.abs / (float)evt.state.height); if (m_pRSQ == null) { return; } m_pRSQ.Ray = mouseRay; //m_pRSQ.SortByDistance=true; RaySceneQueryResult result = m_pRSQ.Execute(); foreach (RaySceneQueryResultEntry itr in result) { if (itr.movable != null) { AdvancedMogreFramework.Singleton.m_pLog.LogMessage("MovableName: " + itr.movable.Name); m_pCurrentObject = m_pSceneMgr.GetEntity(itr.movable.Name).ParentSceneNode; AdvancedMogreFramework.Singleton.m_pLog.LogMessage("ObjName " + m_pCurrentObject.Name); m_pCurrentObject.ShowBoundingBox = true; m_pCurrentEntity = m_pSceneMgr.GetEntity(itr.movable.Name); m_pCurrentEntity.GetSubEntity(1).SetMaterial(m_pOgreHeadMatHigh); break; } } }
// intersects objects in scene with ray from screen coords: x, y public static RaySceneQueryResult Pick(SceneManager mgr, int x, int y, Viewport vp, Camera cam) { //normalise mouse coordinates to [0,1] //we could have used the panel's width/height in pixels instead of viewport's width/height float scrx = (float)x / vp.ActualWidth; float scry = (float)y / vp.ActualHeight; Ray ray = cam.GetCameraToViewportRay(scrx, scry); RaySceneQuery query = mgr.CreateRayQuery(ray); RaySceneQueryResult results = query.Execute(); return(results); }
/// <summary> /// private method for selection object that creates a box from a single mouse click /// </summary> private void PerformSelectionWithMouseClick() { Log("MouseSelector: " + this._name + " single click selecting at (" + this._start.x.ToString() + ";" + this._start.y.ToString() + ")"); Ray mouseRay = this._Camera.GetCameraToViewportRay(this._start.x, this._start.y); RaySceneQuery RayScnQuery = Root.Instance.SceneManager.CreateRayQuery(mouseRay); RayScnQuery.SortByDistance = true; foreach (RaySceneQueryResultEntry re in RayScnQuery.Execute()) { SelectObject(re.SceneObject); } }
public void updateFilpTerrain() { Ray ray = new Ray(Position, Mogre.Vector3.NEGATIVE_UNIT_Y); RaySceneQuery rayQuery = mCamera.SceneManager.CreateRayQuery(ray); RaySceneQueryResult rayQueryResult = rayQuery.Execute(); foreach (var result in rayQueryResult) { if (result.worldFragment != null) { mBodyNode.SetPosition( Position.x, result.worldFragment.singleIntersection.y + 10, Position.z); } } }
public bool Update(BulletManager bulletMgr, float frameTime) { if (this.mDistTravalled >= this.Range) { return(false); } float distance = this.Speed * frameTime; this.mDistTravalled += distance; this.mYawNode.Translate(distance * this.mForwardDir, Node.TransformSpace.TS_LOCAL); if (this.mAccurateTest) { this.mRay.Origin = this.mYawNode.Position; if ( !(bulletMgr.World.getIsland() .getBlock(MainWorld.getRelativeFromAbsolute(this.mYawNode.Position), false) is Air)) { return(false); } RaySceneQuery raySQuery = bulletMgr.SceneMgr.CreateRayQuery(this.mRay); raySQuery.SetSortByDistance(true); foreach (RaySceneQueryResultEntry raySQREntry in raySQuery.Execute()) { if (raySQREntry.movable != null && raySQREntry.distance > 0 && raySQREntry.distance <= distance) { string[] s = raySQREntry.movable.Name.Split('_'); if (s.Length == 2 && s[0] == "CharacterEnt") { int id = int.Parse(s[1]); if (id != this.mSource.Info.Id) { bulletMgr.CharacMgr.GetCharacterById(id).Hit(this.Damage, this.mSource); return(false); } } } } } return(true); }
protected RaySceneQueryResult RaycastBoundingBox(Ray ray) { raySceneQuery = this.sceneManager.CreateRayQuery(ray); raySceneQuery.SetSortByDistance(true); // check we are initialised if (raySceneQuery != null) { // create a query object raySceneQuery.Ray = ray; raySceneQuery.SetSortByDistance(true); raySceneQuery.QueryMask = 1; // execute the query, returns a vector of hits return(raySceneQuery.Execute()); } return(null); }
public string selectObject(Point mousePoint, float width, float height) { RestoreBoxnodes(); Ray ray = camera.GetCameraToViewportRay(mousePoint.X / width, mousePoint.Y / height); raySceneQuery.Ray = ray; // Execute query raySceneQuery.SetSortByDistance(true, 1); RaySceneQueryResult result = raySceneQuery.Execute(); if (result.Count > 0) { isTubeRool = true; RaySceneQueryResultEntry entry = result[0]; string entryName = entry.movable.Name; if (entryName.Substring(0, 3).Equals("box")) { Node node = entry.movable.ParentNode; Vector3 nodePosition = node.Position; if (nodePosition.x == 0) { nodePosition.x += 20; node.Position = nodePosition; } } else if (entryName.Substring(0, 4).Equals("tube")) { isTubeRool = false; Node nodeParent = entry.movable.ParentNode.Parent; for (int i = 1; i < 4; i++) { Node nodeChild = nodeParent.GetChild("tube" + i.ToString() + "Node"); nodeChild.ResetOrientation(); } } return(entryName); } return(""); }
private void picRender_MouseClick(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Right) { return; } SelectedItem = ""; RaySceneQuery mRaySceneQuery = null; // Save mouse position float mouseX = (float)e.X / picRender.Width; float mouseY = (float)e.Y / picRender.Height; // Setup the ray scene query Ray mouseRay = mgr.GetCamera("Camera").GetCameraToViewportRay(mouseX, mouseY); mRaySceneQuery = mgr.CreateRayQuery(mouseRay); // Execute query RaySceneQueryResult result = mRaySceneQuery.Execute(); RaySceneQueryResultEntry oneobj; ctxPickObject.Items.Clear(); // Get results, create a node/entity on the position for (Int16 i = 0; i < result.Count; i++) { oneobj = result[i]; if (oneobj.movable != null && oneobj.movable.Name != "canvas") { ctxPickObject.Items.Add(oneobj.movable.Name).Click += new EventHandler(ItemPicked); } } // ctxPickObject.Show(picRender, e.X, e.Y); drawFrame(); }
public void LeftClicked(float x, float y, string currentEntity) { // Save mouse position mouseX = x; mouseY = y; // Setup the ray scene query Ray mouseRay = mCamera.GetCameraToViewportRay(mouseX, mouseY); Ray newRay = new Ray(new Vector3(mouseRay.Origin.x, System.Math.Abs(mouseRay.Origin.y), mouseRay.Origin.z), mouseRay.Direction); mRaySceneQuery.Ray = newRay; // Execute query RaySceneQueryResult result = mRaySceneQuery.Execute(); RaySceneQueryResult.Enumerator itr = (RaySceneQueryResult.Enumerator)result.GetEnumerator(); // Get results, create a node/entity on the position if (itr != null && itr.MoveNext()) { if (string.IsNullOrWhiteSpace(currentEntity)) { return; } if (itr.Current != null && itr.Current.worldFragment != null) { Entity ent = mMgr.CreateEntity(currentEntity + mCount.ToString(), currentEntity); mCurrentObject = mMgr.RootSceneNode.CreateChildSceneNode(currentEntity + "Node" + mCount.ToString(), itr.Current.worldFragment.singleIntersection); mCount++; mCurrentObject.AttachObject(ent); mCurrentObject.SetScale(scale); } } // mLMouseDown = true; return; }
protected Vector3 GetFirstRealHit(Vector3 origin, Vector3 direction) { Vector3 hit = origin; float minDistance = float.MaxValue; RaySceneQuery raySceneQuery = CameraCS.SceneManager.CreateRayQuery(new Ray(origin, direction)); RaySceneQueryResult result = raySceneQuery.Execute(); var iterator = result.GetEnumerator(); bool intersect = false; while (iterator.MoveNext() /*&& !intersect*/) //! @todo are the results ordered ?? if so, uncomment (optimization) { var itr = iterator.Current; if (itr.distance < minDistance && // take the shorter itr.movable.ParentSceneNode != CameraCS.CameraSceneNode && itr.movable.ParentSceneNode != CameraCS.TargetNode && !_ignoreList.Contains(itr.movable)) { minDistance = itr.distance; intersect = true; if (itr.worldFragment != null) { hit = itr.worldFragment.singleIntersection; } else //if(itr.movable) { hit = origin + (direction * itr.distance); } } } CameraCS.SceneManager.DestroyQuery(raySceneQuery); return(hit); }
public static Vector3 GetBestLocationFromYDown(Vector3 vector, float fallbackY, float sizeY) { Ray ray = new Ray(vector + new Vector3(0, (float.MaxValue), 0), Vector3.NEGATIVE_UNIT_Y); RaySceneQuery mRaySceneQuery = Engine.Renderer.Scene.CreateRayQuery(ray); mRaySceneQuery.SetSortByDistance(true, 64); mRaySceneQuery.QueryMask = (uint)QueryFlags.INSTANCE_ENTITY; mRaySceneQuery.QueryTypeMask = SceneManager.ENTITY_TYPE_MASK | SceneManager.STATICGEOMETRY_TYPE_MASK | SceneManager.USER_TYPE_MASK_LIMIT | SceneManager.FRUSTUM_TYPE_MASK | SceneManager.FX_TYPE_MASK | SceneManager.LIGHT_TYPE_MASK | SceneManager.WORLD_GEOMETRY_TYPE_MASK; RaySceneQueryResult result = mRaySceneQuery.Execute(); RaySceneQueryResult.Enumerator itr = (RaySceneQueryResult.Enumerator)(result.GetEnumerator()); Vector3 max = new Vector3(vector.x, fallbackY, vector.z); if (itr != null) { while (itr.MoveNext()) { RaySceneQueryResultEntry entry = itr.Current; SceneNode parentNode = entry.movable.ParentSceneNode; Vector3 current = new Vector3(vector.x, parentNode.Position.y + sizeY, vector.z); if (current.y > max.y) { max = current; } } } return(max); }
protected override bool ExampleApp_FrameStarted(FrameEvent evt) { if (base.ExampleApp_FrameStarted(evt) == false) { return(false); } // clamp to terrain Ray updateRay = new Ray(this.camera.Position, Vector3.NEGATIVE_UNIT_Y); raySceneQuery.Ray = updateRay; RaySceneQueryResult qryResult = raySceneQuery.Execute(); RaySceneQueryResultEntry rs = qryResult[0]; if (rs != null && rs.worldFragment != null) { camera.SetPosition(camera.Position.x, rs.worldFragment.singleIntersection.y + 10, camera.Position.z); } return(true); }
private bool FrameStarted(FrameEvent evt) { // Check camera height RaySceneQuery raySceneQuery = sceneMgr.CreateRayQuery(new Ray(camera.Position + new Vector3(0, 1000000, 0), Vector3.NEGATIVE_UNIT_Y)); RaySceneQueryResult qryResult = raySceneQuery.Execute(); RaySceneQueryResult.Iterator it = qryResult.Begin(); if (it != qryResult.End() && it.Value.worldFragment != null) { if (camera.DerivedPosition.y < it.Value.worldFragment.singleIntersection.y + 30) { camera.SetPosition(camera.Position.x, it.Value.worldFragment.singleIntersection.y + 30, camera.Position.z); } it.MoveNext(); } //SkyX::AtmosphereManager::Options SkyXOptions = mSkyX->getAtmosphereManager()->getOptions(); // Time if (!showInformation) { manager.TimeMultiplier = 0.1f; } else { manager.TimeMultiplier = 0.0f; } textArea.Caption = GetConfigString(); manager.Update(evt.timeSinceLastFrame); return(true); }
private static bool GetRaySceneLocationWithPlane(double x, double y, Plane plane, out Vector3 vector, SceneNode ignore) { float width = Engine.Renderer.Camera.Viewport.ActualWidth; float height = Engine.Renderer.Camera.Viewport.ActualHeight; Ray mouseRay = Engine.Renderer.Camera.GetCameraToViewportRay((float)((x - 1) / width), (float)((y - 1) / height)); Plane inverse = new Plane(-plane.normal, -plane.d); Pair <bool, float> d0 = mouseRay.Intersects(plane); Pair <bool, float> d1 = mouseRay.Intersects(inverse); RaySceneQuery mRaySceneQuery = Engine.Renderer.Scene.CreateRayQuery(mouseRay); mRaySceneQuery.SetSortByDistance(true, 16); mRaySceneQuery.QueryMask = (uint)QueryFlags.INSTANCE_ENTITY; mRaySceneQuery.QueryTypeMask = SceneManager.ENTITY_TYPE_MASK | SceneManager.STATICGEOMETRY_TYPE_MASK | SceneManager.USER_TYPE_MASK_LIMIT | SceneManager.FRUSTUM_TYPE_MASK | SceneManager.FX_TYPE_MASK | SceneManager.LIGHT_TYPE_MASK | SceneManager.WORLD_GEOMETRY_TYPE_MASK; RaySceneQueryResult result = mRaySceneQuery.Execute(); RaySceneQueryResult.Enumerator itr = (RaySceneQueryResult.Enumerator)(result.GetEnumerator()); if (itr != null) { RaySceneQueryResultEntry entry = null; while (itr.MoveNext()) { entry = itr.Current; if (entry != null && !entry.movable.ParentSceneNode.Equals(ignore)) { vector = mouseRay.GetPoint(entry.distance); return(true); } } if (d0.first) { Vector3 planePoint = mouseRay.GetPoint(d0.second); if ((Engine.Renderer.Camera.Position - planePoint).Length < MAX_TRANSLATE_DRAG_DISTANCE) { vector = planePoint; return(true); } } if (d1.first) { Vector3 planePoint = mouseRay.GetPoint(d1.second); if ((Engine.Renderer.Camera.Position - planePoint).Length < MAX_TRANSLATE_DRAG_DISTANCE) { vector = planePoint; return(true); } else { vector = Vector3.ZERO; return(false); } } else { vector = Vector3.ZERO; return(false); } } else { vector = Vector3.ZERO; return(false); } }
protected override void OnFrameStarted(object source, FrameEventArgs e) { float waterFlow; waterFlow = FLOW_SPEED * e.TimeSinceLastFrame; if (waterNode != null) { if (flowUp) { flowAmount += waterFlow; } else { flowAmount -= waterFlow; } if (flowAmount >= FLOW_HEIGHT) { flowUp = false; } else if (flowAmount <= 0.0f) { flowUp = true; } waterNode.Translate(new Vector3(0, flowUp ? waterFlow : -waterFlow, 0)); } float scaleMove = 200 * e.TimeSinceLastFrame; // reset acceleration zero camAccel = Vector3.Zero; // set the scaling of camera motion cameraScale = 100 * e.TimeSinceLastFrame; // TODO: Move this into an event queueing mechanism that is processed every frame input.Capture(); if (input.IsKeyPressed(KeyCodes.Escape)) { Root.Instance.QueueEndRendering(); return; } if (input.IsKeyPressed(KeyCodes.H) && toggleDelay < 0) { humanSpeed = !humanSpeed; toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.G) && toggleDelay < 0) { followTerrain = !followTerrain; toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.A)) { camAccel.x = -0.5f; } if (input.IsKeyPressed(KeyCodes.D)) { camAccel.x = 0.5f; } if (input.IsKeyPressed(KeyCodes.W)) { camAccel.z = -1.0f; } if (input.IsKeyPressed(KeyCodes.S)) { camAccel.z = 1.0f; } camAccel.y += input.RelativeMouseZ * 0.1f; if (input.IsKeyPressed(KeyCodes.Left)) { camera.Yaw(cameraScale); } if (input.IsKeyPressed(KeyCodes.Right)) { camera.Yaw(-cameraScale); } if (input.IsKeyPressed(KeyCodes.Up)) { camera.Pitch(cameraScale); } if (input.IsKeyPressed(KeyCodes.Down)) { camera.Pitch(-cameraScale); } // subtract the time since last frame to delay specific key presses toggleDelay -= e.TimeSinceLastFrame; // toggle rendering mode if (input.IsKeyPressed(KeyCodes.R) && toggleDelay < 0) { if (camera.SceneDetail == SceneDetailLevel.Points) { camera.SceneDetail = SceneDetailLevel.Solid; } else if (camera.SceneDetail == SceneDetailLevel.Solid) { camera.SceneDetail = SceneDetailLevel.Wireframe; } else { camera.SceneDetail = SceneDetailLevel.Points; } Console.WriteLine("Rendering mode changed to '{0}'.", camera.SceneDetail); toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.T) && toggleDelay < 0) { // toggle the texture settings switch (filtering) { case TextureFiltering.Bilinear: filtering = TextureFiltering.Trilinear; aniso = 1; break; case TextureFiltering.Trilinear: filtering = TextureFiltering.Anisotropic; aniso = 8; break; case TextureFiltering.Anisotropic: filtering = TextureFiltering.Bilinear; aniso = 1; break; } Console.WriteLine("Texture Filtering changed to '{0}'.", filtering); // set the new default MaterialManager.Instance.SetDefaultTextureFiltering(filtering); MaterialManager.Instance.DefaultAnisotropy = aniso; toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.P)) { string[] temp = Directory.GetFiles(Environment.CurrentDirectory, "screenshot*.jpg"); string fileName = string.Format("screenshot{0}.jpg", temp.Length + 1); // show briefly on the screen window.DebugText = string.Format("Wrote screenshot '{0}'.", fileName); TakeScreenshot(fileName); // show for 2 seconds debugTextDelay = 2.0f; } if (input.IsKeyPressed(KeyCodes.B)) { scene.ShowBoundingBoxes = !scene.ShowBoundingBoxes; } if (input.IsKeyPressed(KeyCodes.F)) { // hide all overlays, includes ones besides the debug overlay viewport.OverlaysEnabled = !viewport.OverlaysEnabled; } if (!input.IsMousePressed(MouseButtons.Left)) { float cameraYaw = -input.RelativeMouseX * .13f; float cameraPitch = -input.RelativeMouseY * .13f; camera.Yaw(cameraYaw); camera.Pitch(cameraPitch); } else { cameraVector.x += input.RelativeMouseX * 0.13f; } if (humanSpeed) { camVelocity = camAccel * 7.0f; camera.MoveRelative(camVelocity * e.TimeSinceLastFrame); } else { camVelocity += (camAccel * scaleMove * camSpeed); // move the camera based on the accumulated movement vector camera.MoveRelative(camVelocity * e.TimeSinceLastFrame); // Now dampen the Velocity - only if user is not accelerating if (camAccel == Vector3.Zero) { camVelocity *= (1 - (6 * e.TimeSinceLastFrame)); } } // update performance stats once per second if (statDelay < 0.0f && showDebugOverlay) { UpdateStats(); statDelay = 1.0f; } else { statDelay -= e.TimeSinceLastFrame; } // turn off debug text when delay ends if (debugTextDelay < 0.0f) { debugTextDelay = 0.0f; window.DebugText = ""; } else if (debugTextDelay > 0.0f) { debugTextDelay -= e.TimeSinceLastFrame; } if (followTerrain) { // adjust new camera position to be a fixed distance above the ground raySceneQuery.Ray = new Ray(camera.Position, Vector3.NegativeUnitY); raySceneQuery.Execute(this); } }
private void renderBox_MouseClick(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) { return; } foreach (MovableObject selectedNode in selectedNodes) { try { selectedNode.ParentSceneNode.ShowBoundingBox = false; } catch (Exception ex) { //log(ex.ToString()); } } selectedNodes = new ArrayList(); float scrx = (float)e.X / OgreWindow.Instance.mViewport.ActualWidth; float scry = (float)e.Y / OgreWindow.Instance.mViewport.ActualHeight; Ray ray = OgreWindow.Instance.mCamera.GetCameraToViewportRay(scrx, scry); RaySceneQuery query = OgreWindow.Instance.mSceneMgr.CreateRayQuery(ray); RaySceneQueryResult results = query.Execute(); float nearest = 100000000f; //100 mill int nearestIndex = -1; for (int i = 0; i < results.Count; i++) { RaySceneQueryResultEntry entry = results[i]; if (entry.movable.Name == "MainCamera") { continue; } if (entry.movable.Name.IndexOf("SphereEntity") > -1) { continue; } if (entry.movable.Name.IndexOf("SkyXMeshEnt") > -1) { continue; } if (entry.movable.Name.IndexOf("_Hydrax_GodRays_ManualObject") > -1) { continue; } if (entry.movable.Name.IndexOf("_Hydrax_GodRays_Projector_Camera") > -1) { continue; } if (entry.movable.Name.IndexOf("_Hydrax_Projector_Camera") > -1) { continue; } if (entry.movable.Name.IndexOf("HydraxMeshEnt") > -1) { continue; } bool cancel = false; foreach (string s in preventSelect) { if (entry.movable.Name.IndexOf(s) > -1) { cancel = true; break; } } if (cancel) { continue; } if (entry.distance < nearest) { nearest = entry.distance; nearestIndex = i; } } if (nearestIndex > -1) { RaySceneQueryResultEntry entry = results[nearestIndex]; selectSceneNode(entry.movable); } }
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); } }
protected RaySceneQueryResult RaycastBoundingBox(Ray ray) { raySceneQuery = this.sceneManager.CreateRayQuery(ray); raySceneQuery.SetSortByDistance(true); // check we are initialised if (raySceneQuery != null) { // create a query object raySceneQuery.Ray = ray; raySceneQuery.SetSortByDistance(true); raySceneQuery.QueryMask = 1; // execute the query, returns a vector of hits return raySceneQuery.Execute(); } 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); } }