22 private AnimationCurve _flyToAltitudeProfileCurve;
35 get => this._flyToAltitudeProfileCurve;
36 set => this._flyToAltitudeProfileCurve = value;
40 private AnimationCurve _flyToProgressCurve;
48 get => this._flyToProgressCurve;
49 set => this._flyToProgressCurve = value;
53 private AnimationCurve _flyToMaximumAltitudeCurve;
65 get => this._flyToMaximumAltitudeCurve;
66 set => this._flyToMaximumAltitudeCurve = value;
71 private double _flyToDuration = 5.0;
78 get => this._flyToDuration;
79 set => this._flyToDuration = Math.Max(value, 0.0);
82 #region Deprecated Functionality
84 private double _flyToGranularityDegrees = 0.01;
96 [Obsolete(
"CesiumFlyToController no longer works using keypoints. This value has no effect.")]
99 get => this._flyToGranularityDegrees;
102 this._flyToGranularityDegrees = Math.Max(value, 0.0);
103 if (this._flyToGranularityDegrees == 0.0)
106 "FlyToGranularityDegrees must be set to a non-zero value. " +
107 "Otherwise, CesiumFlyToController will not fly to any " +
108 "specified location.");
137 private double _flightPathLength;
141 private Quaternion _sourceRotation;
142 private Quaternion _destinationRotation;
144 private double3 _destinationECEF;
145 private double3 _previousPositionECEF;
147 private double _maxHeight;
149 private double _currentFlyToTime = 0.0;
151 private bool _flyingToLocation =
false;
152 private bool _canInterruptFlight =
true;
157 if (this._georeference ==
null)
160 "CesiumFlyToController must be nested under a game object " +
161 "with a CesiumGeoreference.");
165 if (this._globeAnchor ==
null)
167 Debug.LogError(
"CesiumFlyToController expects a CesiumGlobeAnchor to be attached to itself or to a parent");
170 CesiumOriginShift originShift = this._globeAnchor.GetComponent<CesiumOriginShift>();
171 if (originShift ==
null)
173 Debug.LogError(
"CesiumFlyToController expects a CesiumOriginShift to be attached to the CesiumGlobeAnchor above it");
178 this._cameraController = this.gameObject.GetComponent<CesiumCameraController>();
183 if (this._flyingToLocation)
185 this.HandleFlightStep(Time.deltaTime);
193 CesiumGlobeAnchor anchor = this.gameObject.GetComponentInParent<CesiumGlobeAnchor>();
196 anchor = this.gameObject.AddComponent<CesiumGlobeAnchor>();
197 Debug.LogWarning(
"CesiumFlyToController missing a CesiumGlobeAnchor - adding");
200 CesiumOriginShift origin = anchor.GetComponent<CesiumOriginShift>();
203 origin = anchor.gameObject.AddComponent<CesiumOriginShift>();
204 Debug.LogWarning(
"CesiumFlyToController missing a CesiumOriginShift - adding");
219 private bool DetectMovementInput()
222 double distanceSquared = math.lengthsq(currentPositionECEF - this._previousPositionECEF);
223 const double distanceConsideredMovement = 1e-6;
224 return distanceSquared >= (distanceConsideredMovement * distanceConsideredMovement);
246 private void HandleFlightStep(
float deltaTime)
248 if (!this._flyingToLocation || this._flightPath ==
null)
253 if (this._georeference ==
null)
255 this._flyingToLocation =
false;
259 if (this._canInterruptFlight && this.DetectMovementInput())
261 this.InterruptFlight();
265 this._currentFlyToTime += deltaTime;
267 double flyPercentage = 0.0;
268 if (this._currentFlyToTime >= this._flyToDuration)
272 else if (this._flyToProgressCurve !=
null && this._flyToProgressCurve.length > 0)
275 flyPercentage = math.clamp(this._flyToProgressCurve.Evaluate((
float)(
this._currentFlyToTime /
this._flyToDuration)), 0.0, 1.0);
279 flyPercentage = this._currentFlyToTime / this._flyToDuration;
283 if (flyPercentage == 1.0 || (this._flightPathLength == 0.0 && this._sourceRotation == this._destinationRotation))
285 this.CompleteFlight();
290 double altituteOffset = 0.0;
294 altituteOffset += curveOffset;
298 double3 currentPosition = this._flightPath.
GetPosition(flyPercentage, altituteOffset);
299 this._previousPositionECEF = currentPosition;
300 this._globeAnchor.positionGlobeFixed = currentPosition;
302 Quaternion currentQuat = Quaternion.Slerp(this._sourceRotation, this._destinationRotation, (
float)flyPercentage);
303 this._globeAnchor.rotationEastUpNorth = currentQuat;
306 private void CompleteFlight()
308 this._globeAnchor.positionGlobeFixed = _destinationECEF;
309 this._globeAnchor.rotationEastUpNorth = this._destinationRotation;
311 this._flyingToLocation =
false;
312 this._currentFlyToTime = 0.0;
314 this._globeAnchor.adjustOrientationForGlobeWhenMoving =
true;
315 this._globeAnchor.detectTransformChanges =
true;
317 if (this._cameraController !=
null)
319 this._cameraController.enableMovement =
true;
320 this._cameraController.enableRotation =
true;
329 private void InterruptFlight()
331 this._flyingToLocation =
false;
334 Vector3 angles = this.transform.eulerAngles;
336 this.transform.eulerAngles = angles;
338 this._globeAnchor.adjustOrientationForGlobeWhenMoving =
true;
339 this._globeAnchor.detectTransformChanges =
true;
341 if (this._cameraController !=
null)
343 this._cameraController.enableMovement =
true;
344 this._cameraController.enableRotation =
true;
353 private void ComputeFlightPath(
355 double3 destinationECEF,
356 float yawAtDestination,
357 float pitchAtDestination)
360 pitchAtDestination = Mathf.Clamp(pitchAtDestination, -89.99f, 89.99f);
361 this._sourceRotation = this._globeAnchor.transform.rotation;
362 this._destinationRotation = Quaternion.Euler(pitchAtDestination, yawAtDestination, 0.0f);
363 this._destinationECEF = destinationECEF;
365 this._flightPath = CesiumSimplePlanarEllipsoidCurve.FromCenteredFixedCoordinates(
369 this._flightPathLength = math.length(sourceECEF - destinationECEF);
371 this._maxHeight = 0.0;
372 if (this._flyToAltitudeProfileCurve !=
null && this._flyToMaximumAltitudeCurve.length > 0)
374 this._maxHeight = 30000.0;
375 if (this._flyToMaximumAltitudeCurve !=
null && this._flyToMaximumAltitudeCurve.length > 0)
377 this._maxHeight = this._flyToMaximumAltitudeCurve.Evaluate((
float)this._flightPathLength);
381 this._previousPositionECEF = sourceECEF;
382 this._flyingToLocation =
true;
403 float yawAtDestination,
404 float pitchAtDestination,
405 bool canInterruptByMoving)
407 if (this._flyingToLocation)
412 pitchAtDestination = Mathf.Clamp(pitchAtDestination, -89.99f, 89.99f);
417 this.ComputeFlightPath(source, destination, yawAtDestination, pitchAtDestination);
420 this._flyingToLocation =
true;
421 this._canInterruptFlight = canInterruptByMoving;
422 this._globeAnchor.adjustOrientationForGlobeWhenMoving =
false;
423 this._globeAnchor.detectTransformChanges =
false;
425 if (this._cameraController !=
null)
427 this._cameraController.enableMovement = canInterruptByMoving;
428 this._cameraController.enableRotation =
false;
450 float yawAtDestination,
451 float pitchAtDestination,
452 bool canInterruptByMoving)
463 canInterruptByMoving);
485 float yawAtDestination,
486 float pitchAtDestination,
487 bool canInterruptByMoving)
489 double3 destinationECEF =
496 canInterruptByMoving);
518 float yawAtDestination,
519 float pitchAtDestination,
520 bool canInterruptByMoving)
522 double3 destinationCoordinates =
new double3()
528 double3 destinationECEF =
530 destinationCoordinates);
536 canInterruptByMoving);