Stores how an object can interact with other objects through collisions.
예제 #1
0
 ///<summary>
 /// Tries to remove a relationship about rulesB from ownerA's Specific list.
 ///</summary>
 ///<param name="ownerA">Owner of the collision rules that will lose an entry in its Specific relationships.</param>
 ///<param name="rulesB">Collision rules that will be removed from ownerA's Specific relationships.</param>
 public static void RemoveRule(ICollisionRulesOwner ownerA, CollisionRules rulesB)
 {
     if (!ownerA.CollisionRules.specific.Remove(rulesB))
     {
         rulesB.specific.Remove(ownerA.CollisionRules);
     }
 }
예제 #2
0
        protected BroadPhaseEntry()
        {
            CollisionRules = new CollisionRules();
            collisionRulesUpdatedDelegate = CollisionRulesUpdated;

            hashCode = (int)(base.GetHashCode() * 0xd8163841);
        }
예제 #3
0
 ///<summary>
 /// Tries to remove a relationship about ownerB from rulesA's Specific list.
 ///</summary>
 ///<param name="rulesA">Collision rules that will lose an entry in its Specific relationships.</param>
 ///<param name="ownerB">Owner of the collision rules that will be removed from ownerA's Specific relationships.</param>
 public static void RemoveRule(CollisionRules rulesA, ICollisionRulesOwner ownerB)
 {
     if (!rulesA.specific.Remove(ownerB.CollisionRules))
     {
         ownerB.CollisionRules.specific.Remove(rulesA);
     }
 }
예제 #4
0
 ///<summary>
 /// Default implementation used to calculate collision rules due to the rulesets' personal rules.
 ///</summary>
 ///<param name="a">First ruleset in the pair.</param>
 ///<param name="b">Second ruleset in the pair.</param>
 ///<returns>Collision rule governing the interaction between the pair.</returns>
 public static CollisionRule GetPersonalCollisionRuleDefault(CollisionRules a, CollisionRules b)
 {
     if (a == null || b == null)
     {
         return(CollisionRule.Defer);
     }
     return(a.personal > b.personal ? a.personal : b.personal);
 }
예제 #5
0
        ///<summary>
        /// Default implementation used to calculate collision rules due to the rulesets' specific relationships.
        ///</summary>
        ///<param name="a">First ruleset in the pair.</param>
        ///<param name="b">Second ruleset in the pair.</param>
        ///<returns>Collision rule governing the interaction between the pair.</returns>
        public static CollisionRule GetSpecificCollisionRuleDefault(CollisionRules a, CollisionRules b)
        {
            CollisionRule aToB;

            a.specific.WrappedDictionary.TryGetValue(b, out aToB);
            CollisionRule bToA;

            b.specific.WrappedDictionary.TryGetValue(a, out bToA);
            return(aToB > bToA ? aToB : bToA);
        }
예제 #6
0
        ///<summary>
        /// Default implementation used to calculate collision rules due to the rulesets' collision groups.
        ///</summary>
        ///<param name="a">First ruleset in the pair.</param>
        ///<param name="b">Second ruleset in the pair.</param>
        ///<returns>Collision rule governing the interaction between the pair.</returns>
        public static CollisionRule GetGroupCollisionRuleDefault(CollisionRules a, CollisionRules b)
        {
            if (a.group == null || b.group == null)
            {
                return(CollisionRule.Defer); //This can happen occasionally when objects aren't in a space or are being handled uniquely (like in compound bodies).
            }
            CollisionRule pairRule;

            CollisionGroupRules.TryGetValue(new CollisionGroupPair(a.group, b.group), out pairRule);
            return(pairRule);
        }
