// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #if USE_LARGE_WORLDS using Real = System.Double; #else using Real = System.Single; #endif using FlaxEngine; namespace FlaxEditor.Viewport.Cameras { /// /// Implementation of that orbits around the fixed location. /// /// [HideInEditor] public class ArcBallCamera : ViewportCamera { private Vector3 _orbitCenter; private Real _orbitRadius; /// /// Gets or sets the orbit center. /// public Vector3 OrbitCenter { get => _orbitCenter; set { _orbitCenter = value; UpdatePosition(); } } /// /// Gets or sets the orbit radius. /// public Real OrbitRadius { get => _orbitRadius; set { _orbitRadius = Mathf.Max(value, 0.0001f); UpdatePosition(); } } /// public override bool UseMovementSpeed => false; /// /// Initializes a new instance of the class. /// public ArcBallCamera() { } /// /// Initializes a new instance of the class. /// /// The orbit center. /// The orbit radius. public ArcBallCamera(Vector3 orbitCenter, float radius) { _orbitCenter = orbitCenter; _orbitRadius = radius; } /// /// Sets view direction. /// /// The view direction. public void SetView(Vector3 direction) { // Rotate Viewport.ViewDirection = direction; // Update view position UpdatePosition(); } /// /// Sets view orientation. /// /// The view rotation. public void SetView(Quaternion orientation) { // Rotate Viewport.ViewOrientation = orientation; // Update view position UpdatePosition(); } private void UpdatePosition() { // Move camera to look at orbit center point Vector3 localPosition = Viewport.ViewDirection * (-1 * _orbitRadius); Viewport.ViewPosition = _orbitCenter + localPosition; } /// public override void SetArcBallView(Quaternion orientation, Vector3 orbitCenter, Real orbitRadius) { base.SetArcBallView(orientation, orbitCenter, orbitRadius); _orbitCenter = orbitCenter; _orbitRadius = orbitRadius; } /// public override void UpdateView(float dt, ref Vector3 moveDelta, ref Float2 mouseDelta, out bool centerMouse) { centerMouse = true; Viewport.GetInput(out EditorViewport.Input input); // Rotate Viewport.YawPitch += mouseDelta; // Zoom if (input.IsZooming) { _orbitRadius = Mathf.Clamp(_orbitRadius - (Viewport.MouseWheelZoomSpeedFactor * input.MouseWheelDelta * 25.0f), 0.001f, 10000.0f); } // Update view position UpdatePosition(); } } }