Exemple #1
0
 ///<summary>
 /// Forces an update of the pair's material properties.
 ///</summary>
 ///<param name="a">Material of the first member of the pair.</param>
 ///<param name="b">Material of the second member of the pair.</param>
 public override void UpdateMaterialProperties(Material a, Material b)
 {
     foreach (var pairHandler in subPairs.Values)
     {
         pairHandler.UpdateMaterialProperties(a, b);
     }
 }
 internal CompoundChild(CompoundShape shape, EntityCollidable collisionInformation, Material material, int index)
 {
     this.shape = shape;
     this.collisionInformation = collisionInformation;
     Material = material;
     this.shapeIndex = index;
 }
Exemple #3
0
 protected virtual void OnMaterialChanged(Material newMaterial)
 {
     for (int i = 0; i < pairs.Count; i++)
     {
         pairs[i].UpdateMaterialProperties();
     }
 }
        ///<summary>
        /// Computes the interaction properties between two materials.
        ///</summary>
        ///<param name="materialA">First material of the pair.</param>
        ///<param name="materialB">Second material of the pair.</param>
        ///<param name="properties">Interaction properties between two materials.</param>
        public static void GetInteractionProperties(Material materialA, Material materialB, out InteractionProperties properties)
        {
            MaterialBlender specialBlender;
            if (MaterialInteractions.TryGetValue(new MaterialPair(materialA, materialB), out specialBlender))
                specialBlender(materialA, materialB, out properties);
            else
                MaterialBlender(materialA, materialB, out properties);

        }
 /// <summary>
 /// Blender used to combine materials into a pair's interaction properties.
 /// </summary>
 /// <param name="a">Material associated with the first object to blend.</param>
 /// <param name="b">Material associated with the second object to blend.</param>
 /// <param name="properties">Blended material values.</param>
 public static void DefaultMaterialBlender(Material a, Material b, out InteractionProperties properties)
 {
     properties = new InteractionProperties
     {
         Bounciness = a.bounciness * b.bounciness,
         KineticFriction = a.kineticFriction * b.kineticFriction,
         StaticFriction = a.staticFriction * b.staticFriction
     };
 }
        ///<summary>
        /// Constructs a new static mesh.
        ///</summary>
        ///<param name="vertices">Vertex positions of the mesh.</param>
        ///<param name="indices">Index list of the mesh.</param>
        public StaticMesh(Vector3[] vertices, int[] indices)
        {
            base.Shape = new StaticMeshShape(vertices, indices);
            collisionRules.group = CollisionRules.DefaultKinematicCollisionGroup;
            events = new ContactEventManager<StaticMesh>(this);

            material = new Material();
            materialChangedDelegate = OnMaterialChanged;
            material.MaterialChanged += materialChangedDelegate;
        }
