Example #1
0
        /// <summary>
        /// Finds contacts between the query object and any intersected objects within the character's bounding box.
        /// </summary>
        /// <param name="queryObject">Collidable to query for contacts with.</param>
        /// <param name="tractionContacts">Output contacts that would provide traction.</param>
        /// <param name="supportContacts">Output contacts that would provide support.</param>
        /// <param name="sideContacts">Output contacts on the sides of the query object.</param>
        /// <param name="headContacts">Output contacts on the head of the query object.</param>
        public void QueryContacts(EntityCollidable queryObject,
                                  ref QuickList <CharacterContact> tractionContacts, ref QuickList <CharacterContact> supportContacts, ref QuickList <CharacterContact> sideContacts, ref QuickList <CharacterContact> headContacts)
        {
            var downDirection = characterBody.orientationMatrix4.Down;

            tractionContacts.Clear();
            supportContacts.Clear();
            sideContacts.Clear();
            headContacts.Clear();

            foreach (var collidable in characterBody.CollisionInformation.OverlappedCollidables)
            {
                //The query object is assumed to have a valid bounding box.
                if (collidable.BoundingBox.Intersects(queryObject.BoundingBox))
                {
                    var pair        = new CollidablePair(collidable, queryObject);
                    var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair);
                    if (pairHandler.CollisionRule == CollisionRule.Normal)
                    {
                        pairHandler.SuppressEvents = true;
                        pairHandler.UpdateCollision(0);
                        pairHandler.SuppressEvents = false;

                        contactCategorizer.CategorizeContacts(pairHandler, characterBody.CollisionInformation, ref downDirection,
                                                              ref tractionContacts, ref supportContacts, ref sideContacts, ref headContacts);
                    }
                    //TODO: It would be nice if this was a bit easier.
                    //Having to remember to clean up AND give it back is a bit weird, especially with the property-diving.
                    //No one would ever just guess this correctly.
                    //At least hide it behind a NarrowPhaseHelper function.
                    pairHandler.CleanUp();
                    pairHandler.Factory.GiveBack(pairHandler);
                }
            }
        }
 public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : unmanaged, IContactManifold <TManifold>
 {
     pairMaterial.FrictionCoefficient     = this.FrictionCoefficient;
     pairMaterial.MaximumRecoveryVelocity = this.MaximumRecoveryVelocity;
     pairMaterial.SpringSettings          = this.ContactSpringiness;
     return(true);
 }
Example #3
0
        protected void TryToAdd(Collidable a, Collidable b, Material materialA, Material materialB)
        {
            CollisionRule rule;

            if ((rule = CollisionRules.collisionRuleCalculator(a, b)) < CollisionRule.NoNarrowPhasePair)
            {
                //Clamp the rule to the parent's rule.  Always use the more restrictive option.
                //Don't have to test for NoNarrowPhasePair rule on the parent's rule because then the parent wouldn't exist!
                if (rule < CollisionRule)
                {
                    rule = CollisionRule;
                }
                var pair = new CollidablePair(a, b);
                if (!subPairs.ContainsKey(pair))
                {
                    var newPair = NarrowPhaseHelper.GetPairHandler(ref pair, rule);
                    if (newPair != null)
                    {
                        newPair.UpdateMaterialProperties(materialA, materialB);  //Override the materials, if necessary.
                        newPair.Parent = this;
                        subPairs.Add(pair, newPair);
                    }
                }
                containedPairs.Add(pair);
            }
        }
Example #4
0
 public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold>
 {
     pairMaterial.FrictionCoefficient     = 1;
     pairMaterial.MaximumRecoveryVelocity = 2f;
     pairMaterial.SpringSettings          = new SpringSettings(30, 1);
     return(true);
 }