예제 #7
0
        ///<summary>
        /// Default implementation used to calculate collision rules due to the rulesets' specific relationships.
        ///</summary>
        ///<param name="a">First ruleset in the pair.</param>
        ///<param name="b">Second ruleset in the pair.</param>
        ///<returns>Collision rule governing the interaction between the pair.</returns>
        public static CollisionRule GetSpecificCollisionRuleDefault(CollisionRules a, CollisionRules b)
        {
            if (a == null || b == null || a.specific == null || b.specific == null)
            {
                return(CollisionRule.Defer);
            }
            CollisionRule aToB;

            a.specific.WrappedDictionary.TryGetValue(b, out aToB);
            CollisionRule bToA;

            b.specific.WrappedDictionary.TryGetValue(a, out bToA);
            return(aToB > bToA ? aToB : bToA);
        }
예제 #8
0
        /// <summary>
        /// Determines what collision rule governs the interaction between the two objects.
        /// </summary>
        /// <param name="a">First ruleset in the pair.  This entity's space is used to determine the collision detection settings that contain special collision group interaction rules.</param>
        /// <param name="b">Second ruleset in the pair.</param>
        /// <returns>Collision rule governing the interaction between the pair.</returns>
        public static CollisionRule GetCollisionRuleDefault(CollisionRules a, CollisionRules b)
        {
            CollisionRule pairRule = GetSpecificCollisionRuleDefault(a, b);

            if (pairRule == CollisionRule.Defer)
            {
                pairRule = GetPersonalCollisionRuleDefault(a, b);
                if (pairRule == CollisionRule.Defer)
                {
                    pairRule = GetGroupCollisionRuleDefault(a, b);
                }
            }

            if (pairRule == CollisionRule.Defer)
            {
                pairRule = DefaultCollisionRule;
            }
            return(pairRule);
        }
예제 #9
0
 ///<summary>
 /// Default implementation used to calculate collision rules due to the rulesets' personal rules.
 ///</summary>
 ///<param name="a">First ruleset in the pair.</param>
 ///<param name="b">Second ruleset in the pair.</param>
 ///<returns>Collision rule governing the interaction between the pair.</returns>
 public static CollisionRule GetPersonalCollisionRuleDefault(CollisionRules a, CollisionRules b)
 {
     return a.personal > b.personal ? a.personal : b.personal;
 }
예제 #10
0
 ///<summary>
 /// Default implementation used to calculate collision rules due to the rulesets' collision groups.
 ///</summary>
 ///<param name="a">First ruleset in the pair.</param>
 ///<param name="b">Second ruleset in the pair.</param>
 ///<returns>Collision rule governing the interaction between the pair.</returns>
 public static CollisionRule GetGroupCollisionRuleDefault(CollisionRules a, CollisionRules b)
 {
     if (a.group == null || b.group == null)
         return CollisionRule.Defer; //This can happen occasionally when objects aren't in a space or are being handled uniquely (like in compound bodies).
     CollisionRule pairRule;
     CollisionGroupRules.TryGetValue(new CollisionGroupPair(a.group, b.group), out pairRule);
     return pairRule;
 }
예제 #11
0
        ///<summary>
        /// Default implementation used to calculate collision rules due to the rulesets' specific relationships.
        ///</summary>
        ///<param name="a">First ruleset in the pair.</param>
        ///<param name="b">Second ruleset in the pair.</param>
        ///<returns>Collision rule governing the interaction between the pair.</returns>
        public static CollisionRule GetSpecificCollisionRuleDefault(CollisionRules a, CollisionRules b)
        {
            CollisionRule aToB;
            a.specific.wrappedDictionary.TryGetValue(b, out aToB);
            CollisionRule bToA;
            b.specific.wrappedDictionary.TryGetValue(a, out bToA);
            return aToB > bToA ? aToB : bToA;

        }
예제 #12
0
        /// <summary>
        /// Determines what collision rule governs the interaction between the two objects.
        /// </summary>
        /// <param name="a">First ruleset in the pair.  This entity's space is used to determine the collision detection settings that contain special collision group interaction rules.</param>
        /// <param name="b">Second ruleset in the pair.</param>
        /// <returns>Collision rule governing the interaction between the pair.</returns>
        public static CollisionRule GetCollisionRuleDefault(CollisionRules a, CollisionRules b)
        {
            CollisionRule pairRule = GetSpecificCollisionRuleDefault(a, b);
            if (pairRule == CollisionRule.Defer)
            {
                pairRule = GetPersonalCollisionRuleDefault(a, b);
                if (pairRule == CollisionRule.Defer)
                    pairRule = GetGroupCollisionRuleDefault(a, b);
            }

            if (pairRule == CollisionRule.Defer)
                pairRule = DefaultCollisionRule;
            return pairRule;
        }
