///<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); } }
protected BroadPhaseEntry() { CollisionRules = new CollisionRules(); collisionRulesUpdatedDelegate = CollisionRulesUpdated; hashCode = (int)(base.GetHashCode() * 0xd8163841); }
///<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); } }
///<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); }
///<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); }
///<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); }
///<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); }
/// <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); }
///<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; }
///<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; }
///<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; }
/// <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; }
///<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); }
///<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); }
///<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); }
///<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); }
/// <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() }; }
///<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); }
/// <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); }
///<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); }
///<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); }