Exemple #7
0
        ///<summary>
        /// Performs common initialization.
        ///</summary>
        protected StaticCollidable()
        {
            collisionRules.group = CollisionRules.DefaultKinematicCollisionGroup;
            //Note that the Events manager is not created here.  That is left for subclasses to implement so that the type is more specific.
            //Entities can get away with having EntityCollidable specificity since you generally care more about the entity than the collidable,
            //but with static objects, the collidable is the only important object.  It would be annoying to cast to the type you know it is every time
            //just to get access to some type-specific properties.

            material = new Material();
            materialChangedDelegate = OnMaterialChanged;
            material.MaterialChanged += materialChangedDelegate;
        }
        ///<summary>
        /// Computes the interaction properties between two materials.
        ///</summary>
        ///<param name="materialA">First material of the pair.</param>
        ///<param name="materialB">Second material of the pair.</param>
        ///<param name="properties">Interaction properties between two materials.</param>
        public static void GetInteractionProperties(Material materialA, Material materialB, out InteractionProperties properties)
        {
            if (MaterialInteractions.TryGetValue(new MaterialPair(materialA, materialB), out properties))
            {
                return;
            }
            properties = new InteractionProperties();
            properties.StaticFriction = FrictionBlender(materialA.staticFriction, materialB.staticFriction, null);
            properties.KineticFriction = FrictionBlender(materialA.kineticFriction, materialB.kineticFriction, null);
            properties.Bounciness = BouncinessBlender(materialA.bounciness, materialB.bounciness, null);

        }
        ///<summary>
        /// Constructs a new InstancedMesh.
        ///</summary>
        ///<param name="meshShape">Shape to use for the instance.</param>
        ///<param name="worldTransform">Transform to use for the instance.</param>
        public InstancedMesh(InstancedMeshShape meshShape, AffineTransform worldTransform)
        {
            this.worldTransform = worldTransform;
            base.Shape = meshShape;
            collisionRules.group = CollisionRules.DefaultKinematicCollisionGroup;
            events = new ContactEventManager<InstancedMesh>(this);

            material = new Material();
            materialChangedDelegate = OnMaterialChanged;
            material.MaterialChanged += materialChangedDelegate;

        }
        ///<summary>
        /// Blends the static friction of the two materials together.
        ///</summary>
        ///<param name="materialA">First material of the pair.</param>
        ///<param name="materialB">Second material of the pair.</param>
        ///<param name="blendedCoefficient">Blended friction coefficient.</param>
        public static void GetStaticFriction(Material materialA, Material materialB, out float blendedCoefficient)
        {
            InteractionProperties properties;
            if (materialA != null && materialB != null &&
                MaterialInteractions.TryGetValue(new MaterialPair(materialA, materialB), out properties))
            {
                blendedCoefficient = properties.StaticFriction;
                return;
            }

            blendedCoefficient = FrictionBlender(materialA.staticFriction, materialB.staticFriction, null);

        }
Exemple #11
0
 /// <summary>
 /// Finds a supporting entity, the contact location, and the contact normal.
 /// </summary>
 /// <param name="location">Contact point between the wheel and the support.</param>
 /// <param name="normal">Contact normal between the wheel and the support.</param>
 /// <param name="suspensionLength">Length of the suspension at the contact.</param>
 /// <param name="supportCollidable">Collidable supporting the wheel, if any.</param>
 /// <param name="entity">Entity supporting the wheel, if any.</param>
 /// <param name="material">Material of the support.</param>
 /// <returns>Whether or not any support was found.</returns>
 protected internal abstract bool FindSupport(out Vector3 location, out Vector3 normal, out float suspensionLength, out Collidable supportCollidable, out Entity entity, out Material material);
 ///<summary>
 /// Forces an update of the pair's material properties.
 ///</summary>
 public override void UpdateMaterialProperties(Material a, Material b)
 {
     ContactConstraint.UpdateMaterialProperties(
         a ?? (EntityA == null ? null : EntityA.material),
         b ?? (EntityB == null ? null : EntityB.material));
 }
Exemple #13
0
        ///<summary>
        /// Constructs a new Terrain.
        ///</summary>
        ///<param name="shape">Shape to use for the terrain.</param>
        ///<param name="worldTransform">Transform to use for the terrain.</param>
        public Terrain(TerrainShape shape, AffineTransform worldTransform)
        {
            this.worldTransform = worldTransform;
            Shape = shape;
            collisionRules.group = CollisionRules.DefaultKinematicCollisionGroup;

            material = new Material();
            materialChangedDelegate = OnMaterialChanged;
            material.MaterialChanged += materialChangedDelegate;

            events = new ContactEventManager<Terrain>(this);
        }
        /// <summary>
        /// Finds a supporting entity, the contact location, and the contact normal.
        /// </summary>
        /// <param name="location">Contact point between the wheel and the support.</param>
        /// <param name="normal">Contact normal between the wheel and the support.</param>
        /// <param name="suspensionLength">Length of the suspension at the contact.</param>
        /// <param name="supportingCollidable">Collidable supporting the wheel, if any.</param>
        /// <param name="entity">Supporting object.</param>
        /// <param name="material">Material of the wheel.</param>
        /// <returns>Whether or not any support was found.</returns>
        protected internal override bool FindSupport(out Vector3 location, out Vector3 normal, out float suspensionLength, out Collidable supportingCollidable, out Entity entity, out Material material)
        {
            suspensionLength = float.MaxValue;
            location = Toolbox.NoVector;
            supportingCollidable = null;
            entity = null;
            normal = Toolbox.NoVector;
            material = null;

            Collidable testCollidable;
            RayHit rayHit;

            bool hit = false;

            for (int i = 0; i < detector.CollisionInformation.pairs.Count; i++)
            {
                var pair = detector.CollisionInformation.pairs[i];
                testCollidable = (pair.BroadPhaseOverlap.entryA == detector.CollisionInformation ? pair.BroadPhaseOverlap.entryB : pair.BroadPhaseOverlap.entryA) as Collidable;
                if (testCollidable != null)
                {
                    if (CollisionRules.CollisionRuleCalculator(this, testCollidable) == CollisionRule.Normal &&
                        testCollidable.RayCast(new Ray(wheel.suspension.worldAttachmentPoint, wheel.suspension.worldDirection), wheel.suspension.restLength, out rayHit) &&
                        rayHit.T < suspensionLength)
                    {
                        suspensionLength = rayHit.T;
                        EntityCollidable entityCollidable;
                        if ((entityCollidable = testCollidable as EntityCollidable) != null)
                        {
                            entity = entityCollidable.Entity;
                            material = entityCollidable.Entity.Material;
                        }
                        else
                        {
                            entity = null;
                            supportingCollidable = testCollidable;
                            var materialOwner = testCollidable as IMaterialOwner;
                            if (materialOwner != null)
                                material = materialOwner.Material;
                        }
                        location = rayHit.Location;
                        normal = rayHit.Normal;
                        hit = true;
                    }
                }
            }
            if (hit)
            {
                if (suspensionLength > 0)
                    normal.Normalize();
                else
                    Vector3.Negate(ref wheel.suspension.worldDirection, out normal);
                return true;
            }
            return false;
        }