예제 #13
0
 ///<summary>
 /// Tries to remove a relationship about rulesB from ownerA's Specific list.
 ///</summary>
 ///<param name="ownerA">Owner of the collision rules that will lose an entry in its Specific relationships.</param>
 ///<param name="rulesB">Collision rules that will be removed from ownerA's Specific relationships.</param>
 public static void RemoveRule(ICollisionRulesOwner ownerA, CollisionRules rulesB)
 {
     if (!ownerA.CollisionRules.specific.Remove(rulesB))
         rulesB.specific.Remove(ownerA.CollisionRules);
 }
예제 #14
0
 ///<summary>
 /// Tries to remove a relationship about ownerB from rulesA's Specific list.
 ///</summary>
 ///<param name="rulesA">Collision rules that will lose an entry in its Specific relationships.</param>
 ///<param name="ownerB">Owner of the collision rules that will be removed from ownerA's Specific relationships.</param>
 public static void RemoveRule(CollisionRules rulesA, ICollisionRulesOwner ownerB)
 {
     if (!rulesA.specific.Remove(ownerB.CollisionRules))
         ownerB.CollisionRules.specific.Remove(rulesA);
 }
예제 #15
0
 ///<summary>
 /// Adds an entry in rulesA's Specific relationships list about ownerB.
 ///</summary>
 ///<param name="ownerA">Owner of the collision rules that will gain an entry in its Specific relationships.</param>
 ///<param name="rulesB">Collision rules that will be added to ownerA's Specific relationships.</param>
 ///<param name="rule">Rule assigned to the pair.</param>
 public static void AddRule(ICollisionRulesOwner ownerA, CollisionRules rulesB, CollisionRule rule)
 {
     ownerA.CollisionRules.specific.Add(rulesB, rule);
 }
예제 #16
0
 ///<summary>
 /// Adds an entry in rulesA's Specific relationships list about ownerB.
 ///</summary>
 ///<param name="rulesA">Collision rules that will gain an entry in its Specific relationships.</param>
 ///<param name="ownerB">Owner of the collision rules that will be added to ownerA's Specific relationships.</param>
 ///<param name="rule">Rule assigned to the pair.</param>
 public static void AddRule(CollisionRules rulesA, ICollisionRulesOwner ownerB, CollisionRule rule)
 {
     rulesA.specific.Add(ownerB.CollisionRules, rule);
 }
예제 #17
0
 /// <summary>
 /// Creates a detector volume.
 /// </summary>
 /// <param name="triangleMesh">Arbitrary closed triangle mesh representing the volume.</param>
 /// <param name="queryAccelerator">System used to find nearby objects.</param>
 public DetectorVolume(MeshBoundingBoxTreeData triangleMesh, IQueryAccelerator queryAccelerator)
 {
     TriangleMesh = new TriangleMesh(triangleMesh);
     QueryAccelerator = queryAccelerator;
     collisionRules = new CollisionRules()
     {
          group = new CollisionGroup()
     };
 }
예제 #18
0
 ///<summary>
 /// Default implementation used to calculate collision rules due to the rulesets' personal rules.
 ///</summary>
 ///<param name="a">First ruleset in the pair.</param>
 ///<param name="b">Second ruleset in the pair.</param>
 ///<returns>Collision rule governing the interaction between the pair.</returns>
 public static CollisionRule GetPersonalCollisionRuleDefault(CollisionRules a, CollisionRules b)
 {
     return(a.personal > b.personal ? a.personal : b.personal);
 }