Example #5
0
        public bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold,
                                                         out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold>
        {
            //The IContactManifold parameter includes functions for accessing contact data regardless of what the underlying type of the manifold is.
            //If you want to have direct access to the underlying type, you can use the manifold.Convex property and a cast like Unsafe.As<TManifold, ConvexContactManifold or NonconvexContactManifold>(ref manifold).

            //The engine does not define any per-body material properties. Instead, all material lookup and blending operations are handled by the callbacks.
            //For the purposes of this demo, we'll use the same settings for all pairs.
            //(Note that there's no bounciness property! See here for more details: https://github.com/bepu/bepuphysics2/issues/3)
            pairMaterial.FrictionCoefficient     = 1f;
            pairMaterial.MaximumRecoveryVelocity = 2f;
            pairMaterial.SpringSettings          = new SpringSettings(30, 1);
            //For the purposes of the demo, contact constraints are always generated.

            try
            {
                OnCollision(pair.A, pair.B);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            return(false);
        }
Example #6
0
 public bool AllowContactGeneration(int workerIndex, CollidablePair pair, int childIndexA, int childIndexB)
 {
     //This is similar to the top level broad phase callback above. It's called by the narrow phase before generating
     //subpairs between children in parent shapes.
     //This only gets called in pairs that involve at least one shape type that can contain multiple children, like a Compound.
     return(true);
 }
Example #7
0
        /// <summary>
        /// Finds contacts between the query object and any intersected objects within the character's bounding capsule.
        /// </summary>
        /// <param name="queryObject">Collidable to query for contacts with.</param>
        /// <param name="tractionContacts">Output contacts that would provide traction.</param>
        /// <param name="supportContacts">Output contacts that would provide support.</param>
        /// <param name="sideContacts">Output contacts on the sides of the query object.</param>
        /// <param name="headContacts">Output contacts on the head of the query object.</param>
        /// <param name="forceStandardPairsToBeQueries">An extremely hacky control parameter that makes any mesh-cylinder pair treat the mesh as double sided. Useful for not going through the ceiling when changing stances.</param>
        public void QueryContacts(EntityCollidable queryObject,
                                  ref QuickList <CharacterContact> tractionContacts, ref QuickList <CharacterContact> supportContacts, ref QuickList <CharacterContact> sideContacts, ref QuickList <CharacterContact> headContacts,
                                  bool forceStandardPairsToBeQueries = false)
        {
            var downDirection = characterBody.orientationMatrix.Down;

            tractionContacts.Clear();
            supportContacts.Clear();
            sideContacts.Clear();
            headContacts.Clear();

            foreach (var collidable in characterBody.CollisionInformation.OverlappedCollidables)
            {
                //The query object is assumed to have a valid bounding capsule.
                if (collidable.BoundingBox.Intersects(queryObject.BoundingBox))
                {
                    var pair        = new CollidablePair(collidable, queryObject);
                    var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair);
                    if (pairHandler.CollisionRule == CollisionRule.Normal)
                    {
                        if (forceStandardPairsToBeQueries)
                        {
                            //TODO: This is a massive hack that assumes a fixed set of collidable types. This won't work in the long run.
                            //The only reason it's here is that it was the easiest solution, combined with the fact that the character has to be rewritten for v2 anyway.
                            //Hopefully no one gets bit by this before the replacement is available.
                            //The core reason it exists is that one sided meshes don't generate contacts on their backside. That means a query shape can end up above a ceiling
                            //and it won't detect the ceiling. A better solution would be to let the caller choose whether or not to filter the contacts, and then use a
                            //direct test rather than stateful pair to perform the query here. Still some type-related annoyance to deal with, but a bit better.
                            var standardPair = pairHandler as StandardPairHandler;
                            if (standardPair != null)
                            {
                                standardPair.ContactManifold.IsQuery = true;
                            }
                        }
                        pairHandler.SuppressEvents = true;
                        pairHandler.UpdateCollision(0);
                        pairHandler.SuppressEvents = false;
                        if (forceStandardPairsToBeQueries)
                        {
                            //TODO: Again, superhack! Avoid this in v2.
                            var standardPair = pairHandler as StandardPairHandler;
                            if (standardPair != null)
                            {
                                standardPair.ContactManifold.IsQuery = false;
                            }
                        }

                        contactCategorizer.CategorizeContacts(pairHandler, characterBody.CollisionInformation, ref downDirection,
                                                              ref tractionContacts, ref supportContacts, ref sideContacts, ref headContacts);
                    }
                    //TODO: It would be nice if this was a bit easier.
                    //Having to remember to clean up AND give it back is a bit weird, especially with the property-diving.
                    //No one would ever just guess this correctly.
                    //At least hide it behind a NarrowPhaseHelper function.
                    pairHandler.CleanUp();
                    pairHandler.Factory.GiveBack(pairHandler);
                }
            }
        }
 public bool ConfigureContactManifold(int workerIndex, CollidablePair pair, int childIndexA, int childIndexB, ref ConvexContactManifold manifold)
 {
     if (manifold.Count > 0)
     {
         Console.WriteLine($"SUBPAIR: {pair.A} child {childIndexA} versus {pair.B} child {childIndexB}");
     }
     return(true);
 }
