/// <summary> /// Performs a bounce collision (a collision which modifies velocity and acceleration), and separates the objects if so. /// </summary> /// <param name="sphere">The Sphere to perform collision against.</param> /// <param name="thisMass">The mass of this instance.</param> /// <param name="otherMass">Th e mass of the argument cube.</param> /// <param name="elasticity">The ratio of velocity to preserve.</param> /// <returns>Whether a collision occurred.</returns> public bool CollideAgainstBounce(Sphere sphere, float thisMass, float otherMass, float elasticity) { #if DEBUG if (thisMass == 0 && otherMass == 0) { throw new ArgumentException("Both masses cannot be 0. For equal masses pick a non-zero value"); } #endif if (CollideAgainstMove(sphere, thisMass, otherMass)) { // Get the relative velocity of this circle to the argument circle: Vector3 relativeVelocity = new Vector3( this.TopParent.XVelocity - sphere.TopParent.XVelocity, this.TopParent.YVelocity - sphere.TopParent.YVelocity, this.TopParent.ZVelocity - sphere.TopParent.ZVelocity); #if FRB_MDX float velocityNormalDotResult = Vector3.Dot(relativeVelocity, LastMoveCollisionReposition); #else float velocityNormalDotResult; Vector3.Dot(ref relativeVelocity, ref LastMoveCollisionReposition, out velocityNormalDotResult); #endif if (velocityNormalDotResult >= 0) { return(true); } #if FRB_MDX //Vector2 tangentVector = new Vector2((float)mLastCollisionTangent.X, (float)mLastCollisionTangent.Y); // Perform the bounce if the relative velocity and the tangent are the opposite direction. Vector3 reverseNormal = -Vector3.Normalize(LastMoveCollisionReposition); float length = Vector3.Dot(relativeVelocity, reverseNormal); Vector3 velocityOnNormal = Vector3.Multiply(reverseNormal, length); #else Vector3 reverseNormal = -LastMoveCollisionReposition; reverseNormal.Normalize(); float length = Vector3.Dot(relativeVelocity, reverseNormal); Vector3 velocityOnNormal; Vector3.Multiply(ref reverseNormal, length, out velocityOnNormal); #endif sphere.TopParent.Velocity.X += (1 + elasticity) * thisMass / (thisMass + otherMass) * velocityOnNormal.X; sphere.TopParent.Velocity.Y += (1 + elasticity) * thisMass / (thisMass + otherMass) * velocityOnNormal.Y; sphere.TopParent.Velocity.Z += (1 + elasticity) * thisMass / (thisMass + otherMass) * velocityOnNormal.Z; this.TopParent.Velocity.X -= (1 + elasticity) * otherMass / (thisMass + otherMass) * velocityOnNormal.X; this.TopParent.Velocity.Y -= (1 + elasticity) * otherMass / (thisMass + otherMass) * velocityOnNormal.Y; this.TopParent.Velocity.Z -= (1 + elasticity) * otherMass / (thisMass + otherMass) * velocityOnNormal.Z; return(true); } return(false); }
/// <summary> /// Larger comes first. /// </summary> /// <param name="first">The first instance.</param> /// <param name="second">The second instance.</param> /// <returns>-1 if the first comes first, 1 if the second comes first, 0 if they're equal.</returns> #endregion public int Compare(IDrawableBatch first, IDrawableBatch second) { Vector3 firstCameraRelativePosition = new Vector3( first.X - mCamera.X, first.Y - mCamera.Y, first.Z - mCamera.Z); Vector3 secondCameraRelativePosition = new Vector3( second.X - mCamera.X, second.Y - mCamera.Y, second.Z - mCamera.Z); float firstDistance; #if FRB_MDX Vector3 forwardVector = mCamera.RotationMatrix.Forward(); Vector3Extensions.Dot(ref firstCameraRelativePosition, ref forwardVector, out firstDistance); float secondDistance; Vector3Extensions.Dot(ref secondCameraRelativePosition, ref forwardVector, out secondDistance); #else Vector3 forwardVector = mCamera.RotationMatrix.Forward; Vector3.Dot(ref firstCameraRelativePosition, ref forwardVector, out firstDistance); float secondDistance; Vector3.Dot(ref secondCameraRelativePosition, ref forwardVector, out secondDistance); #endif if (firstDistance < secondDistance) { return(1); } else if (firstDistance > secondDistance) { return(-1); } else { return(0); } }