public void Initialize(b2TimeStep step, List <b2Contact> contacts, int contactCount, object allocator) { b2Contact contact; m_step.Set(step); m_allocator = allocator; int i; b2Vec2 tVec; b2Mat22 tMat; m_constraintCount = contactCount; // fill vector to hold enough constraints while (m_constraints.Count < m_constraintCount) { m_constraints.Add(new b2ContactConstraint()); } for (i = 0; i < contactCount; ++i) { contact = contacts[i]; b2Fixture fixtureA = contact.m_fixtureA; b2Fixture fixtureB = contact.m_fixtureB; b2Shape shapeA = fixtureA.m_shape; b2Shape shapeB = fixtureB.m_shape; float radiusA = shapeA.m_radius; float radiusB = shapeB.m_radius; b2Body bodyA = fixtureA.m_body; b2Body bodyB = fixtureB.m_body; b2Manifold manifold = contact.GetManifold(); float friction = b2Settings.b2MixFriction(fixtureA.GetFriction(), fixtureB.GetFriction());; float restitution = b2Settings.b2MixRestitution(fixtureA.GetRestitution(), fixtureB.GetRestitution()); //var vA:b2Vec2 = bodyA.m_linearVelocity.Copy(); float vAX = bodyA.m_linearVelocity.x; float vAY = bodyA.m_linearVelocity.y; //var vB:b2Vec2 = bodyB.m_linearVelocity.Copy(); float vBX = bodyB.m_linearVelocity.x; float vBY = bodyB.m_linearVelocity.y; float wA = bodyA.m_angularVelocity; float wB = bodyB.m_angularVelocity; b2Settings.b2Assert(manifold.m_pointCount > 0); s_worldManifold.Initialize(manifold, bodyA.m_xf, radiusA, bodyB.m_xf, radiusB); float normalX = s_worldManifold.m_normal.x; float normalY = s_worldManifold.m_normal.y; b2ContactConstraint cc = m_constraints[i]; cc.bodyA = bodyA; //p cc.bodyB = bodyB; //p cc.manifold = manifold; //p //c.normal = normal; cc.normal.x = normalX; cc.normal.y = normalY; cc.pointCount = manifold.m_pointCount; cc.friction = friction; //-----------------------------修改 2015/12/10 13:07 by kingBook------------------ float bevel = 10.0f; float planeAngle; int vx; if (!bodyA.m_allowBevelSlither || bodyA.m_uphillZeroFriction) { planeAngle = Mathf.Atan2(normalY, normalX) * 57.3f + 90.0f; vx = (int)(bodyA.m_linearVelocity.x); if (planeAngle < 0.0f) { planeAngle += 360.0f; } if ((planeAngle > bevel && planeAngle < 90.0f - bevel) || (planeAngle > 180.0f + bevel && planeAngle < 270.0f - bevel))//斜面 左上角-右下角 { if (!bodyA.m_allowBevelSlither) { if (vx >= 0.0f) { cc.friction = 1.0f; } } if (bodyA.m_uphillZeroFriction) { if (vx < 0.0f) { cc.friction = 0.0f; } } } else if ((planeAngle > 90.0f && planeAngle < 180.0f - bevel) || (planeAngle > 270.0f + bevel && planeAngle < 360.0f - bevel))//斜面 左下角-右上角 { if (!bodyA.m_allowBevelSlither) { if (vx <= 0.0f) { cc.friction = 1.0f; } } if (bodyA.m_uphillZeroFriction) { if (vx > 0.0f) { cc.friction = 0.0f; } } } } else if (!bodyB.m_allowBevelSlither || bodyB.m_uphillZeroFriction) { planeAngle = Mathf.Atan2(-normalY, -normalX) * 57.3f + 90.0f; vx = (int)(bodyB.m_linearVelocity.x); if (planeAngle < 0.0f) { planeAngle += 360.0f; } if ((planeAngle > bevel && planeAngle < 90.0f - bevel) || (planeAngle > 180.0f + bevel && planeAngle < 270.0f - bevel))//斜面 左上角-右下角 { if (!bodyB.m_allowBevelSlither) { if (vx >= 0.0f) { cc.friction = 1.0f; } } if (bodyB.m_uphillZeroFriction) { if (vx < 0.0f) { cc.friction = 0.0f; } } } else if ((planeAngle > 90.0f && planeAngle < 180.0f - bevel) || (planeAngle > 270.0f + bevel && planeAngle < 360.0f - bevel))//斜面 左下角-右上角 { if (!bodyB.m_allowBevelSlither) { if (vx <= 0.0f) { cc.friction = 1.0f; } } if (bodyB.m_uphillZeroFriction) { if (vx > 0) { cc.friction = 0.0f; } } } } if (bodyA.m_isIgnoreFrictionX || bodyB.m_isIgnoreFrictionX) { if (Mathf.Abs(normalY) > 0.9f) { cc.friction = 0.0f; } } else if (bodyA.m_isIgnoreFrictionY || bodyB.m_isIgnoreFrictionY) { if (Mathf.Abs(normalX) > 0.9f) { cc.friction = 0.0f; } } //-----------------------------修改结束------------------ cc.restitution = restitution; cc.localPlaneNormal.x = manifold.m_localPlaneNormal.x; cc.localPlaneNormal.y = manifold.m_localPlaneNormal.y; cc.localPoint.x = manifold.m_localPoint.x; cc.localPoint.y = manifold.m_localPoint.y; cc.radius = radiusA + radiusB; cc.type = manifold.m_type; for (int k = 0; k < cc.pointCount; ++k) { b2ManifoldPoint cp = manifold.m_points[k]; b2ContactConstraintPoint ccp = cc.points[k]; ccp.normalImpulse = cp.m_normalImpulse; ccp.tangentImpulse = cp.m_tangentImpulse; ccp.localPoint.SetV(cp.m_localPoint); float rAX = ccp.rA.x = s_worldManifold.m_points[k].x - bodyA.m_sweep.c.x; float rAY = ccp.rA.y = s_worldManifold.m_points[k].y - bodyA.m_sweep.c.y; float rBX = ccp.rB.x = s_worldManifold.m_points[k].x - bodyB.m_sweep.c.x; float rBY = ccp.rB.y = s_worldManifold.m_points[k].y - bodyB.m_sweep.c.y; float rnA = rAX * normalY - rAY * normalX; //b2Math.b2Cross(r1, normal); float rnB = rBX * normalY - rBY * normalX; //b2Math.b2Cross(r2, normal); rnA *= rnA; rnB *= rnB; float kNormal = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rnA + bodyB.m_invI * rnB; //b2Settings.b2Assert(kNormal > Number.MIN_VALUE); ccp.normalMass = 1.0f / kNormal; float kEqualized = bodyA.m_mass * bodyA.m_invMass + bodyB.m_mass * bodyB.m_invMass; kEqualized += bodyA.m_mass * bodyA.m_invI * rnA + bodyB.m_mass * bodyB.m_invI * rnB; //b2Assert(kEqualized > Number.MIN_VALUE); ccp.equalizedMass = 1.0f / kEqualized; //var tangent:b2Vec2 = b2Math.b2CrossVF(normal, 1.0); float tangentX = normalY; float tangentY = -normalX; //var rtA:Number = b2Math.b2Cross(rA, tangent); float rtA = rAX * tangentY - rAY * tangentX; //var rtB:Number = b2Math.b2Cross(rB, tangent); float rtB = rBX * tangentY - rBY * tangentX; rtA *= rtA; rtB *= rtB; float kTangent = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rtA + bodyB.m_invI * rtB; //b2Settings.b2Assert(kTangent > Number.MIN_VALUE); ccp.tangentMass = 1.0f / kTangent; // Setup a velocity bias for restitution. ccp.velocityBias = 0.0f; //b2Dot(c.normal, vB + b2Cross(wB, rB) - vA - b2Cross(wA, rA)); float tX = vBX + (-wB * rBY) - vAX - (-wA * rAY); float tY = vBY + (wB * rBX) - vAY - (wA * rAX); //var vRel:Number = b2Dot(cc.normal, t); float vRel = cc.normal.x * tX + cc.normal.y * tY; if (vRel < -b2Settings.b2_velocityThreshold) { ccp.velocityBias += -cc.restitution * vRel; } } // If we have two points, then prepare the block solver. if (cc.pointCount == 2) { b2ContactConstraintPoint ccp1 = cc.points[0]; b2ContactConstraintPoint ccp2 = cc.points[1]; float invMassA = bodyA.m_invMass; float invIA = bodyA.m_invI; float invMassB = bodyB.m_invMass; float invIB = bodyB.m_invI; //var rn1A:Number = b2Cross(ccp1.rA, normal); //var rn1B:Number = b2Cross(ccp1.rB, normal); //var rn2A:Number = b2Cross(ccp2.rA, normal); //var rn2B:Number = b2Cross(ccp2.rB, normal); float rn1A = ccp1.rA.x * normalY - ccp1.rA.y * normalX; float rn1B = ccp1.rB.x * normalY - ccp1.rB.y * normalX; float rn2A = ccp2.rA.x * normalY - ccp2.rA.y * normalX; float rn2B = ccp2.rB.x * normalY - ccp2.rB.y * normalX; float k11 = invMassA + invMassB + invIA * rn1A * rn1A + invIB * rn1B * rn1B; float k22 = invMassA + invMassB + invIA * rn2A * rn2A + invIB * rn2B * rn2B; float k12 = invMassA + invMassB + invIA * rn1A * rn2A + invIB * rn1B * rn2B; // Ensure a reasonable condition number. float k_maxConditionNumber = 100.0f; if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) { // K is safe to invert. cc.K.col1.Set(k11, k12); cc.K.col2.Set(k12, k22); cc.K.GetInverse(cc.normalMass); } else { // The constraints are redundant, just use one. // TODO_ERIN use deepest? cc.pointCount = 1; } } } //b2Settings.b2Assert(count == m_constraintCount); }