예제 #19
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public RobotArmDemo(DemosGame game)
            : base(game)
        {
            //Since this is not a "StandardDemo" derived class, we need to set our own gravity.
            Space.ForceUpdater.Gravity = new Vector3(0, -9.81f, 0);
            Entity ground = new Box(Vector3.Zero, 30, 1, 30);
            Space.Add(ground);

            var armBase = new Cylinder(new Vector3(0, 2, 0), 2.5f, 1, 40);
            Space.Add(armBase);

            //The arm base can rotate around the Y axis.
            //Rotation is controlled by user input.
            groundToBaseJoint = new RevoluteJoint(ground, armBase, Vector3.Zero, Vector3.Up);
            groundToBaseJoint.Motor.IsActive = true;
            groundToBaseJoint.Motor.Settings.Mode = MotorMode.Servomechanism;
            groundToBaseJoint.Motor.Settings.MaximumForce = 3500;
            Space.Add(groundToBaseJoint);

            Entity lowerArm = new Box(armBase.Position + new Vector3(0, 2, 0), 1, 3, .5f, 10);
            Space.Add(lowerArm);

            shoulder = new RevoluteJoint(armBase, lowerArm, armBase.Position, Vector3.Forward);
            shoulder.Motor.IsActive = true;
            shoulder.Motor.Settings.Mode = MotorMode.Servomechanism;
            shoulder.Motor.Settings.MaximumForce = 2500;

            //Don't want it to rotate too far; this keeps the whole contraption off the ground.
            shoulder.Limit.IsActive = true;
            shoulder.Limit.MinimumAngle = -MathHelper.PiOver4;
            shoulder.Limit.MaximumAngle = MathHelper.PiOver4;
            Space.Add(shoulder);

            //Make the next piece of the arm.
            Entity upperArm = new Cylinder(lowerArm.Position + new Vector3(0, 3, 0), 3, .25f, 10);
            Space.Add(upperArm);

            //Swivel hinges allow motion around two axes.  Imagine a tablet PC's monitor hinge.
            elbow = new SwivelHingeJoint(lowerArm, upperArm, lowerArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward);
            elbow.TwistMotor.IsActive = true;
            elbow.TwistMotor.Settings.Mode = MotorMode.Servomechanism;
            elbow.TwistMotor.Settings.MaximumForce = 1000;

            elbow.HingeMotor.IsActive = true;
            elbow.HingeMotor.Settings.Mode = MotorMode.Servomechanism;
            elbow.HingeMotor.Settings.MaximumForce = 1250;

            //Keep it from rotating too much.
            elbow.HingeLimit.IsActive = true;
            elbow.HingeLimit.MinimumAngle = -MathHelper.PiOver2;
            elbow.HingeLimit.MaximumAngle = MathHelper.PiOver2;
            Space.Add(elbow);


            //Add a menacing claw at the end.
            var lowerPosition = upperArm.Position + new Vector3(-.65f, 1.6f, 0);

            CollisionRules clawPart1ARules = new CollisionRules();
            var bodies = new List<CompoundChildData>()
            {
                new CompoundChildData() { Entry = new CompoundShapeEntry(new BoxShape(1, .25f, .25f), lowerPosition, 3), CollisionRules = clawPart1ARules },
                new CompoundChildData() { Entry = new CompoundShapeEntry(new ConeShape(1, .125f), lowerPosition + new Vector3(-.375f, .4f, 0), 3), Material = new Material(2,2,0) }
            };

            var claw = new CompoundBody(bodies, 6);
            Space.Add(claw);

            clawHingeA = new RevoluteJoint(upperArm, claw, upperArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward);
            clawHingeA.Motor.IsActive = true;
            clawHingeA.Motor.Settings.Mode = MotorMode.Servomechanism;
            clawHingeA.Motor.Settings.Servo.Goal = -MathHelper.PiOver2;
            //Weaken the claw to prevent it from crushing the boxes.
            clawHingeA.Motor.Settings.Servo.SpringSettings.DampingConstant /= 100;
            clawHingeA.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 100;

            clawHingeA.Limit.IsActive = true;
            clawHingeA.Limit.MinimumAngle = -MathHelper.PiOver2;
            clawHingeA.Limit.MaximumAngle = -MathHelper.Pi / 6;
            Space.Add(clawHingeA);

            //Add one more claw to complete the contraption.
            lowerPosition = upperArm.Position + new Vector3(.65f, 1.6f, 0);

            CollisionRules clawPart1BRules = new CollisionRules();
            bodies = new List<CompoundChildData>()
            {
                new CompoundChildData() { Entry = new CompoundShapeEntry(new BoxShape(1, .25f, .25f), lowerPosition, 3), CollisionRules = clawPart1BRules },
                new CompoundChildData() { Entry = new CompoundShapeEntry(new ConeShape(1, .125f), lowerPosition + new Vector3(.375f, .4f, 0), 3), Material = new Material(2,2,0) }
            };
            claw = new CompoundBody(bodies, 6);
            Space.Add(claw);

            clawHingeB = new RevoluteJoint(upperArm, claw, upperArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward);
            clawHingeB.Motor.IsActive = true;
            clawHingeB.Motor.Settings.Mode = MotorMode.Servomechanism;
            clawHingeB.Motor.Settings.Servo.Goal = MathHelper.PiOver2;
            //Weaken the claw to prevent it from crushing the boxes.
            clawHingeB.Motor.Settings.Servo.SpringSettings.DampingConstant /= 100;
            clawHingeB.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 100;

            clawHingeB.Limit.IsActive = true;
            clawHingeB.Limit.MinimumAngle = MathHelper.Pi / 6;
            clawHingeB.Limit.MaximumAngle = MathHelper.PiOver2;
            Space.Add(clawHingeB);

            //Keep the pieces of the robot from interacting with each other.
            //The CollisionRules.AddRule method is just a convenience method that adds items to the 'specific' dictionary.
            //Sometimes, it's a little unwieldy to reference the collision rules,
            //so the convenience method just takes the owners and hides the ugly syntax.
            CollisionRules.AddRule(armBase, lowerArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(lowerArm, upperArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(clawPart1ARules, upperArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(clawPart1BRules, upperArm, CollisionRule.NoBroadPhase);
            //Here's an example without a convenience method.  Since they are both direct CollisionRules references, it's pretty clean.
            clawPart1BRules.Specific.Add(clawPart1ARules, CollisionRule.NoBroadPhase);


            //Put some boxes on the ground to try to pick up.
            for (double k = 0; k < Math.PI * 2; k += Math.PI / 6)
            {
                Space.Add(new Box(new Vector3((float)Math.Cos(k) * 5.5f, 2, (float)Math.Sin(k) * 5.5f), 1, 1, 1, 10));
            }

            game.Camera.Position = new Vector3(0, 5, 13);
        }
예제 #20
0
 ///<summary>
 /// Adds an entry in rulesA's Specific relationships list about ownerB.
 ///</summary>
 ///<param name="rulesA">Collision rules that will gain an entry in its Specific relationships.</param>
 ///<param name="ownerB">Owner of the collision rules that will be added to ownerA's Specific relationships.</param>
 ///<param name="rule">Rule assigned to the pair.</param>
 public static void AddRule(CollisionRules rulesA, ICollisionRulesOwner ownerB, CollisionRule rule)
 {
     rulesA.specific.Add(ownerB.CollisionRules, rule);
 }
예제 #21
0
 ///<summary>
 /// Adds an entry in rulesA's Specific relationships list about ownerB.
 ///</summary>
 ///<param name="ownerA">Owner of the collision rules that will gain an entry in its Specific relationships.</param>
 ///<param name="rulesB">Collision rules that will be added to ownerA's Specific relationships.</param>
 ///<param name="rule">Rule assigned to the pair.</param>
 public static void AddRule(ICollisionRulesOwner ownerA, CollisionRules rulesB, CollisionRule rule)
 {
     ownerA.CollisionRules.specific.Add(rulesB, rule);
 }