Example #9
0
 public unsafe bool ConfigureContactManifold(int workerIndex, CollidablePair pair, ConvexContactManifold *manifold, out PairMaterialProperties pairMaterial)
 {
     GetMaterial(out pairMaterial);
     //Console.WriteLine("ConfigureContactManifold2");
     //Console.WriteLine(pair.A.Handle);
     //Console.WriteLine(pair.B.Handle);
     return(true);
 }
 public bool ConfigureContactManifold(int workerIndex, CollidablePair pair, ContactManifold *manifold, out PairMaterialProperties pairMaterial)
 {
     pairMaterial.FrictionCoefficient             = 1;
     pairMaterial.MaximumRecoveryVelocity         = float.MaxValue;
     pairMaterial.SpringSettings.NaturalFrequency = MathHelper.Pi * 30;
     pairMaterial.SpringSettings.DampingRatio     = 100f;// 100000;
     return(true);
 }
 public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold>
 {
     pairMaterial = new PairMaterialProperties {
         FrictionCoefficient = 1, MaximumRecoveryVelocity = 2, SpringSettings = new SpringSettings(30, 1)
     };
     Characters.TryReportContacts(pair, ref manifold, workerIndex, ref pairMaterial);
     return(true);
 }
Example #12
0
 public unsafe bool ConfigureContactManifold(int workerIndex, CollidablePair pair, ConvexContactManifold *manifold, out PairMaterialProperties pairMaterial)
 {
     if (manifold->Count > 0)
     {
         Console.WriteLine($"CONVEX PAIR: {pair.A} versus {pair.B}");
     }
     ConfigureMaterial(out pairMaterial);
     return(true);
 }
Example #13
0
        public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold>
        {
            //For the purposes of this demo, we'll use multiplicative blending for the friction and choose spring properties according to which collidable has a higher maximum recovery velocity.
            var a = CollidableMaterials[pair.A];
            var b = CollidableMaterials[pair.B];

            pairMaterial.FrictionCoefficient     = a.FrictionCoefficient * b.FrictionCoefficient;
            pairMaterial.MaximumRecoveryVelocity = MathF.Max(a.MaximumRecoveryVelocity, b.MaximumRecoveryVelocity);
            pairMaterial.SpringSettings          = pairMaterial.MaximumRecoveryVelocity == a.MaximumRecoveryVelocity ? a.SpringSettings : b.SpringSettings;
            return(true);
        }
Example #14
0
            public bool ConfigureContactManifold(int workerIndex, CollidablePair pair, int childIndexA, int childIndexB, ref ConvexContactManifold manifold)
            {
                BepuPhysicsComponent A = getFromReference(pair.A);
                BepuPhysicsComponent B = getFromReference(pair.B);

                if (((uint)A.CanCollideWith & (uint)B.CollisionGroup) != 0)
                {
                    RecordContact(A, B, ref manifold);
                    return(!A.GhostBody && !B.GhostBody);
                }
                return(false);
            }
