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); } }
protected internal CollisionRule GetCollisionRule(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { if (entryA.IsActive || entryB.IsActive) { return(CollisionRules.collisionRuleCalculator(entryA, entryB)); } return(CollisionRule.NoBroadPhase); }
protected void TryToAdd(EntityCollidable collidable) { CollisionRule rule; if ((rule = CollisionRules.collisionRuleCalculator(DetectorVolume, collidable)) < 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; } if (!subPairs.ContainsKey(collidable)) { var newPair = NarrowPhaseHelper.GetPairHandler(DetectorVolume, collidable, rule) as DetectorVolumePairHandler; if (newPair != null) { newPair.Parent = this; subPairs.Add(collidable, newPair); } } containedPairs.Add(collidable); } }
void AnalyzeEntry(int i) { var entityCollidable = broadPhaseEntries[i] as EntityCollidable; if (entityCollidable != null && entityCollidable.IsActive && entityCollidable.entity.isDynamic && CollisionRules.collisionRuleCalculator(this, entityCollidable) <= CollisionRule.Normal) { bool keepGoing = false; foreach (var tri in surfaceTriangles) { //Don't need to do anything if the entity is outside of the water. if (Toolbox.IsPointInsideTriangle(ref tri[0], ref tri[1], ref tri[2], ref entityCollidable.worldTransform.Position)) { keepGoing = true; break; } } if (!keepGoing) { return; } //The entity is submerged, apply buoyancy forces. float submergedVolume; Vector3 submergedCenter; GetBuoyancyInformation(entityCollidable, out submergedVolume, out submergedCenter); if (submergedVolume > 0) { //The approximation can sometimes output a volume greater than the shape itself. Don't let that error seep into usage. float fractionSubmerged = Math.Min(1, submergedVolume / entityCollidable.entity.CollisionInformation.Shape.Volume); //Divide the volume by the density multiplier if present. float densityMultiplier; if (DensityMultipliers.TryGetValue(entityCollidable.entity, out densityMultiplier)) { submergedVolume /= densityMultiplier; } Vector3 force; Vector3.Multiply(ref upVector, -gravity * Density * dt * submergedVolume, out force); entityCollidable.entity.ApplyImpulseWithoutActivating(ref submergedCenter, ref force); //Flow if (FlowForce != 0) { float dot = Math.Max(Vector3.Dot(entityCollidable.entity.linearVelocity, flowDirection), 0); if (dot < MaxFlowSpeed) { force = Math.Min(FlowForce, (MaxFlowSpeed - dot) * entityCollidable.entity.mass) * dt * fractionSubmerged * FlowDirection; entityCollidable.entity.ApplyLinearImpulse(ref force); } } //Damping entityCollidable.entity.ModifyLinearDamping(fractionSubmerged * LinearDamping); entityCollidable.entity.ModifyAngularDamping(fractionSubmerged * AngularDamping); } } }