private void Report(ContactConstraint[] constraints) { if (_contactManager == null) { return; } for (int i = 0; i < ContactCount; ++i) { Contact c = _contacts[i]; if (c.FixtureA.AfterCollision != null) { c.FixtureA.AfterCollision(c.FixtureA, c.FixtureB, c); } if (c.FixtureB.AfterCollision != null) { c.FixtureB.AfterCollision(c.FixtureB, c.FixtureA, c); } if (_contactManager.PostSolve != null) { ContactConstraint cc = constraints[i]; _contactManager.PostSolve(c, cc); } } }
protected override void PostSolve(Contact contact, ContactConstraint impulse) { if (_broke) { // The body already broke. return; } // Should the body break? float maxImpulse = 0.0f; Manifold manifold; contact.GetManifold(out manifold); for (int i = 0; i < manifold.PointCount; ++i) { maxImpulse = Math.Max(maxImpulse, impulse.Points[i].NormalImpulse); } if (maxImpulse > 40.0f) { // Flag the body for breaking. _break = true; } }
internal CollisionData(Body localBody, ContactConstraint impulse, int pointIndex) { if (localBody == impulse.BodyA) { this.pos = PhysicsUnit.LengthToDuality * (impulse.Points[pointIndex].rA + impulse.BodyA.WorldCenter); this.normal = impulse.Normal; this.normalImpulse = PhysicsUnit.ImpulseToDuality * impulse.Points[pointIndex].NormalImpulse; this.tangentImpulse = PhysicsUnit.ImpulseToDuality * impulse.Points[pointIndex].TangentImpulse; this.normalMass = PhysicsUnit.MassToDuality * impulse.Points[pointIndex].NormalMass; this.tangentMass = PhysicsUnit.MassToDuality * impulse.Points[pointIndex].TangentMass; } else if (localBody == impulse.BodyB) { this.pos = PhysicsUnit.LengthToDuality * (impulse.Points[pointIndex].rB + impulse.BodyB.WorldCenter); this.normal = -impulse.Normal; this.normalImpulse = PhysicsUnit.ImpulseToDuality * impulse.Points[pointIndex].NormalImpulse; this.tangentImpulse = PhysicsUnit.ImpulseToDuality * impulse.Points[pointIndex].TangentImpulse; this.normalMass = PhysicsUnit.MassToDuality * impulse.Points[pointIndex].NormalMass; this.tangentMass = PhysicsUnit.MassToDuality * impulse.Points[pointIndex].TangentMass; } else { throw new ArgumentException("Local body is not part of the collision", "localBody"); } }
internal void OnPostSolve(Contact contact, ContactConstraint impulse) { if (this.PostSolve != null) { this.PostSolve(contact, impulse); } }
private void PostSolve(ContactConstraint contactConstraint) { if (!Broken) { float maxImpulse = 0.0f; for (int i = 0; i < contactConstraint.Manifold.PointCount; ++i) { maxImpulse = Math.Max(maxImpulse, contactConstraint.Manifold.Points[0].NormalImpulse); maxImpulse = Math.Max(maxImpulse, contactConstraint.Manifold.Points[1].NormalImpulse); } if (maxImpulse > Strength) { // Flag the body for breaking. _break = true; } } }
private void PostSolve(Contact contact, ContactConstraint impulse) { if (!Broken) { if (Parts.Contains(contact.FixtureA) || Parts.Contains(contact.FixtureB)) { float maxImpulse = 0.0f; int count = contact.Manifold.PointCount; for (int i = 0; i < count; ++i) { maxImpulse = Mathf.Max(maxImpulse, impulse.Points[i].NormalImpulse); } if (maxImpulse > Strength) { // Flag the body for breaking. _break = true; } } } }
public void PostSolve(Contact contact, ContactConstraint contactConstraint) { string levelUid = LevelSystem.currentLevelUid; List <int> characterEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.CharacterMovement); int entityAId = (int)contact.FixtureA.Body.UserData; int entityBId = (int)contact.FixtureB.Body.UserData; CharacterMovementComponent characterMovementComponent = null; FixedArray2 <Vector2> points; Vector2 normal; characterMovementComponent = (_entityManager.getComponent(levelUid, entityAId, ComponentType.CharacterMovement) ?? _entityManager.getComponent(levelUid, entityBId, ComponentType.CharacterMovement)) as CharacterMovementComponent; if (characterMovementComponent != null) { if (contact.FixtureA == characterMovementComponent.feetFixture || contact.FixtureB == characterMovementComponent.feetFixture) { contact.GetWorldManifold(out normal, out points); characterMovementComponent.collisionNormals.Add(normal); //if (characterMovementComponent.allowJumpResetOnCollision) // characterMovementComponent.alreadyJumped = false; } } }
private void Report(ContactConstraint[] constraints) { if (_contactManager == null) { return; } for (int i = 0; i < ContactCount; ++i) { Contact c = _contacts[i]; ContactConstraint cc = constraints[i]; ContactImpulse impulse = new ContactImpulse(); for (int j = 0; j < cc.PointCount; ++j) { impulse.NormalImpulses[j] = cc.Points[j].NormalImpulse; impulse.TangentImpulses[j] = cc.Points[j].TangentImpulse; } _contactManager.PostSolve(c, ref impulse); } }
private void Report(ContactConstraint[] constraints) { if (this._contactManager == null) { return; } for (int i = 0; i < this.ContactCount; ++i) { Contact c = this._contacts[i]; c.FixtureA.Body.OnAfterCollision(c.FixtureA, c.FixtureB, c); c.FixtureB.Body.OnAfterCollision(c.FixtureB, c.FixtureA, c); ContactConstraint cc = constraints[i]; c.FixtureA.Body.OnPostSolve(c, cc); c.FixtureB.Body.OnPostSolve(c, cc); if (this._contactManager.PostSolve != null) { this._contactManager.PostSolve(c, cc); } } }
protected virtual void PostSolve(Contact contact, ContactConstraint impulse) { }
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); } }