Exemplo n.º 1
0
        /// <summary>
        /// Checks if two objects are equal.
        /// </summary>
        /// <param name="obj">The object to check against.</param>
        /// <returns>Returns true if they are equal, otherwise false.</returns>
        public override bool Equals(object obj)
        {
            OverlapPairContact other = (OverlapPairContact)obj;

            return(other.Entity1.Equals(Entity1) && other.Entity2.Equals(Entity2) ||
                   other.Entity1.Equals(Entity2) && other.Entity2.Equals(Entity1));
        }
        /// <summary>
        /// Integrates the whole world a timestep further in time.
        /// </summary>
        /// <param name="timestep">The timestep in seconds.
        /// It should be small as possible to keep the simulation stable.
        /// The physics simulation shouldn't run slower than 60fps.
        /// (timestep=1/60).</param>
        public void Step(FP timestep)
        {
            this.timestep = timestep;

            // yeah! nothing to do!
            if (timestep == FP.Zero)
            {
                return;
            }

            // throw exception if the timestep is smaller zero.
            if (timestep < FP.Zero)
            {
                throw new ArgumentException("The timestep can't be negative.", "timestep");
            }

            // Calculate this
            //currentAngularDampFactor = (FP)Math.Pow((double)(float)angularDamping, (double)(float)timestep);
            //currentLinearDampFactor = (FP)Math.Pow((double)(float)linearDamping, (double)(float)timestep);

#if (WINDOWS_PHONE)
            events.RaiseWorldPreStep(timestep);
            foreach (RigidBody body in rigidBodies)
            {
                body.PreStep(timestep);
            }
            UpdateContacts();

            while (removedArbiterQueue.Count > 0)
            {
                islands.ArbiterRemoved(removedArbiterQueue.Dequeue());
            }

            foreach (SoftBody body in softbodies)
            {
                body.Update(timestep);
                body.DoSelfCollision(collisionDetectionHandler);
            }

            CollisionSystem.Detect();

            while (addedArbiterQueue.Count > 0)
            {
                islands.ArbiterCreated(addedArbiterQueue.Dequeue());
            }

            CheckDeactivation();

            IntegrateForces();
            HandleArbiter(contactIterations);
            Integrate();

            foreach (RigidBody body in rigidBodies)
            {
                body.PostStep(timestep);
            }
            events.RaiseWorldPostStep(timestep);
#else
            events.RaiseWorldPreStep(timestep);

            UpdateContacts();

            for (int index = 0, length = initialCollisions.Count; index < length; index++)
            {
                OverlapPairContact op = initialCollisions[index];
                events.RaiseBodiesStayCollide(op.contact);
            }

            for (int index = 0, length = initialTriggers.Count; index < length; index++)
            {
                OverlapPairContact op = initialTriggers[index];
                events.RaiseTriggerStayCollide(op.contact);
            }

            while (removedArbiterQueue.Count > 0)
            {
                islands.ArbiterRemoved(removedArbiterQueue.Dequeue());
            }

            for (int index = 0, length = softbodies.Count; index < length; index++)
            {
                SoftBody body = softbodies[index];
                body.Update(timestep);
                body.DoSelfCollision(collisionDetectionHandler);
            }

            CollisionSystem.Detect();

            while (addedArbiterQueue.Count > 0)
            {
                islands.ArbiterCreated(addedArbiterQueue.Dequeue());
            }

            CheckDeactivation();

            IntegrateForces();

            HandleArbiter(contactIterations);

            Integrate();

            for (int index = 0, length = rigidBodies.Count; index < length; index++)
            {
                RigidBody body = rigidBodies[index];
                body.PostStep();

                for (int index2 = 0, length2 = body.constraints.Count; index2 < length2; index2++)
                {
                    body.constraints[index2].PostStep();
                }
            }

            events.RaiseWorldPostStep(timestep);
#endif
        }
        private void CollisionDetected(RigidBody body1, RigidBody body2, FPVector point1, FPVector point2, FPVector normal, FP penetration)
        {
            bool anyBodyColliderOnly = body1.IsColliderOnly || body2.IsColliderOnly;

            Arbiter    arbiter            = null;
            ArbiterMap selectedArbiterMap = null;

            if (anyBodyColliderOnly)
            {
                selectedArbiterMap = arbiterTriggerMap;
            }
            else
            {
                selectedArbiterMap = arbiterMap;
            }

            bool arbiterCreated = false;

            lock (selectedArbiterMap) {
                selectedArbiterMap.LookUpArbiter(body1, body2, out arbiter);
                if (arbiter == null)
                {
                    arbiter       = Arbiter.Pool.GetNew();
                    arbiter.body1 = body1; arbiter.body2 = body2;
                    selectedArbiterMap.Add(new ArbiterKey(body1, body2), arbiter);

                    arbiterCreated = true;
                }
            }

            Contact contact = null;

            if (arbiter.body1 == body1)
            {
                FPVector.Negate(ref normal, out normal);
                contact = arbiter.AddContact(point1, point2, normal, penetration, contactSettings);
            }
            else
            {
                contact = arbiter.AddContact(point2, point1, normal, penetration, contactSettings);
            }

            if (arbiterCreated)
            {
                if (anyBodyColliderOnly)
                {
                    /*if (body1.isColliderOnly) {
                     *  events.RaiseTriggerBeginCollide(body1, body2);
                     * } else {
                     *  events.RaiseTriggerBeginCollide(body2, body1);
                     * }*/

                    events.RaiseTriggerBeginCollide(contact);

                    body1.arbitersTrigger.Add(arbiter);
                    body2.arbitersTrigger.Add(arbiter);

                    OverlapPairContact overlapContact = new OverlapPairContact(body1, body2);
                    overlapContact.contact = contact;

                    initialTriggers.Add(overlapContact);
                }
                else
                {
                    events.RaiseBodiesBeginCollide(contact);
                    addedArbiterQueue.Enqueue(arbiter);

                    OverlapPairContact overlapContact = new OverlapPairContact(body1, body2);
                    overlapContact.contact = contact;

                    initialCollisions.Add(overlapContact);
                }
            }

            if (!anyBodyColliderOnly && contact != null)
            {
                events.RaiseContactCreated(contact);
            }
        }