/// <summary> /// Changes the camera based on the tilt of the Windows Phone. /// </summary> /// <param name="deltaTime">The elapsed time since the last call of <see cref="Update"/>.</param> private void TiltCamera(TimeSpan deltaTime) { // (Note: We use DigitalRune Mathematics instead of the XNA math types - mainly because // DigitalRune Mathematics provides a 3x3 matrix to describe rotations and the QuaternionF // provides a nice helper function to create a rotation from two given vectors. // // Please note that DigitalRune Mathematics uses column vectors whereas XNA uses row vectors. // When using Vector3F and Matrix33F we need to multiple them in this order: v' = M * v. // When using Vector3 and Matrix we need to multiple them in this order: v' = v * M.) // Get accelerometer value transformed into world space. Vector3F accelerometerVector = new Vector3F( -InputService.AccelerometerValue.Y, InputService.AccelerometerValue.Z, -InputService.AccelerometerValue.X); // Run the accelerometer signal through a low-pass filter to remove noise and jitter. Vector3F currentGravityDirection = _lowPassFilter.Filter(accelerometerVector, (float)deltaTime.TotalSeconds); Matrix33F cameraTilt; if (!currentGravityDirection.IsNumericallyZero) { // We have some valid sensor readings. // Let's compute the tilt of the camera. When the phone is lying flat on a table the camera // looks down onto the scene. When the phone is tilted we want to rotate the position of // the camera. QuaternionF contains a useful helper function that creates a rotation from // two given directions - exactly what we need here. cameraTilt = QuaternionF.CreateRotation(currentGravityDirection, new Vector3F(0, -1, 0)).ToRotationMatrix33(); } else { // Current acceleration is nearly (0, 0, 0). We cannot infer any useful direction from // this vector. Reset the camera tilt. cameraTilt = Matrix33F.Identity; } // ----- Set up the view matrix (= the position and orientation of the camera). Vector3F cameraTarget = new Vector3F(0, 2, 0); // That's were the camera is looking at. Vector3F cameraPosition = new Vector3F(0, _cameraDistance, 0); // That's the default position of the camera. Vector3F cameraUpVector = new Vector3F(0, 0, -1); // That's the up-vector of the camera. // Apply the camera tilt to the position and orientation. cameraPosition = cameraTilt * cameraPosition; cameraUpVector = cameraTilt * cameraUpVector; // Keep the camera above the ground. cameraPosition.Y = Math.Max(0.5f, cameraPosition.Y); // Create the view matrix from these points. GraphicsScreen.CameraNode.View = Matrix44F.CreateLookAt(cameraPosition, cameraTarget, cameraUpVector); // Save the camera position because it is required for hit-testing in DragBodies(). _cameraPosition = cameraPosition; }