Esempio n. 1
0
        /// <summary>
        /// Handles a collision between the physics object and a surface described by a surface
        /// normal. The object's velocity will change such that the angle of incidence and the 
        /// angle of reflection are equal with respect to the surface normal. Note that this
        /// method does not check whether any sort of a collision actually occurred - it trusts
        /// the caller to determine that.
        /// </summary>
        /// <param name="physicsObject">The object whose velocity will change as a result of the
        /// collision.</param>
        /// <param name="surfaceNormal">The surface normal of the surface against which the object
        /// collided.</param>
        /// <param name="restitution">Coefficient of restitution. 1.0f means an elastic collision (no
        /// energy lost), so the object will bounce back as forcefully as it went in. For 0.0f, the
        /// object will effectively stop at the surface.</param>
        private void HandleCollisionWithSurface(IPhysicsObject physicsObject, Vector3 surfaceNormal,
            float restitution)
        {
            Vector3 oldVelocity = physicsObject.GetVelocity();

            // Project velocity vector onto the surface normal
            float v_dot_n = Vector3.Dot(oldVelocity, surfaceNormal);

            // Calculate the normal force
            Vector3 normalForce = -(1.0f + restitution) * v_dot_n * surfaceNormal;

            // Add the normal force to the motion vector to get the new velocity
            Vector3 newVelocity = oldVelocity + normalForce;

            physicsObject.UpdateVelocity(newVelocity);
        }
Esempio n. 2
0
        private void DoCollisionDetectionWithTerrain(IPhysicsObject physicsObject)
        {
            Vector3 position = physicsObject.GetPosition();

            if (game.terrain.heightMapInfo.IsOnHeightmap(position))
            {
                float objectBottom = physicsObject.GetBoundingBox().Min.Y;

                //Utility.BoundingBoxRenderer.Render(game, physicsObject.GetBoundingBox(), game.GraphicsDevice, game.worldCamera.ViewMatrix, game.worldCamera.ProjectionMatrix, Color.White);

                Vector3 v = physicsObject.GetVelocity();

                // In the bounding box, the bottom corners have indices 2,3,6,7. We're
                // interested in checking just the collisions of the bottom corners of
                // the object with the terrain.

                Vector3[] corners = physicsObject.GetBoundingBox().GetCorners();
                int[] bottomCorners = { 2, 3, 6, 7 };
                foreach (int i in bottomCorners)
                {
                    float terrainElevation;
                    Vector3 terrainNormal;

                    if (game.terrain.heightMapInfo.IsOnHeightmap(corners[i]))
                    {
                        game.terrain.heightMapInfo.GetHeightAndNormal(corners[i], out terrainElevation, out terrainNormal);
                        if (corners[i].Y <= terrainElevation)
                        {
                            HandleCollisionWithSurface(physicsObject, terrainNormal, 0.7f);

                            // Notify the physics object that a collision with the terrain had occurred.
                            physicsObject.HandleCollisionWithTerrain();

                            return;
                        }
                    }
                }
            }
        }