/// <summary>
        /// Initialize the sample.
        /// </summary>
        protected override void Initialize()
        {
            // create a default world and matrix
            meshRotation = Matrix.Identity;

            // create the mesh array
            sampleMeshes = new Model[5];

            // set up the sample camera
            camera          = new SampleArcBallCamera(SampleArcBallCameraMode.RollConstrained);
            camera.Distance = 12;
            // orbit the camera so we're looking down the z=-1 axis,
            // at the "front" of the object
            camera.OrbitRight(MathHelper.Pi);
            // orbit up a bit for perspective
            camera.OrbitUp(.2f);

            //set up a ring of meshes
            meshWorlds = new Matrix[8];
            for (int i = 0; i < 8; i++)
            {
                float theta = MathHelper.TwoPi * ((float)i / 8f);
                meshWorlds[i] = Matrix.CreateTranslation(
                    5f * (float)Math.Sin(theta), 0, 5f * (float)Math.Cos(theta));
            }

            // set the initial material assignments to the geometry
            materialRotation = 2;


            // stretch the cube out to represent a "floor"
            // that will help visualize the light radii
            floorWorld = Matrix.CreateScale(30f, 1f, 30f) *
                         Matrix.CreateTranslation(0, -2.2f, 0);
            lightMeshWorld = Matrix.CreateScale(.2f);

            base.Initialize();
        }
        private void HandleInput(GameTime gameTime, GamePadState gpState,
                                 KeyboardState kbState)
        {
            float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

            // handle input for rotating the materials
            if (((gpState.Buttons.X == ButtonState.Pressed) &&
                 (lastGpState.Buttons.X == ButtonState.Released)) ||
                (kbState.IsKeyDown(Keys.Tab) && lastKbState.IsKeyUp(Keys.Tab)))
            {
                // switch the active mesh
                materialRotation = (materialRotation + 1) % materials.Length;
            }


            // handle input for adding lights to the scene
            if (((gpState.Buttons.RightShoulder == ButtonState.Pressed) &&
                 (lastGpState.Buttons.RightShoulder == ButtonState.Released)) ||
                (kbState.IsKeyDown(Keys.Add) && lastKbState.IsKeyUp(Keys.Add)))
            {
                numLights = ((numLights) % (maxLights)) + 1;
            }


            // handle input for removing lights from the scene
            if (((gpState.Buttons.LeftShoulder == ButtonState.Pressed) &&
                 (lastGpState.Buttons.LeftShoulder == ButtonState.Released)) ||
                (kbState.IsKeyDown(Keys.Subtract) &&
                 lastKbState.IsKeyUp(Keys.Subtract)))
            {
                numLights = (numLights - 1);
                if (numLights < 1)
                {
                    numLights = maxLights;
                }
            }

            // handle input for adding lights to the scene
            if (((gpState.DPad.Up == ButtonState.Pressed) &&
                 (lastGpState.DPad.Up == ButtonState.Released)) ||
                (kbState.IsKeyDown(Keys.P) && lastKbState.IsKeyUp(Keys.P)))
            {
                numLightsPerPass = ((numLightsPerPass) % (maxLightsPerPass)) + 1;

                lightingEffect.Parameters["numLightsPerPass"].SetValue(numLightsPerPass);
            }

            // handle input for generating new values for the lights
            if (((gpState.Buttons.Y == ButtonState.Pressed) &&
                 (lastGpState.Buttons.Y == ButtonState.Released)) ||
                (kbState.IsKeyDown(Keys.Space) && lastKbState.IsKeyUp(Keys.Space)))
            {
                GenerateRandomLights();
            }

            // handle mesh rotation inputs
            float dx =
                SampleArcBallCamera.ReadKeyboardAxis(kbState, Keys.Left, Keys.Right) +
                gpState.ThumbSticks.Left.X;
            float dy =
                SampleArcBallCamera.ReadKeyboardAxis(kbState, Keys.Down, Keys.Up) +
                gpState.ThumbSticks.Left.Y;

            // apply mesh rotation from inputs
            if (dx != 0)
            {
                meshRotation *= Matrix.CreateFromAxisAngle(camera.Up,
                                                           elapsedTime * dx);
            }
            if (dy != 0)
            {
                meshRotation *= Matrix.CreateFromAxisAngle(camera.Right,
                                                           elapsedTime * -dy);
            }

            // handle the light rotation inputs
            float lightRotation =
                SampleArcBallCamera.ReadKeyboardAxis(kbState, Keys.PageUp,
                                                     Keys.PageDown) + gpState.Triggers.Right - gpState.Triggers.Left;

            if (lightRotation != 0)
            {
                Matrix rotation = Matrix.CreateRotationY(lightRotation * elapsedTime);

                foreach (PointLight light in lights)
                {
                    // rotate all of the lights by transforming their positions
                    light.Position = Vector4.Transform(light.Position, rotation);
                }
            }
        }