Example #1
0
        public void UpdateTracking(Cockpit cockpit, fCamera camera)
        {
            fGameObject cockpitGO = cockpit.RootGameObject;

            if (!bInitialized)
            {
                currentFrame = cockpit.GetLevelViewFrame(CoordSpace.WorldCoords);
                currentFrame.ConstrainedAlignAxis(2, Vector3f.AxisZ, Vector3f.AxisY);
                bInitialized = true;
            }

            Vector3f vCamFW = camera.Forward();

            vCamFW[1] = 0; vCamFW.Normalize();      // I don't think this is strictly necessary but
                                                    // better to be safe for now...
            Vector3f vCamPos = camera.GetPosition();

            //if (tracking_debug == null)
            //    tracking_debug = UnityUtil.CreatePrimitiveGO("tracking_indicator", PrimitiveType.Sphere, MaterialUtil.CreateStandardMaterial(Color.green), false);
            //tracking_debug.transform.position = vCamPos + 15.0f * vCamFW;

            //if (tracking_avg == null) {
            //    tracking_avg = UnityUtil.CreatePrimitiveGO("tracking_indicator", PrimitiveType.Sphere, MaterialUtil.CreateStandardMaterial(Color.blue), false);
            //    tracking_avg.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
            //}
            //tracking_avg.transform.position = vCamPos + 10.0f * vSlowViewDirTrack;

            //tracking_debug.SetVisible(false);
            //tracking_avg.SetVisible(false);

            if (vSlowViewDirTrack == Vector3f.Zero)
            {
                vSlowViewDirTrack = vCamFW;
            }

            float slowTrackSpeed = 0.05f;

            vSlowViewDirTrack = VRUtil.AngleLerp(vSlowViewDirTrack, vCamFW, slowTrackSpeed);


            // head position tracking
            if (IsLocked == false)
            {
                cockpitGO.SetPosition(vCamPos);
            }
            //Vector3 vDelta = (camera.transform.position - RootGameObject.transform.position);
            //if (vDelta.magnitude > 0.2f)
            //    RootGameObject.transform.position = camera.transform.position;
            ////else if ( vDelta.magnitude > 0.05f)
            //else
            //    RootGameObject.transform.position =
            //        (1.0f - TrackingSpeed) * RootGameObject.transform.position +
            //        (TrackingSpeed) * camera.transform.position;


            float RotationSpeed                = 200.0f;
            float WarmupTrackingAngleThresh    = 55.0f;
            float ImmediateTrackingAngleThresh = 65.0f;
            float StopTrackingAngleThresh      = 5.0f;
            float TrackingWarmupDelay          = 2.0f;
            float TrackingCooldownDelay        = 0.75f;


            //Vector3 vCockpitFW = cockpitGO.transform.forward;
            Vector3f vCockpitFW = currentFrame.Z;

            float fSlowHDeviation      = VRUtil.PlaneAngle(vCockpitFW, vSlowViewDirTrack);
            float fActualViewDeviation = VRUtil.PlaneAngle(vCockpitFW, vCamFW);

            bool bDoTrack = false;

            if (eState == TrackingState.NotTracking)
            {
                //tracking_debug.GetComponent<Renderer>().material = MaterialUtil.CreateStandardMaterial(Color.green);
                if (fSlowHDeviation > WarmupTrackingAngleThresh)
                {
                    set_tracking_state(TrackingState.TrackingWarmup);
                    stateChangeStartTime = FPlatform.RealTime();
                }
            }
            else if (eState == TrackingState.TrackingWarmup)
            {
                //tracking_debug.GetComponent<Renderer>().material = MaterialUtil.CreateStandardMaterial(Color.yellow);
                if (fSlowHDeviation > ImmediateTrackingAngleThresh)
                {
                    set_tracking_state(TrackingState.Tracking);
                }
                else if (fSlowHDeviation > WarmupTrackingAngleThresh)
                {
                    if ((FPlatform.RealTime() - stateChangeStartTime) > TrackingWarmupDelay)
                    {
                        set_tracking_state(TrackingState.Tracking);
                    }
                }
                else
                {
                    set_tracking_state(TrackingState.NotTracking);
                }
            }
            else if (eState == TrackingState.Tracking)
            {
                bDoTrack = true;
                //tracking_debug.GetComponent<Renderer>().material = MaterialUtil.CreateStandardMaterial(Color.red);
                if (fActualViewDeviation < StopTrackingAngleThresh)
                {
                    set_tracking_state(TrackingState.TrackingCooldown);
                    stateChangeStartTime = FPlatform.RealTime();
                }
            }
            else if (eState == TrackingState.TrackingCooldown)
            {
                bDoTrack = true;
                //tracking_debug.GetComponent<Renderer>().material = MaterialUtil.CreateStandardMaterial(Color.gray);
                if (fActualViewDeviation < StopTrackingAngleThresh)
                {
                    if ((FPlatform.RealTime() - stateChangeStartTime) > TrackingCooldownDelay)
                    {
                        set_tracking_state(TrackingState.NotTracking);
                        bDoTrack = false;
                    }
                }
                else
                {
                    set_tracking_state(TrackingState.Tracking);
                }
            }

            if (IsLocked)
            {
                bDoTrack = false;
                set_tracking_state(TrackingState.NotTracking);
            }


            if (bDoTrack)
            {
                float dt     = (float)(FPlatform.RealTime() - animation_last_time);
                float fDelta = RotationSpeed * dt;

                Vector3f vCurrent = new Vector3f(vCockpitFW[0], 0, vCockpitFW[2]).Normalized;
                Vector3f vTarget  = new Vector3f(vSlowViewDirTrack[0], 0, vSlowViewDirTrack[2]).Normalized;
                //Vector3 vTarget = new Vector3(vCamFW[0], 0, vCamFW[2]).normalized;
                Vector3f c     = Vector3f.Cross(vCurrent, vTarget);
                float    a     = Vector3f.AngleD(vCurrent, vTarget);
                float    fSign = (c[1] < 0) ? -1.0f : 1.0f;

                float fRotAngle = Math.Min(a, fDelta) * fSign;

                currentFrame.Rotate(Quaternionf.AxisAngleD(Vector3f.AxisY, fRotAngle));
            }
            cockpitGO.SetRotation(currentFrame.Rotation);
            animation_last_time = FPlatform.RealTime();


            if (indicator == null)
            {
                indicator = new CockpitTrackingWidget();
                indicator.Create(this, cockpit);
                cockpit.AddUIElement(indicator, false);
            }
            indicator.EnableIndicator = show_indicator;
        }