Exemplo n.º 1
0
        CharacterContactPositionState TrySupportLocation(ConvexCollidable <CylinderShape> queryObject, ref Vector3 position, out float hintOffset,
                                                         ref QuickList <CharacterContact> tractionContacts, ref QuickList <CharacterContact> supportContacts, ref QuickList <CharacterContact> sideContacts, ref QuickList <CharacterContact> headContacts)
        {
            hintOffset = 0;
            PrepareQueryObject(queryObject, ref position);
            QueryManager.QueryContacts(queryObject, ref tractionContacts, ref supportContacts, ref sideContacts, ref headContacts, true);

            bool obstructed = IsObstructed(ref sideContacts, ref headContacts);

            if (obstructed)
            {
                return(CharacterContactPositionState.Obstructed);
            }
            if (supportContacts.Count > 0)
            {
                CharacterContactPositionState supportState;
                CharacterContact supportContact;
                QueryManager.AnalyzeSupportState(ref tractionContacts, ref supportContacts, out supportState, out supportContact);
                var down = characterBody.orientationMatrix.Down;
                //Note that traction is not tested for; it isn't important for the stance manager.
                if (supportState == CharacterContactPositionState.Accepted)
                {
                    //We're done! The guess found a good spot to stand on.
                    //We need to have fairly good contacts after this process, so only push it up a bit.
                    hintOffset = Math.Min(0, Vector3.Dot(supportContact.Contact.Normal, down) * (CollisionDetectionSettings.AllowedPenetration * .5f - supportContact.Contact.PenetrationDepth));
                    return(CharacterContactPositionState.Accepted);
                }
                else if (supportState == CharacterContactPositionState.TooDeep)
                {
                    //Looks like we have to keep trying, but at least we found a good hint.
                    hintOffset = Math.Min(0, Vector3.Dot(supportContact.Contact.Normal, down) * (CollisionDetectionSettings.AllowedPenetration * .5f - supportContact.Contact.PenetrationDepth));
                    return(CharacterContactPositionState.TooDeep);
                }
                else //if (supportState == SupportState.Separated)
                {
                    //It's not obstructed, but the support isn't quite right.
                    //It's got a negative penetration depth.
                    //We can use that as a hint.
                    hintOffset = -.001f - Vector3.Dot(supportContact.Contact.Normal, down) * supportContact.Contact.PenetrationDepth;
                    return(CharacterContactPositionState.NoHit);
                }
            }
            else //Not obstructed, but no support.
            {
                return(CharacterContactPositionState.NoHit);
            }
        }
        public override void Initialize(Collidable newCollidableA, Collidable newCollidableB)
        {
            convex   = newCollidableA as ConvexCollidable;
            triangle = newCollidableB as ConvexCollidable <TriangleShape>;


            if (convex == null || triangle == null)
            {
                convex   = newCollidableB as ConvexCollidable;
                triangle = newCollidableA as ConvexCollidable <TriangleShape>;
                if (convex == null || triangle == null)
                {
                    throw new ArgumentException("Inappropriate types used to initialize contact manifold.");
                }
            }

            pairTester.Initialize(convex.Shape);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Constructs a stance manager for a character.
        /// </summary>
        /// <param name="characterBody">The character's body entity.</param>
        /// <param name="crouchingHeight">Crouching height of the character.</param>
        /// <param name="proneHeight">Prone height of the character.</param>
        /// <param name="queryManager">Provider of queries used by the stance manager to test if it is okay to change stances.</param>
        /// <param name="supportFinder">Support finder used by the character.</param>
        public StanceManager(Cylinder characterBody, float crouchingHeight, float proneHeight, QueryManager queryManager, SupportFinder supportFinder)
        {
            this.QueryManager  = queryManager;
            this.SupportFinder = supportFinder;
            this.characterBody = characterBody;
            standingHeight     = characterBody.Height;
            if (crouchingHeight < standingHeight)
            {
                this.crouchingHeight = crouchingHeight;
            }
            else
            {
                throw new ArgumentException("Crouching height must be less than standing height.");
            }
            if (proneHeight < crouchingHeight)
            {
                this.proneHeight = proneHeight;
            }
            else
            {
                throw new ArgumentException("Prone height must be less than crouching height.");
            }

            //We can share the real shape with the query objects.
            currentQueryObject  = new ConvexCollidable <CylinderShape>(characterBody.CollisionInformation.Shape);
            standingQueryObject = new ConvexCollidable <CylinderShape>(new CylinderShape(StandingHeight, characterBody.Radius)
            {
                CollisionMargin = currentQueryObject.Shape.CollisionMargin
            });
            crouchingQueryObject = new ConvexCollidable <CylinderShape>(new CylinderShape(CrouchingHeight, characterBody.Radius)
            {
                CollisionMargin = currentQueryObject.Shape.CollisionMargin
            });
            proneQueryObject = new ConvexCollidable <CylinderShape>(new CylinderShape(proneHeight, characterBody.Radius)
            {
                CollisionMargin = currentQueryObject.Shape.CollisionMargin
            });
            //Share the collision rules between the main body and its query objects.  That way, the character's queries return valid results.
            currentQueryObject.CollisionRules   = characterBody.CollisionInformation.CollisionRules;
            standingQueryObject.CollisionRules  = characterBody.CollisionInformation.CollisionRules;
            crouchingQueryObject.CollisionRules = characterBody.CollisionInformation.CollisionRules;
            proneQueryObject.CollisionRules     = characterBody.CollisionInformation.CollisionRules;
        }
Exemplo n.º 4
0
        ///<summary>
        /// Initializes the pair handler.
        ///</summary>
        ///<param name="entryA">First entry in the pair.</param>
        ///<param name="entryB">Second entry in the pair.</param>
        public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB)
        {
            box    = entryA as ConvexCollidable <BoxShape>;
            sphere = entryB as ConvexCollidable <SphereShape>;

            if (box == null || sphere == null)
            {
                box    = entryB as ConvexCollidable <BoxShape>;
                sphere = entryA as ConvexCollidable <SphereShape>;
                if (box == null || sphere == null)
                {
                    throw new ArgumentException("Inappropriate types used to initialize pair.");
                }
            }

            //Reorder the entries so that the guarantee that the normal points from A to B is satisfied.
            broadPhaseOverlap.entryA = box;
            broadPhaseOverlap.entryB = sphere;

            base.Initialize(entryA, entryB);
        }