Exemple #15
0
 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);
     }
 }
Exemple #16
0
 protected void TryToAdd(Collidable a, Collidable b, Material materialA)
 {
     TryToAdd(a, b, materialA, null);
 }
 ///<summary>
 /// Forces an update of the pair's material properties.
 ///</summary>
 public override void UpdateMaterialProperties(Material a, Material b)
 {
     ContactConstraint.UpdateMaterialProperties(
         a == null ? EntityA == null ? null : EntityA.material : a,
         b == null ? EntityB == null ? null : EntityB.material : b);
 }
        /// <summary>
        /// Finds a supporting entity, the contact location, and the contact normal.
        /// </summary>
        /// <param name="location">Contact point between the wheel and the support.</param>
        /// <param name="normal">Contact normal between the wheel and the support.</param>
        /// <param name="suspensionLength">Length of the suspension at the contact.</param>
        /// <param name="supportingCollidable">Collidable supporting the wheel, if any.</param>
        /// <param name="entity">Supporting object.</param>
        /// <param name="material">Material of the wheel.</param>
        /// <returns>Whether or not any support was found.</returns>
        protected internal override bool FindSupport(out Vector3 location, out Vector3 normal, out float suspensionLength, out Collidable supportingCollidable, out Entity entity, out Material material)
        {
            suspensionLength = float.MaxValue;
            location = Toolbox.NoVector;
            supportingCollidable = null;
            entity = null;
            normal = Toolbox.NoVector;
            material = null;

            Collidable testCollidable;
            RayHit rayHit;

            bool hit = false;

            Quaternion localSteeringTransform;
            Quaternion.CreateFromAxisAngle(ref wheel.suspension.localDirection, steeringAngle, out localSteeringTransform);
            var startingTransform = new RigidTransform
            {
                Position = wheel.suspension.worldAttachmentPoint,
                Orientation = Quaternion.Concatenate(Quaternion.Concatenate(LocalWheelOrientation, IncludeSteeringTransformInCast ? localSteeringTransform : Quaternion.Identity), wheel.vehicle.Body.orientation)
            };
            Vector3 sweep;
            Vector3.Multiply(ref wheel.suspension.worldDirection, wheel.suspension.restLength, out sweep);

            for (int i = 0; i < detector.CollisionInformation.pairs.Count; i++)
            {
                var pair = detector.CollisionInformation.pairs[i];
                testCollidable = (pair.BroadPhaseOverlap.entryA == detector.CollisionInformation ? pair.BroadPhaseOverlap.entryB : pair.BroadPhaseOverlap.entryA) as Collidable;
                if (testCollidable != null)
                {
                    if (CollisionRules.CollisionRuleCalculator(this, testCollidable) == CollisionRule.Normal &&
                        testCollidable.ConvexCast(shape, ref startingTransform, ref sweep, out rayHit) &&
                        rayHit.T * wheel.suspension.restLength < suspensionLength)
                    {
                        suspensionLength = rayHit.T * wheel.suspension.restLength;
                        EntityCollidable entityCollidable;
                        if ((entityCollidable = testCollidable as EntityCollidable) != null)
                        {
                            entity = entityCollidable.Entity;
                            material = entityCollidable.Entity.Material;
                        }
                        else
                        {
                            entity = null;
                            supportingCollidable = testCollidable;
                            var materialOwner = testCollidable as IMaterialOwner;
                            if (materialOwner != null)
                                material = materialOwner.Material;
                        }
                        location = rayHit.Location;
                        normal = rayHit.Normal;
                        hit = true;
                    }
                }
            }
            if (hit)
            {
                if (suspensionLength > 0)
                {
                    float dot;
                    Vector3.Dot(ref normal, ref wheel.suspension.worldDirection, out dot);
                    if (dot > 0)
                    {
                        //The cylinder cast produced a normal which is opposite of what we expect.
                        Vector3.Negate(ref normal, out normal);
                    }
                    normal.Normalize();
                }
                else
                    Vector3.Negate(ref wheel.suspension.worldDirection, out normal);
                return true;
            }
            return false;
        }
        protected Entity()
        {
            InitializeId();

            BufferedStates = new EntityBufferedStates(this);

            material = new Material();
            materialChangedDelegate = OnMaterialChanged;
            material.MaterialChanged += materialChangedDelegate;

            shapeChangedDelegate = OnShapeChanged;

            activityInformation = new SimulationIslandMember(this);


        }
 void OnMaterialChanged(Material newMaterial)
 {
     for (int i = 0; i < collisionInformation.pairs.Count; i++)
     {
         collisionInformation.pairs[i].UpdateMaterialProperties();
     }
 }
 ///<summary>
 /// Updates the material properties associated with the constraint.
 ///</summary>
 ///<param name="materialA">Material associated with the first entity of the pair.</param>
 ///<param name="materialB">Material associated with the second entity of the pair.</param>
 public void UpdateMaterialProperties(Material materialA, Material materialB)
 {
     if (materialA != null && materialB != null)
         MaterialManager.GetInteractionProperties(materialA, materialB, out materialInteraction);
     else if (materialA == null && materialB != null)
     {
         materialInteraction.KineticFriction = materialB.kineticFriction;
         materialInteraction.StaticFriction = materialB.staticFriction;
         materialInteraction.Bounciness = materialB.bounciness;
     }
     else if (materialA != null)
     {
         materialInteraction.KineticFriction = materialA.kineticFriction;
         materialInteraction.StaticFriction = materialA.staticFriction;
         materialInteraction.Bounciness = materialA.bounciness;
     }
     else
     {
         materialInteraction.KineticFriction = 0;
         materialInteraction.StaticFriction = 0;
         materialInteraction.Bounciness = 0;
     }
 }
 ///<summary>
 /// Forces an update of the pair's material properties.
 ///</summary>
 /// <param name="materialA">First material to use.</param>
 /// <param name="materialB">Second material to use.</param>
 public abstract void UpdateMaterialProperties(Material materialA, Material materialB);
        ///<summary>
        /// Blends the bounciness of the two materials together.
        ///</summary>
        ///<param name="materialA">First material of the pair.</param>
        ///<param name="materialB">Second material of the pair.</param>
        /// <param name="blender">Blender to use to blend the material properties.</param>
        ///<param name="blendedCoefficient">Blended bounciness coefficient.</param>
        public static void GetBounciness(Material materialA, Material materialB, PropertyBlender blender, out float blendedCoefficient)
        {
            InteractionProperties properties;
            if (materialA != null && materialB != null &&
                MaterialInteractions.TryGetValue(new MaterialPair(materialA, materialB), out properties))
            {
                blendedCoefficient = properties.Bounciness;
                return;
            }

            blendedCoefficient = blender(materialA.Bounciness, materialB.Bounciness, null);

        }