Example #15
0
 public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold>
 {
     pairMaterial.FrictionCoefficient = Properties[pair.A.Handle].Friction;
     if (pair.B.Mobility != CollidableMobility.Static)
     {
         //If two bodies collide, just average the friction.
         pairMaterial.FrictionCoefficient = (pairMaterial.FrictionCoefficient + Properties[pair.B.Handle].Friction) * 0.5f;
     }
     pairMaterial.MaximumRecoveryVelocity = 2f;
     pairMaterial.SpringSettings          = new SpringSettings(30, 1);
     return(true);
 }
        //Note that this does not check collision rules.
        /// <summary>
        /// Tests the pair of collidables for intersection without regard for collision rules.
        /// </summary>
        /// <param name="pair">Pair to test.</param>
        /// <returns>Whether or not the pair is intersecting.</returns>
        public static bool Intersecting(ref CollidablePair pair)
        {
            var pairHandler = GetPairHandler(ref pair);

            pairHandler.SuppressEvents = true;
            pairHandler.UpdateCollision(0);
            bool toReturn = pairHandler.ContactCount > 0;

            pairHandler.SuppressEvents = false;
            pairHandler.CleanUp();
            (pairHandler as NarrowPhasePair).Factory.GiveBack(pairHandler);
            return(toReturn);
        }
Example #17
0
        public World CreateWorld()
        {
            int   conver = Point3D.vectortrans;
            World place  = new World((Width / conver) + 1, 1, (Height / conver) + 1);

            for (int x = 0; x < place.Right; x++)
            {
                for (int y = 0; y < place.Top; y++)
                {
                    for (int z = 0; z < place.Back; z++)
                    {
                        BoundingBox            box  = new BoundingBox(new Vector3(x * conver, minheight + 5, z * conver), new Vector3(((x + 1) * conver) - 1, minheight + 25, ((z + 1) * conver) - 1));
                        List <BroadPhaseEntry> list = new List <BroadPhaseEntry>();
                        game.Space.BroadPhase.QueryAccelerator.GetEntries(box, list);
                        Ray ray;

                        if (list.Count > 0)
                        {
                            for (int k = 0; k < list.Count; k++)
                            {
                                StaticMesh temp        = list[k] as StaticMesh;
                                var        pair        = new CollidablePair(temp, new Box(new Vector3(x * conver, minheight + 5, z * conver), conver, 25, conver).CollisionInformation);
                                var        pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair);
                                pairHandler.SuppressEvents = true;
                                pairHandler.UpdateCollision(0);
                                pairHandler.SuppressEvents = false;

                                if (pairHandler.Colliding)
                                {
                                    place.MarkPosition(new Point3D(x, y, z), true);
                                    break;
                                }

                                pairHandler.CleanUp();
                                pairHandler.Factory.GiveBack(pairHandler);
                            }
                        }
                        //prevent the starting square from being blocked

                        /*if ((x + y + z) % 3 == 0 && (x + y + z) != 0)
                         * {
                         *  place.MarkPosition(new Point3D(x, y, z), true);
                         * }*/
                    }
                }
            }


            return(place);
        }
Example #18
0
        private void QueryContacts(Vector3 position, EntityCollidable queryObject)
        {
            this.ClearContacts();

            //Update the position and orientation of the query object.
            RigidTransform transform;

            transform.Position    = position;
            transform.Orientation = this.character.Body.Orientation;
            queryObject.UpdateBoundingBoxForTransform(ref transform, 0);

            foreach (var collidable in this.character.Body.CollisionInformation.OverlappedCollidables)
            {
                if (collidable.BoundingBox.Intersects(queryObject.BoundingBox))
                {
                    var pair        = new CollidablePair(collidable, queryObject);
                    var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair);
                    if (pairHandler.CollisionRule == CollisionRule.Normal)
                    {
                        pairHandler.SuppressEvents = true;
                        pairHandler.UpdateCollision(0);
                        pairHandler.SuppressEvents = false;

                        foreach (var contact in pairHandler.Contacts)
                        {
                            //Must check per-contact collision rules, just in case
                            //the pair was actually a 'parent pair.'
                            if (contact.Pair.CollisionRule == CollisionRule.Normal)
                            {
                                ContactData contactData;
                                contactData.Position         = contact.Contact.Position;
                                contactData.Normal           = contact.Contact.Normal;
                                contactData.Id               = contact.Contact.Id;
                                contactData.PenetrationDepth = contact.Contact.PenetrationDepth;
                                this.contacts.Add(contactData);
                            }
                        }
                    }
                    //TODO: It would be nice if this was a bit easier.
                    //Having to remember to clean up AND give it back is a bit weird, especially with the property-diving.
                    //No one would ever just guess this correctly.
                    //At least hide it behind a NarrowPhaseHelper function.
                    pairHandler.CleanUp();
                    pairHandler.Factory.GiveBack(pairHandler);
                }
            }

            this.CategorizeContacts(ref position);
        }
