public override void Collide(CollisionEvent coll, PlayerPhysics physics) { var ball = coll.Ball; // make sure we process each ball/ball collision only once // (but if we are frozen, there won"t be a second collision event, so deal with it now!) if ((physics.SwapBallCollisionHandling && ball.Id >= _id || !physics.SwapBallCollisionHandling && ball.Id <= _id) && !_state.IsFrozen) { return; } // target ball to object ball delta velocity var vRel = ball.Hit.Vel.Clone().Sub(Vel); var vNormal = coll.HitNormal; var dot = vRel.Dot(vNormal); // correct displacements, mostly from low velocity, alternative to true acceleration processing if (dot >= -PhysicsConstants.LowNormVel) { // nearly receding ... make sure of conditions if (dot > PhysicsConstants.LowNormVel) { // otherwise if clearly approaching .. process the collision return; // is this velocity clearly receding (i.E must > a minimum) } //#ifdef PhysicsConstants.Embedded if (coll.HitDistance < -PhysicsConstants.Embedded) { dot = -PhysicsConstants.EmbedShot; // has ball become embedded???, give it a kick } else { return; } //#endif } // fixme script // send ball/ball collision event to script function // if (dot < -0.25f) { // only collisions with at least some small true impact velocity (no contacts) // g_pplayer->m_ptable->InvokeBallBallCollisionCallback(this, pball, -dot); // } //#ifdef PhysicsConstants.DispGain var eDist = -PhysicsConstants.DispGain * coll.HitDistance; var normalDist = vNormal.Clone().MultiplyScalar(eDist); if (eDist > 1.0e-4) { if (eDist > PhysicsConstants.DispLimit) { eDist = PhysicsConstants.DispLimit; // crossing ramps, delta noise } if (!_state.IsFrozen) { // if the hit ball is not frozen eDist *= 0.5f; } ball.State.Pos.Add(normalDist); // push along norm, back to free area // use the norm, but is not correct, but cheaply handled } eDist = -PhysicsConstants.DispGain * Coll.HitDistance; // noisy value .... needs investigation if (!_state.IsFrozen && eDist > 1.0e-4) { if (eDist > PhysicsConstants.DispLimit) { eDist = PhysicsConstants.DispLimit; // crossing ramps, delta noise } eDist *= 0.5f; _state.Pos.Sub(normalDist); // pull along norm, back to free area } //#endif var myInvMass = _state.IsFrozen ? 0.0f : InvMass; // frozen ball has infinite mass var impulse = -(1.0f + 0.8f) * dot / (myInvMass + ball.Hit.InvMass); // resitution = 0.8 if (!_state.IsFrozen) { Vel.Sub(vNormal.Clone().MultiplyScalar(impulse * myInvMass)); } ball.Hit.Vel.Add(vNormal.Clone().MultiplyScalar(impulse * ball.Hit.InvMass)); }