void FixedUpdate()
        {
            DerivedBodyInformation info = null;

            if (OrientationMode == BodyOrientationMode.HMD_Only)
            {
                info = DeriveBodyInfoFromHMD();

                transform.position = Vector3.Lerp(transform.position, info.IntendedPosition, updateRate);

                transform.LookAt(transform.position + info.AssumedForward * 5, Vector3.up);
            }
            else if (OrientationMode == BodyOrientationMode.ChestIMU_Only)
            {
                info = DeriveBodyInfoFromChestIMU();
            }
            else if (OrientationMode == BodyOrientationMode.Blend)
            {
                info = DeriveBodyInfoFromBlend();

                //This back/down projects based on the headset's view position
                transform.position = Vector3.Lerp(transform.position, info.IntendedPosition, updateRate);

                DerivedBodyInformation imuInfo = DeriveBodyInfoFromChestIMU();

                //This orients the body according to the chest censor.
                transform.LookAt(transform.position + imuInfo.AssumedForward * 5, Vector3.up);

                //Next change - handle the swivel rotations.
            }
        }
        private DerivedBodyInformation DeriveBodyInfoFromBlend()
        {
            DerivedBodyInformation hmdInfo   = DeriveBodyInfoFromHMD();
            DerivedBodyInformation chestInfo = DeriveBodyInfoFromChestIMU();

            DerivedBodyInformation info = new DerivedBodyInformation();

            info.DerivationType   = BodyOrientationMode.Blend;
            info.IntendedPosition = hmdInfo.IntendedPosition;
            info.AssumedForward   = SimulatedIMU.transform.forward;

            return(info);
        }
        private DerivedBodyInformation DeriveBodyInfoFromChestIMU()
        {
            DerivedBodyInformation info = new DerivedBodyInformation();

            info.DerivationType = BodyOrientationMode.ChestIMU_Only;

            SimulatedIMU.transform.localPosition = Vector3.zero;
            //trackingBody.calibrator.GetOrientation(Imu.Chest);
            SimulatedIMU.transform.rotation = trackingBody.calibrator.GetOrientation(Imu.Chest);

            info.AssumedForward = SimulatedIMU.transform.forward;
            //SimulatedIMU.transform.localRotation = Quaternion.Lerp(trackingBody.calibrator.GetOrientation(Imu.Chest), SimulatedIMU.transform.rotation, 0.3f);

            return(info);
        }
        private DerivedBodyInformation DeriveBodyInfoFromHMD()
        {
            DerivedBodyInformation info = new DerivedBodyInformation();

            info.DerivationType = BodyOrientationMode.HMD_Only;

            Vector3 hmdNoUp = hmd.transform.forward;

            hmdNoUp.y = 0;
            Vector3 hmdUpNoY = hmd.transform.up;

            hmdUpNoY.y = 0;

            if (Vector3.Distance(hmd.transform.position, LastUpdatedPosition) > SnapUpdateDist)
            {
                ImmediateUpdate();
            }
            else
            {
                LastRelativePosition = transform.position - hmd.transform.position;
            }

            float angleFromDown = Vector3.Angle(hmd.transform.forward, Vector3.down);

            PureHMDPitch = angleFromDown;

            UpdateDebugDisplay(angleFromDown);

            //We want to use the HMD's Up to find which way we should actually look to solve the overtilting problem
            float mirrorAngleAmt = Vector3.Angle(hmd.transform.forward, Vector3.up);

            //Check if we need to do a mirror operation
            if (mirrorAngleAmt < 5 || mirrorAngleAmt > 175)
            {
                hmdNoUp = -hmdNoUp;
            }

            UpdateCounter += Time.deltaTime * updateRate;

            if (UpdateCounter >= UpdateDuration)
            {
                UpdateCounter       = 0;
                LastUpdatedPosition = hmd.transform.position;
                updateRate          = .05f;
            }

            float prog = UpdateDuration - UpdateCounter;

            LastUpdatedPosition = Vector3.Lerp(LastUpdatedPosition, hmd.transform.position, Mathf.Clamp(prog / UpdateDuration, 0, 1));

            Vector3 flatRight = hmd.transform.right;

            flatRight.y = 0;

            Vector3 rep = Vector3.Cross(flatRight, Vector3.up);

            assumedForward = rep.normalized;

            //Debug.DrawLine(hmd.transform.position + Vector3.up * 5.5f, hmd.transform.position + rep + Vector3.up * 5.5f, Color.grey, .08f);

            float dist = hmd.transform.position.y + .75f;
            //Debug.Log(dist + " away " + dist * beltHeightPercentage + "  \n" + hmd.transform.position);
            Vector3 hmdDown = Vector3.down * dist * (UseDevTranslationAmt ? devDownTranslationAmt : downTranslationAmt);

            targetPosition = assumedForward * backTranslationAmt + hmd.transform.position + hmdDown;

            //Debug.Log("Target Position: " + targetPosition + " \t\t" + hmd.transform.position + "\n" + hmdDown.ToString() + "\t\t" + hmdDown.magnitude + "\t\t");
            info.AssumedForward   = assumedForward;
            info.IntendedPosition = targetPosition;

            return(info);
        }