/// <summary> /// Returns all overlapping objects of a given ray with the physics world, the ray does NOT stop at solid hit but will report all overlaps and solid hits on the ray /// </summary> /// <param name="ray">Ray to test against</param> /// <param name="length">Maximum distance to test</param> /// <param name="group">Collision Group to use for the ray anything above "NoSolver" is ignored</param> /// <param name="outResults">All overlaps on the ray</param> /// <returns>True if any object was hit</returns> public bool RayOverlap(ref Ray ray, float length, CollisionGroup group, List <SRaycastResult> outResults) { List <RayCastResult> physicsResults = new List <RayCastResult>(); if (m_physicSpace.RayCast(ray.ToBepu(), length, GetOverlapFilter(group), physicsResults)) { foreach (RayCastResult physicsResult in physicsResults) { if (physicsResult.HitObject.Tag is CEntity gameEntity) { CollisionRule rule = GetCollisionRuleWithGroup(physicsResult.HitObject, group); SRaycastResult gameResult = new SRaycastResult() { HitEntity = gameEntity, Location = physicsResult.HitData.Location.ToSharp(), Normal = physicsResult.HitData.Normal.ToSharp(), Distance = physicsResult.HitData.T, bIsSolidHit = rule <= CollisionRule.Normal }; outResults.Add(gameResult); } } return(outResults.Count > 0); } return(false); }
/// <summary> /// Returns all overlapping objects of a given ray with the physics world, as no rules are given to this function all hits will be reported as non solid /// </summary> /// <param name="ray">Ray to test against</param> /// <param name="length">Maximum distance to test</param> /// <param name="outResults">All overlaps on the ray</param> /// <returns>True if any object was hit</returns> public bool RayOverlap(ref Ray ray, float length, List <SRaycastResult> outResults) { List <RayCastResult> physicsResults = new List <RayCastResult>(); if (m_physicSpace.RayCast(ray.ToBepu(), length, physicsResults)) { foreach (RayCastResult physicsResult in physicsResults) { if (physicsResult.HitObject.Tag is CEntity gameEntity) { SRaycastResult gameResult = new SRaycastResult() { HitEntity = gameEntity, Location = physicsResult.HitData.Location.ToSharp(), Normal = physicsResult.HitData.Normal.ToSharp(), Distance = physicsResult.HitData.T, bIsSolidHit = false }; outResults.Add(gameResult); } } return(outResults.Count > 0); } return(false); }
private void OnInputEvent(ReadOnlyCollection <SInputButtonEvent> buttonevents, string textinput) { foreach (var buttonEvent in buttonevents) { if (buttonEvent.button == EInputButton.MouseMiddleButton && buttonEvent.buttonEvent == EButtonEvent.Pressed) { CViewManager viewManager = m_gameWorld.ViewManager; int mouseAbsX = System.Windows.Forms.Cursor.Position.X - (int)viewManager.ScreenLeft; int mouseAbsY = System.Windows.Forms.Cursor.Position.Y - (int)viewManager.ScreenTop; if (mouseAbsX < 0 || mouseAbsY < 0) { return; } viewManager.GetViewInfo(out SSceneViewInfo viewInfo); Ray pickRay = Ray.GetPickRay(mouseAbsX, mouseAbsY, new ViewportF(0, 0, viewManager.ScreenWidth, viewManager.ScreenHeight), viewInfo.ViewMatrix * viewInfo.ProjectionMatrix); if (m_physicSpace.RayCast(pickRay.ToBepu(), 9999.0f, out RayCastResult result)) { float fieldRadius = 5.0f; float impulseStrength = 20.0f; List <BroadPhaseEntry> queryResults = new List <BroadPhaseEntry>(); BoundingSphere bs = new BoundingSphere(result.HitData.Location, fieldRadius); m_physicSpace.BroadPhase.QueryAccelerator.GetEntries(bs, queryResults); foreach (var entry in queryResults) { var entityCollision = entry as EntityCollidable; if (entityCollision != null) { var e = entityCollision.Entity; if (e.IsDynamic) { Vector3 toEntity = e.Position - result.HitData.Location; float length = toEntity.Length(); float strength = impulseStrength / length; toEntity.Y = 1.0f; toEntity.Normalize(); e.ApplyImpulse(e.Position, toEntity * strength); } } } } } } }
/// <summary> /// Returns the first hit of a given ray tested against the physics world, does filtering based on the given function /// </summary> /// <param name="ray">Ray to test against</param> /// <param name="length">Maximum distance to test</param> /// <param name="filter">Filter to check if an object is valid to hit</param> /// <param name="outHitResult">The hit that was found if any</param> /// <returns>True if any object was hit</returns> public bool Raycast(ref Ray ray, float length, Func <BroadPhaseEntry, bool> filter, ref SRaycastResult outHitResult) { if (m_physicSpace.RayCast(ray.ToBepu(), length, filter, out RayCastResult result)) { if (result.HitObject.Tag is CEntity gameEntity) { outHitResult.HitEntity = gameEntity; outHitResult.Location = result.HitData.Location.ToSharp(); outHitResult.Normal = result.HitData.Normal.ToSharp(); outHitResult.Distance = result.HitData.T; return(true); } return(false); } return(false); }