public override void PreRender() { base.PreRender(); // for fixed preview orientation, we keep preview "on the right" of scan. if (FixedPreviewOrientation && previewSO != null) { fCamera cam = previewSO.GetScene().ActiveCamera; Vector3f camRightW = cam.Right(); Vector3f camRightS = previewSO.GetScene().ToSceneN(camRightW); Frame3f previewF = lastPreviewFrameS; Frame3f targetF = TargetSO.GetLocalFrame(CoordSpace.SceneCoords); Vector3f dv = previewF.Origin - targetF.Origin; dv.y = 0; float dist = dv.Length; Frame3f rightF = targetF.Translated(dist * camRightS); rightF.Rotation = previewF.Rotation; previewSO.SetLocalFrame(rightF, CoordSpace.SceneCoords); } }
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; }