Example #19
0
            public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold>
            {
                BepuPhysicsComponent a = getFromReference(pair.A);
                BepuPhysicsComponent b = getFromReference(pair.B);

                pairMaterial.FrictionCoefficient              = a.FrictionCoefficient * b.FrictionCoefficient;
                pairMaterial.MaximumRecoveryVelocity          = (a.MaximumRecoveryVelocity + b.MaximumRecoveryVelocity) * 0.5f;
                pairMaterial.SpringSettings.AngularFrequency  = (a.SpringSettings.AngularFrequency + b.SpringSettings.AngularFrequency) * 0.5f;
                pairMaterial.SpringSettings.TwiceDampingRatio = (a.SpringSettings.TwiceDampingRatio + b.SpringSettings.TwiceDampingRatio) * 0.5f;
                if (((uint)a.CanCollideWith & (uint)b.CollisionGroup) != 0)
                {
                    RecordContact(a, b, ref manifold);
                    return(!a.GhostBody && !b.GhostBody);
                }
                return(false);
            }
Example #20
0
        /// <summary>
        /// Tests the pair of collidables for intersection without regard for collision rules.
        /// </summary>
        /// <param name="pair">Pair to test.</param>
        /// <returns>Whether or not the pair is intersecting.</returns>
        public static bool Intersecting(ref CollidablePair pair)
        {
            var pairHandler = GetPairHandler(ref pair);

            if (pairHandler == null)
            {
                return(false);
            }
            pairHandler.SuppressEvents = true;
            pairHandler.UpdateCollision(0);
            bool toReturn = pairHandler.Colliding;

            pairHandler.SuppressEvents = false;
            pairHandler.CleanUp();
            pairHandler.Factory.GiveBack(pairHandler);
            return(toReturn);
        }
Example #21
0
        /// <summary>
        /// Tests the pair of collidables for intersection without regard for collision rules.
        /// </summary>
        /// <param name="pair">Pair to test.</param>
        /// <returns>Whether or not the pair is intersecting.</returns>
        public static bool Intersecting(ref CollidablePair pair)
        {
            var pairHandler = GetPairHandler(ref pair);

            pairHandler.SuppressEvents = true;
            pairHandler.UpdateCollision(0);
            //Technically, contacts with negative depth do not count.
            //The current implementation of collision detection does not generate
            //negative depths on the first execution of UpdateCollision, though,
            //so we don't need to worry about that- yet.
            bool toReturn = pairHandler.ContactCount > 0;

            pairHandler.SuppressEvents = false;
            pairHandler.CleanUp();
            pairHandler.Factory.GiveBack(pairHandler);
            return(toReturn);
        }
 public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold>
 {
     if (manifold.Count > 0)
     {
         if (manifold.Convex)
         {
             Console.WriteLine($"CONVEX PAIR: {pair.A} versus {pair.B}");
         }
         else
         {
             Console.WriteLine($"NONCONVEX PAIR: {pair.A} versus {pair.B}");
         }
     }
     pairMaterial.FrictionCoefficient     = 1f;
     pairMaterial.MaximumRecoveryVelocity = 2f;
     pairMaterial.SpringSettings          = new SpringSettings(30, 1);
     return(true);
 }
        protected void TryToAdd(int index)
        {
            var entry = new TriangleEntry {
                Index = index
            };

            if (!subPairs.ContainsKey(entry))
            {
                var collidablePair = new CollidablePair(CollidableA, entry.Collidable = GetOpposingCollidable(index));
                var newPair        = (MobileMeshPairHandler)NarrowPhaseHelper.GetPairHandler(ref collidablePair);
                if (newPair != null)
                {
                    newPair.CollisionRule = CollisionRule;
                    newPair.UpdateMaterialProperties(MaterialA, MaterialB);  //Override the materials, if necessary.  Meshes don't currently support custom materials but..
                    newPair.Parent = this;
                    subPairs.Add(entry, newPair);
                }
            }
            containedPairs.Add(entry);
        }
