예제 #1
0
 /// <summary>
 /// Sphere / Sphere Collision
 /// </summary>
 /// <param name="first"></param>
 /// <param name="second"></param>
 public void TestCollision(RigidObject first, RigidObject second)
 {
     // Simple sphere / sphere collision
     Vector3 direction = first.Position - second.Position;
     if (direction.LengthSquared() < Math.Pow(first.Scale.X + second.Scale.X, 2))
     {
         float diff = direction.Length() - first.Scale.X - second.Scale.X;
         // First, normalize the direction vector
         direction.Normalize();
         // If the spheres are overlapping, push them out a little so they just touch
         first.Position -= diff / 2 * direction;
         second.Position += diff / 2 * direction;
         // Next, find the relative velocity between the two bodies
         Vector3 relativeVelocity = first.Velocity - second.Velocity;
         // Find the velocity in the direction of contact - use dot product
         float relativeVelocityPerp = -Vector3.Dot(relativeVelocity, direction);
         // Esoteric: Finally, the impulse is determined using this relationship
         float impulse = relativeVelocityPerp  / (1 / first.Mass + 1 / second.Mass);
         // Add the impulses in the correct direction to both bodies
         first.AddForce = 2 * impulse * direction;
         second.AddForce = -2 * impulse * direction;
         collisions[secondIndex]++;
     }
 }
예제 #2
0
 private void AddSphere()
 {
     RigidObject sphere = new RigidObject();
     sphere.Model = sphereModel;
     sphere.Texture = sphereTexture;
     sphere.Position = new Vector3(
                         (float)(random.NextDouble()*20 - 10),
                         (float)(random.NextDouble()*20 - 10),
                         (float)(random.NextDouble()*20 - 10));
     sphere.Velocity = new Vector3(
                         (float)(random.NextDouble()*4 - 2),
                         (float)(random.NextDouble()*4 - 2),
                         (float)(random.NextDouble()*4 - 2));
     sphere.Mass = (float)(1 + random.NextDouble() * 4);
     sphere.Scale *= (float)(0.5 + random.NextDouble());
     sphere.BallColor = RigidObject.ColorBank[random.Next(0, 6)];
     spheres.Add(sphere);
 }
예제 #3
0
 /// <summary>
 /// Sphere / Triangle Collision
 /// </summary>
 /// <param name="first"></param>
 /// <param name="A"></param>
 /// <param name="B"></param>
 /// <param name="C"></param>
 public void TestCollision(RigidObject first, Vector3 A, Vector3 B, Vector3 C)
 {
     // First, make the sphere center our origin
     A = A - first.Position;
     B = B - first.Position;
     C = C - first.Position;
     // Find the surface normal for the triangle (using a cross product)
     Vector3 normal = Vector3.Cross(C - A, B - A);
     normal.Normalize();
     // Find how far away the sphere is from the triangle
     // We use a dot prouct to "project" Vector A on the normal
     float separation = (float)Math.Abs(Vector3.Dot(A, normal));
     // If the sphere is too far away, then quit
     if (separation > first.Scale.X)
         return;
     // Good, so now it is in range! Find the contact point on the plane of the triangle
     Vector3 P = separation * normal;
     // Esoteric: Determine if the point is actually in the triangle
     if (Vector3.Dot(Vector3.Cross(B - A, P - A), Vector3.Cross(C - A, P - A)) > 0 ||
         Vector3.Dot(Vector3.Cross(B - C, P - C), Vector3.Cross(A - C, P - C)) > 0)
         return;
     // If the sphere is actually moving away, then don't bother (dot product here
     if (Vector3.Dot(first.Velocity, normal) > 0)
         return;
     // Finally, add the impulse force to the sphere
     first.AddForce = -2 * Vector3.Dot(first.Velocity, normal) * normal * first.Mass;
 }