コード例 #1
0
ファイル: Simulation.cs プロジェクト: DireAussie/MinimalRune
    private void UpdateContacts()
    {
      CollisionDomain.Update(_fixedTimeStep);

      IslandManager.ContactSetLinks.Clear();

      // Go through contacts and add contact constraints.
      foreach (ContactSet contactSet in CollisionDomain.ContactSets)
      {
        RigidBody bodyA = contactSet.ObjectA.GeometricObject as RigidBody;
        RigidBody bodyB = contactSet.ObjectB.GeometricObject as RigidBody;
        if (bodyA != null && bodyB != null)
        {
          // Check if a dynamic body is involved and if collision response is enabled.
          bool responseEnabled = (bodyA.MotionType == MotionType.Dynamic || bodyB.MotionType == MotionType.Dynamic)
                                 && bodyA.CollisionResponseEnabled
                                 && bodyB.CollisionResponseEnabled
                                 && (ResponseFilter == null || ResponseFilter.Filter(new Pair<RigidBody>(bodyA, bodyB)));

          if (responseEnabled)
            IslandManager.ContactSetLinks.Add(new Pair<RigidBody>(bodyA, bodyB));

          int numberOfContacts = contactSet.Count;
          for (int i = 0; i < numberOfContacts; i++)
          {
            var contact = contactSet[i];
            ContactConstraint constraint = contact.UserData as ContactConstraint;

            if (constraint != null)
            {
              if (responseEnabled)
              {
                // Contact constraint is still in use. 
                // --> Mark contact constraint as active.
                constraint.Used = true;
              }
              else
              {
                // The response was disabled.
                // --> Remove an old constact constraint. 
                contact.UserData = null;
              }
            }
            else if (responseEnabled)
            {
              // Create a new contact constraint.
              constraint = ContactConstraint.Create(bodyA, bodyB, contact);
              contact.UserData = constraint;
              ContactConstraintsInternal.Add(constraint);
              constraint.Used = true;
            }
          }
        }
      }

      // ----- Recycle old contact constraints.
      int numberOfConstraints = ContactConstraintsInternal.Count;
      int numberOfUsedConstraints = numberOfConstraints;
      for (int i = numberOfConstraints - 1; i >= 0; i--)
      {
        var constraint = ContactConstraintsInternal[i];
        if (constraint.Used)
        {
          // The contact constraint is still in use.
          // Keep constraint and reset flag.
          constraint.Used = false;
        }
        else
        {
          numberOfUsedConstraints--;

          // Recycle contact constraint.
          constraint.Recycle();

          // The contact constraint is no longer in use.
          // Swap a used constraint to this index.
          ContactConstraintsInternal[i] = ContactConstraintsInternal[numberOfUsedConstraints];
          // Not needed because we call List.RemoveRange for the end of the list.
          //ContactConstraintsInternal[numberOfUsedConstraints] = constraint;
        }
      }

      // Remove recycled contacts at end of list.
      int numberOfUnusedConstraints = numberOfConstraints - numberOfUsedConstraints;
      if (numberOfUnusedConstraints > 0)
      {
        ContactConstraintsInternal.RemoveRange(numberOfUsedConstraints, numberOfUnusedConstraints);
      }
    }