Example #24
0
        ///<summary>
        /// Determines whether or not an entity is intersecting the triangle shell of a detector volume.
        ///</summary>
        ///<param name="entity">Entity to test.</param>
        /// <param name="intersectedTriangleIndices">First indices of intersected triangles in the index buffer.</param>
        ///<returns>Whether or not the entity is intersecting the shell.</returns>
        public bool IsEntityIntersectingShell(Entity entity, IList <int> intersectedTriangleIndices)
        {
            TriangleMesh.Tree.GetOverlaps(entity.CollisionInformation.BoundingBox, intersectedTriangleIndices);
            foreach (int i in intersectedTriangleIndices)
            {
                Vector3 v1, v2, v3;
                triangleMesh.Data.GetTriangle(i, out v1, out v2, out v3);
                var triangle = Resources.GetTriangleCollidable(ref v1, ref v2, ref v3);
                //TODO: Test a TRIANGLE against ANYTHING ELSE.
                //Requires BOOLEAN tests initially for:
                //Triangle-Convex
                //Triangle-CompoundShape
                var pair = new CollidablePair(entity.CollisionInformation, triangle);
                if (NarrowPhaseHelper.Intersecting(ref pair))
                {
                    Resources.GiveBack(triangle);
                    return(true);
                }
                Resources.GiveBack(triangle);
            }

            return(false);
        }
Example #25
0
        ///<summary>
        /// Determines whether or not an entity is intersecting the triangle shell of a detector volume.
        ///</summary>
        ///<param name="entity">Entity to test.</param>
        /// <param name="intersectedTriangleIndices">First indices of intersected triangles in the index buffer.</param>
        ///<returns>Whether or not the entity is intersecting the shell.</returns>
        public bool IsEntityIntersectingShell(Entity entity, IList<int> intersectedTriangleIndices)
        {

            TriangleMesh.Tree.GetOverlaps(entity.CollisionInformation.BoundingBox, intersectedTriangleIndices);
            foreach (int i in intersectedTriangleIndices)
            {
                Vector3 v1, v2, v3;
                triangleMesh.Data.GetTriangle(i, out v1, out v2, out v3);
                var triangle = Resources.GetTriangleCollidable(ref v1, ref v2, ref v3);
                //TODO: Test a TRIANGLE against ANYTHING ELSE.
                //Requires BOOLEAN tests initially for:
                //Triangle-Convex
                //Triangle-CompoundShape
                var pair = new CollidablePair(entity.CollisionInformation, triangle);
                if (NarrowPhaseHelper.Intersecting(ref pair))
                {
                    Resources.GiveBack(triangle);
                    return true;
                }
                Resources.GiveBack(triangle);
            }

            return false;
        }
 /// <summary>
 /// Tests the pair of collidables for intersection without regard for collision rules.
 /// </summary>
 /// <param name="pair">Pair to test.</param>
 /// <returns>Whether or not the pair is intersecting.</returns>
 public static bool Intersecting(ref CollidablePair pair)
 {
     var pairHandler = GetPairHandler(ref pair);
     if (pairHandler == null)
         return false;
     pairHandler.SuppressEvents = true;
     pairHandler.UpdateCollision(0);
     //Technically, contacts with negative depth do not count.
     //The current implementation of collision detection does not generate
     //negative depths on the first execution of UpdateCollision, though,
     //so we don't need to worry about that- yet.
     bool toReturn = pairHandler.ContactCount > 0;
     pairHandler.SuppressEvents = false;
     pairHandler.CleanUp();
     pairHandler.Factory.GiveBack(pairHandler);
     return toReturn;
 }
 /// <summary>
 /// Gets a collidable pair handler for a pair of collidables.
 /// </summary>
 /// <param name="pair">Pair of collidables to use to create the pair handler.</param>
 /// <returns>CollidablePairHandler for the pair.</returns>
 public static CollidablePairHandler GetPairHandler(ref CollidablePair pair)
 {
     var overlap = new BroadPhaseOverlap(pair.collidableA, pair.collidableB);
     return GetPairHandler(ref overlap) as CollidablePairHandler;
 }
