Page 1 of 1

Collision Test

Posted: Sat Feb 16, 2013 4:58 pm
by Peter Prins
I want to test that my Entity will not cause any collisions at its starting transform before I add it to the space. How would I do that?

Re: Collision Test

Posted: Sat Feb 16, 2013 9:08 pm
by Norbo
One option would be to accumulate nearby objects with a Space.BroadPhase.QueryAccelerator.GetEntries call. Then, between each collected broad phase entry and the query object's collidable, test for collision. Check out the CharacterController's QueryManager for a detailed look at how to do this. There's also a NarrowPhaseHelper.Intersecting method which will handle the tedious parts for you.

Re: Collision Test

Posted: Sat Mar 02, 2013 1:24 am
by Peter Prins
This seems to work in some cases, however not in all. When I use a ConvexHullShape for the Collidable and it finds an overlap with the terrain, the game crashes with a NullReferenceException. the method creating the null reference is the following method from the NarrowPhaseHelper:

Code: Select all

        ///<summary>
        /// Gets a narrow phase pair for a given broad phase overlap.
        ///</summary>
        ///<param name="pair">Overlap to use to create the pair.</param>
        ///<returns>A INarrowPhasePair for the overlap.</returns>
        public static NarrowPhasePair GetPairHandler(ref BroadPhaseOverlap pair)
        {
            NarrowPhasePairFactory factory;
            if (collisionManagers.TryGetValue(new TypePair(pair.entryA.GetType(), pair.entryB.GetType()), out factory))
            {
                var toReturn = factory.GetNarrowPhasePair();
                toReturn.BroadPhaseOverlap = pair;
                toReturn.Factory = factory;
                return toReturn;
            }
            //Convex-convex collisions are a pretty significant chunk of all tests, so rather than defining them all, just have a fallback.
            var a = pair.entryA as ConvexCollidable;
            var b = pair.entryB as ConvexCollidable;
            if (a != null && b != null)
            {
                NarrowPhasePair toReturn = Factories.ConvexConvex.GetNarrowPhasePair();
                toReturn.BroadPhaseOverlap = pair;
                toReturn.Factory = Factories.ConvexConvex;
                return toReturn;
            }
            return null;
        }
This method fails both its if-statements, returning a null reference on its last line.

Re: Collision Test

Posted: Sat Mar 02, 2013 1:28 am
by Norbo
That implies that the BroadPhaseOverlap passed into the method has no associated pair handler. For example, passing in a pair of StaticMeshes would cause that because StaticMeshes cannot collide with StaticMeshes.

Re: Collision Test

Posted: Sat Mar 02, 2013 1:35 am
by Peter Prins
All right, I've gotten it to work, but the reason for the bug seems very strange to me. Everything goes fine when I define the Collidable to test against as follows:

Code: Select all

new ConvexCollidable<BoxShape>(new BoxShape(3f, .2f, 2f))
But when I define the Collidable like this it fails:

Code: Select all

new ConvexCollidable<ConvexShape>(new BoxShape(3f, .2f, 2f))

Re: Collision Test

Posted: Sat Mar 02, 2013 3:42 am
by Norbo
The collidable type is used to determine the pair handler type (and thus the collision detection special case). ConvexCollidable<ConvexShape> is too high in the hierarchy to provide useful information about which special case to be used.

The fallback will catch two such convex collidables, but there is no entry for static-ConvexCollidable<ConvexShape>. You can add such a thing if you want- it's just another set of entries in the dictionary- but using the concrete type will allow special cases to be used if they are available.

Re: Collision Test

Posted: Sat Mar 02, 2013 10:55 am
by Peter Prins
Ok, I'll keep using the more specific collidables then, I like special cases :)