Exemplo n.º 5
0
        ///<summary>
        /// Initializes the pair handler.
        ///</summary>
        ///<param name="entryA">First entry in the pair.</param>
        ///<param name="entryB">Second entry in the pair.</param>
        public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB)
        {
            triangle = entryA as ConvexCollidable <TriangleShape>;
            convex   = entryB as ConvexCollidable;

            if (triangle == null || convex == null)
            {
                triangle = entryB as ConvexCollidable <TriangleShape>;
                convex   = entryA as ConvexCollidable;

                if (triangle == null || convex == null)
                {
                    throw new ArgumentException("Inappropriate types used to initialize pair.");
                }
            }

            //Contact normal goes from A to B.
            broadPhaseOverlap.entryA = convex;
            broadPhaseOverlap.entryB = triangle;

            base.Initialize(entryA, entryB);
        }
Exemplo n.º 6
0
        ///<summary>
        /// Initializes the pair handler.
        ///</summary>
        ///<param name="entryA">First entry in the pair.</param>
        ///<param name="entryB">Second entry in the pair.</param>
        public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB)
        {
            terrain = entryA as Terrain;
            convex  = entryB as ConvexCollidable;

            if (terrain == null || convex == null)
            {
                terrain = entryB as Terrain;
                convex  = entryA as ConvexCollidable;

                if (terrain == null || convex == null)
                {
                    throw new ArgumentException("Inappropriate types used to initialize pair.");
                }
            }

            //Contact normal goes from A to B.
            broadPhaseOverlap.entryA = convex;
            broadPhaseOverlap.entryB = terrain;

            UpdateMaterialProperties(convex.entity != null ? convex.entity.material : null, terrain.material);

            base.Initialize(entryA, entryB);
        }
Exemplo n.º 7
0
 ///<summary>
 /// Cleans up the manifold.
 ///</summary>
 public override void CleanUp()
 {
     boxA = null;
     boxB = null;
     base.CleanUp();
 }
 ///<summary>
 /// Cleans up the pair handler.
 ///</summary>
 public override void CleanUp()
 {
     base.CleanUp();
     convexInfo = null;
 }
Exemplo n.º 9
0
 public override void CleanUp()
 {
     base.CleanUp();
     convex           = null;
     checkContainment = true;
 }
 ///<summary>
 /// Cleans up the pair handler.
 ///</summary>
 public override void CleanUp()
 {
     base.CleanUp();
     instancedMesh = null;
     convex        = null;
 }