Example #28
0
 protected void TryToAdd(Collidable a, Collidable b, Material materialA, Material materialB)
 {
     CollisionRule rule;
     if ((rule = CollisionRules.collisionRuleCalculator(a, b)) < CollisionRule.NoNarrowPhasePair)
     {
         //Clamp the rule to the parent's rule.  Always use the more restrictive option.
         //Don't have to test for NoNarrowPhasePair rule on the parent's rule because then the parent wouldn't exist!
         if (rule < CollisionRule)
             rule = CollisionRule;
         var pair = new CollidablePair(a, b);
         if (!subPairs.ContainsKey(pair))
         {
             var newPair = NarrowPhaseHelper.GetPairHandler(ref pair, rule);
             if (newPair != null)
             {
                 newPair.UpdateMaterialProperties(materialA, materialB);  //Override the materials, if necessary.
                 newPair.Parent = this;
                 subPairs.Add(pair, newPair);
             }
         }
         containedPairs.Add(pair);
     }
 }
Example #29
0
 public bool ConfigureContactManifold(int workerIndex, CollidablePair pair, int childIndexA, int childIndexB,
                                      ref ConvexContactManifold manifold)
 {
     return(true);
 }
 /// <summary>
 /// Gets a collidable pair handler for a pair of collidables.
 /// </summary>
 /// <param name="pair">Pair of collidables to use to create the pair handler.</param>
 /// <param name="rule">Collision rule governing the pair.</param>
 /// <returns>CollidablePairHandler for the pair.</returns>
 public static CollidablePairHandler GetPairHandler(ref CollidablePair pair, CollisionRule rule)
 {
     BroadPhaseOverlap overlap = new BroadPhaseOverlap(pair.collidableA, pair.collidableB, rule);
     return GetPair(ref overlap) as CollidablePairHandler;
 }
 //Note that this does not check collision rules.
 /// <summary>
 /// Tests the pair of collidables for intersection without regard for collision rules.
 /// </summary>
 /// <param name="pair">Pair to test.</param>
 /// <returns>Whether or not the pair is intersecting.</returns>
 public static bool Intersecting(ref CollidablePair pair)
 {
     var pairHandler = GetPairHandler(ref pair);
     pairHandler.SuppressEvents = true;
     pairHandler.UpdateCollision(0);
     bool toReturn = pairHandler.ContactCount > 0;
     pairHandler.SuppressEvents = false;
     pairHandler.CleanUp();
     (pairHandler as NarrowPhasePair).Factory.GiveBack(pairHandler);
     return toReturn;
 }
Example #32
0
 public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold>
 {
     pairMaterial = new PairMaterialProperties();
     return(false);
 }
Example #33
0
 public bool AllowContactGeneration(int workerIndex, CollidablePair pair, int childIndexA, int childIndexB)
 {
     return(true);
 }
Example #34
0
 /// <summary>
 /// Tests the pair of collidables for intersection without regard for collision rules.
 /// </summary>
 /// <param name="pair">Pair to test.</param>
 /// <returns>Whether or not the pair is intersecting.</returns>
 public static bool Intersecting(ref CollidablePair pair)
 {
     var pairHandler = GetPairHandler(ref pair);
     if (pairHandler == null)
         return false;
     pairHandler.SuppressEvents = true;
     pairHandler.UpdateCollision(0);
     bool toReturn = pairHandler.Colliding;
     pairHandler.SuppressEvents = false;
     pairHandler.CleanUp();
     pairHandler.Factory.GiveBack(pairHandler);
     return toReturn;
 }
Example #35
0
 public void OnContactAdded <TManifold>(CollidableReference eventSource, CollidablePair pair, ref TManifold contactManifold,
                                        in System.Numerics.Vector3 contactOffset, in System.Numerics.Vector3 contactNormal, float depth, int featureId, int contactIndex, int workerIndex) where TManifold : struct, IContactManifold <TManifold>
Example #36
0
        /// <summary>
        /// Gets a collidable pair handler for a pair of collidables.
        /// </summary>
        /// <param name="pair">Pair of collidables to use to create the pair handler.</param>
        /// <returns>CollidablePairHandler for the pair.</returns>
        public static CollidablePairHandler GetPairHandler(ref CollidablePair pair)
        {
            var overlap = new BroadPhaseOverlap(pair.collidableA, pair.collidableB);

            return(GetPairHandler(ref overlap) as CollidablePairHandler);
        }
