예제 #1
0
        /// <summary>
        /// Creates a bounding box from a bounding sphere.
        /// </summary>
        /// <param name="boundingSphere">Bounding sphere to be used to create the bounding box.</param>
        /// <param name="boundingBox">Bounding box created from the bounding sphere.</param>
        public static void CreateFromSphere(ref BoundingSphere boundingSphere, out BoundingBox boundingBox)
        {
            boundingBox.Min.X = boundingSphere.Center.X - boundingSphere.Radius;
            boundingBox.Min.Y = boundingSphere.Center.Y - boundingSphere.Radius;
            boundingBox.Min.Z = boundingSphere.Center.Z - boundingSphere.Radius;

            boundingBox.Max.X = boundingSphere.Center.X + boundingSphere.Radius;
            boundingBox.Max.Y = boundingSphere.Center.Y + boundingSphere.Radius;
            boundingBox.Max.Z = boundingSphere.Center.Z + boundingSphere.Radius;
        }
        public void GetEntries(BoundingSphere boundingShape, IList<BroadPhaseEntry> overlaps)
        {
            //Create a bounding box based on the bounding sphere.
            //Compute the min and max of the bounding box.
            //Loop through the cells and select bounding boxes which overlap the x axis.
            #if !WINDOWS
            System.Numerics.Vector3 offset = new System.Numerics.Vector3();
            #else
            System.Numerics.Vector3 offset;
            #endif
            offset.X = boundingShape.Radius;
            offset.Y = offset.X;
            offset.Z = offset.Y;
            BoundingBox box;
            Vector3Ex.Add(ref boundingShape.Center, ref offset, out box.Max);
            Vector3Ex.Subtract(ref boundingShape.Center, ref offset, out box.Min);

            Int2 min, max;
            Grid2DSortAndSweep.ComputeCell(ref box.Min, out min);
            Grid2DSortAndSweep.ComputeCell(ref box.Max, out max);
            for (int i = min.Y; i <= max.Y; i++)
            {
                for (int j = min.Z; j <= max.Z; j++)
                {
                    //Grab the cell that we are currently in.
                    Int2 cellIndex;
                    cellIndex.Y = i;
                    cellIndex.Z = j;
                    GridCell2D cell;
                    if (owner.cellSet.TryGetCell(ref cellIndex, out cell))
                    {

                        //To fully accelerate this, the entries list would need to contain both min and max interval markers.
                        //Since it only contains the sorted min intervals, we can't just start at a point in the middle of the list.
                        //Consider some giant bounding box that spans the entire list.
                        for (int k = 0; k < cell.entries.Count
                            && cell.entries.Elements[k].item.boundingBox.Min.X <= box.Max.X; k++) //TODO: Try additional x axis pruning? A bit of optimization potential due to overlap with AABB test.
                        {
                            bool intersects;
                            var item = cell.entries.Elements[k].item;
                            item.boundingBox.Intersects(ref boundingShape, out intersects);
                            if (intersects && !overlaps.Contains(item))
                            {
                                overlaps.Add(item);
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        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);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Returns the list of ConvexCollidable's and Entities inside or touching the specified sphere.
        /// Result does not include static geometry and non-entity physical objects.
        /// </summary>
        /// <param name="world"></param>
        /// <param name="origin"></param>
        /// <param name="radius"></param>
        /// <returns></returns>
        public List <Entity> WeaponOverlap(Vector3 origin, float radius, Entity entToSkip)
        {
            BU.BoundingSphere sphere      = new BU.BoundingSphere(MathConverter.Convert(origin), radius);
            SphereShape       sphereShape = new SphereShape(radius);

            BU.Vector3        zeroSweep  = BU.Vector3.Zero;
            BU.RigidTransform rigidXForm = new BU.RigidTransform(MathConverter.Convert(origin));

            var candidates = PhysicsResources.GetBroadPhaseEntryList();

            PhysSpace.BroadPhase.QueryAccelerator.BroadPhase.QueryAccelerator.GetEntries(sphere, candidates);

            var result = new List <Entity>();

            foreach (var candidate in candidates)
            {
                BU.RayHit rayHit;
                bool      r = candidate.ConvexCast(sphereShape, ref rigidXForm, ref zeroSweep, out rayHit);

                if (r)
                {
                    var collidable = candidate as ConvexCollidable;
                    var entity     = collidable == null ? null : collidable.Entity.Tag as Entity;

                    if (collidable == null)
                    {
                        continue;
                    }
                    if (entity == null)
                    {
                        continue;
                    }

                    result.Add(entity);
                }
            }

            result.RemoveAll(e => e == entToSkip);

            return(result);
        }
 /// <summary>
 /// Constructs a new force field shape using a bounding sphere.
 /// </summary>
 /// <param name="sphere">Bounding sphere to use.</param>
 public BoundingSphereForceFieldShape(BoundingSphere sphere)
 {
     BoundingSphere = sphere;
 }
예제 #6
0
        /// <summary>
        /// Determines if a bounding box intersects a bounding sphere.
        /// </summary>
        /// <param name="boundingSphere">Sphere to test for intersection.</param>
        /// <param name="intersects">Whether the bounding shapes intersect.</param>
        public void Intersects(ref BoundingSphere boundingSphere, out bool intersects)
        {
            Vector3 clampedLocation;
            if (boundingSphere.Center.X > Max.X)
                clampedLocation.X = Max.X;
            else if (boundingSphere.Center.X < Min.X)
                clampedLocation.X = Min.X;
            else
                clampedLocation.X = boundingSphere.Center.X;

            if (boundingSphere.Center.Y > Max.Y)
                clampedLocation.Y = Max.Y;
            else if (boundingSphere.Center.Y < Min.Y)
                clampedLocation.Y = Min.Y;
            else
                clampedLocation.Y = boundingSphere.Center.Y;

            if (boundingSphere.Center.Z > Max.Z)
                clampedLocation.Z = Max.Z;
            else if (boundingSphere.Center.Z < Min.Z)
                clampedLocation.Z = Min.Z;
            else
                clampedLocation.Z = boundingSphere.Center.Z;

            float distanceSquared;
            Vector3.DistanceSquared(ref clampedLocation, ref boundingSphere.Center, out distanceSquared);
            intersects = distanceSquared <= boundingSphere.Radius * boundingSphere.Radius;

        }
 /// <summary>
 /// Gets the triangles whose bounding boxes are overlapped by the query.
 /// </summary>
 /// <param name="boundingSphere">Shape to query against the tree.</param>
 /// <param name="outputOverlappedElements">Indices of triangles in the index buffer with bounding boxes which are overlapped by the query.</param>
 /// <returns>Whether or not any elements were overlapped.</returns>
 public bool GetOverlaps(BoundingSphere boundingSphere, IList<int> outputOverlappedElements)
 {
     if (root != null)
     {
         bool intersects;
         root.BoundingBox.Intersects(ref boundingSphere, out intersects);
         if (intersects)
             root.GetOverlaps(ref boundingSphere, outputOverlappedElements);
     }
     return outputOverlappedElements.Count > 0;
 }
 internal abstract void GetOverlaps(ref BoundingSphere boundingSphere, IList<int> outputOverlappedElements);
 internal override void GetOverlaps(ref BoundingSphere boundingSphere, IList<int> outputOverlappedElements)
 {
     outputOverlappedElements.Add(LeafIndex);
 }
 internal override void GetOverlaps(ref BoundingSphere boundingSphere, IList<int> outputOverlappedElements)
 {
     bool intersects;
     ChildA.BoundingBox.Intersects(ref boundingSphere, out intersects);
     if (intersects)
         ChildA.GetOverlaps(ref boundingSphere, outputOverlappedElements);
     ChildB.BoundingBox.Intersects(ref boundingSphere, out intersects);
     if (intersects)
         ChildB.GetOverlaps(ref boundingSphere, outputOverlappedElements);
 }
예제 #11
0
        /// <summary>
        /// Returns the list of ConvexCollidable's and Entities inside or touching the specified sphere.
        /// Result does not include static geometry and non-entity physical objects.
        /// </summary>
        /// <param name="world"></param>
        /// <param name="origin"></param>
        /// <param name="radius"></param>
        /// <returns></returns>
        public List<Entity> WeaponOverlap( Vector3 origin, float radius, Entity entToSkip )
        {
            BU.BoundingSphere	sphere		= new BU.BoundingSphere(MathConverter.Convert(origin), radius);
            SphereShape			sphereShape = new SphereShape(radius);
            BU.Vector3			zeroSweep	= BU.Vector3.Zero;
            BU.RigidTransform	rigidXForm	= new BU.RigidTransform( MathConverter.Convert(origin) );

            var candidates = PhysicsResources.GetBroadPhaseEntryList();
            physSpace.BroadPhase.QueryAccelerator.BroadPhase.QueryAccelerator.GetEntries(sphere, candidates);

            var result = new List<Entity>();

            foreach ( var candidate in candidates )	{

                BU.RayHit rayHit;
                bool r = candidate.ConvexCast( sphereShape, ref rigidXForm, ref zeroSweep, out rayHit );

                if (r) {

                    var collidable	=	candidate as ConvexCollidable;
                    var entity		=	collidable==null ? null : collidable.Entity.Tag as Entity;

                    if (collidable==null) continue;
                    if (entity==null) continue;

                    result.Add( entity );
                }
            }

            result.RemoveAll( e => e == entToSkip );

            return result;
        }
 ///// <summary>
 ///// Collects all entries with bounding boxes which intersect the given frustum.
 ///// </summary>
 ///// <param name="frustum">Frustum to test against the world.</param>
 ///// <param name="entries">Entries of the space which intersect the frustum.</param>
 //public void GetEntries(BoundingFrustum frustum, IList<BroadPhaseEntry> entries)
 //{
 //    if (hierarchy.root != null)
 //        hierarchy.root.GetOverlaps(ref frustum, entries);
 //}
 /// <summary>
 /// Collects all entries with bounding boxes which intersect the given sphere.
 /// </summary>
 /// <param name="sphere">Sphere to test against the world.</param>
 /// <param name="entries">Entries of the space which intersect the sphere.</param>
 public void GetEntries(BoundingSphere sphere, IList<BroadPhaseEntry> entries)
 {
     if (hierarchy.root != null)
         hierarchy.root.GetOverlaps(ref sphere, entries);
 }