Example #37
0
        void QueryContacts(Vector3 position, EntityCollidable queryObject)
        {
            ClearContacts();

            //Update the position and orientation of the query object.
            RigidTransform transform;
            transform.Position = position;
            transform.Orientation = character.Body.Orientation;
            queryObject.UpdateBoundingBoxForTransform(ref transform, 0);

            foreach (var collidable in character.Body.CollisionInformation.OverlappedCollidables)
            {
                if (collidable.BoundingBox.Intersects(queryObject.BoundingBox))
                {
                    var pair = new CollidablePair(collidable, queryObject);
                    var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair);
                    if (pairHandler.CollisionRule == CollisionRule.Normal)
                    {
                        pairHandler.UpdateCollision(0);
                        foreach (var contact in pairHandler.Contacts)
                        {
                            //Must check per-contact collision rules, just in case
                            //the pair was actually a 'parent pair.'
                            if (contact.Pair.CollisionRule == CollisionRule.Normal)
                            {
                                ContactData contactData;
                                contactData.Position = contact.Contact.Position;
                                contactData.Normal = contact.Contact.Normal;
                                contactData.Id = contact.Contact.Id;
                                contactData.PenetrationDepth = contact.Contact.PenetrationDepth;
                                contacts.Add(contactData);
                            }
                        }
                    }
                    //TODO: It would be nice if this was a bit easier.
                    //Having to remember to clean up AND give it back is a bit weird, especially with the property-diving.
                    //No one would ever just guess this correctly.
                    //At least hide it behind a NarrowPhaseHelper function.
                    pairHandler.CleanUp();
                    pairHandler.Factory.GiveBack(pairHandler);
                }
            }

            CategorizeContacts(ref position);
        }
Example #38
0
        /// <summary>
        /// Finds contacts between the query object and any intersected objects within the character's bounding box.
        /// </summary>
        /// <param name="queryObject">Collidable to query for contacts with.</param>
        /// <param name="tractionContacts">Output contacts that would provide traction.</param>
        /// <param name="supportContacts">Output contacts that would provide support.</param>
        /// <param name="sideContacts">Output contacts on the sides of the query object.</param>
        /// <param name="headContacts">Output contacts on the head of the query object.</param>
        public void QueryContacts(EntityCollidable queryObject,
            ref QuickList<CharacterContact> tractionContacts, ref QuickList<CharacterContact> supportContacts, ref QuickList<CharacterContact> sideContacts, ref QuickList<CharacterContact> headContacts)
        {
            var downDirection = characterBody.orientationMatrix.Down;

            tractionContacts.Clear();
            supportContacts.Clear();
            sideContacts.Clear();
            headContacts.Clear();

            foreach (var collidable in characterBody.CollisionInformation.OverlappedCollidables)
            {
                //The query object is assumed to have a valid bounding box.
                if (collidable.BoundingBox.Intersects(queryObject.BoundingBox))
                {
                    var pair = new CollidablePair(collidable, queryObject);
                    var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair);
                    if (pairHandler.CollisionRule == CollisionRule.Normal)
                    {
                        pairHandler.SuppressEvents = true;
                        pairHandler.UpdateCollision(0);
                        pairHandler.SuppressEvents = false;

                        contactCategorizer.CategorizeContacts(pairHandler, characterBody.CollisionInformation, ref downDirection,
                                                              ref tractionContacts, ref supportContacts, ref sideContacts, ref headContacts);
                    }
                    //TODO: It would be nice if this was a bit easier.
                    //Having to remember to clean up AND give it back is a bit weird, especially with the property-diving.
                    //No one would ever just guess this correctly.
                    //At least hide it behind a NarrowPhaseHelper function.
                    pairHandler.CleanUp();
                    pairHandler.Factory.GiveBack(pairHandler);
                }
            }

        }
Example #39
0
 public unsafe bool ConfigureContactManifold(int workerIndex, CollidablePair pair, ConvexContactManifold *manifold, out PairMaterialProperties pairMaterial)
 {
     GetMaterial(out pairMaterial);
     return(true);
 }