// Copyright (c) Wojciech Figat. All rights reserved. #if USE_LARGE_WORLDS using Real = System.Double; #else using Real = System.Single; #endif using System.Collections.Generic; using FlaxEditor.Gizmo; using FlaxEditor.SceneGraph; using FlaxEngine; namespace FlaxEditor.Viewport.Cameras { /// /// Base class for view controllers. /// /// [HideInEditor] public abstract class ViewportCamera : IViewportCamera { private EditorViewport _viewport; /// /// Gets the parent viewport. /// public EditorViewport Viewport { get => _viewport; internal set => _viewport = value; } /// /// Gets a value indicating whether the viewport camera uses movement speed. /// public virtual bool UseMovementSpeed => true; /// /// Focuses the viewport on the current selection of the gizmo. /// /// The gizmo collection (from viewport). /// The target view orientation. public virtual void FocusSelection(GizmosCollection gizmos, ref Quaternion orientation) { var transformGizmo = gizmos.Get(); if (transformGizmo == null || transformGizmo.SelectedParents.Count == 0) return; if (gizmos.Active != null) { var gizmoBounds = gizmos.Active.FocusBounds; if (gizmoBounds != BoundingSphere.Empty) { ShowSphere(ref gizmoBounds, ref orientation); return; } } ShowActors(transformGizmo.SelectedParents, ref orientation); } /// /// Moves the viewport to visualize the actor. /// /// The actor to preview. public virtual void ShowActor(Actor actor) { Editor.GetActorEditorSphere(actor, out BoundingSphere sphere); ShowSphere(ref sphere); } /// /// Moves the viewport to visualize selected actors. /// /// The actors to show. public void ShowActors(List selection) { var q = new Quaternion(0.424461186f, -0.0940724313f, 0.0443938486f, 0.899451137f); ShowActors(selection, ref q); } /// /// Moves the viewport to visualize selected actors. /// /// The actors to show. /// The used orientation. public virtual void ShowActors(List selection, ref Quaternion orientation) { if (selection.Count == 0) return; BoundingSphere mergesSphere = BoundingSphere.Empty; for (int i = 0; i < selection.Count; i++) { selection[i].GetEditorSphere(out var sphere); BoundingSphere.Merge(ref mergesSphere, ref sphere, out mergesSphere); } if (mergesSphere == BoundingSphere.Empty) return; ShowSphere(ref mergesSphere, ref orientation); } /// /// Moves the camera to visualize given world area defined by the sphere. /// /// The sphere. public void ShowSphere(ref BoundingSphere sphere) { var q = new Quaternion(0.424461186f, -0.0940724313f, 0.0443938486f, 0.899451137f); ShowSphere(ref sphere, ref q); } /// /// Moves the camera to visualize given world area defined by the sphere. /// /// The sphere. /// The camera orientation. public virtual void ShowSphere(ref BoundingSphere sphere, ref Quaternion orientation) { SetArcBallView(orientation, sphere.Center, sphere.Radius); } /// /// Sets view orientation and position to match the arc ball camera style view for the given target object bounds. /// /// The target object bounds. /// The margin distance scale of the orbit radius. public void SetArcBallView(BoundingBox objectBounds, float marginDistanceScale = 2.0f) { SetArcBallView(BoundingSphere.FromBox(objectBounds), marginDistanceScale); } /// /// Sets view orientation and position to match the arc ball camera style view for the given target object bounds. /// /// The target object bounds. /// The margin distance scale of the orbit radius. public void SetArcBallView(BoundingSphere objectBounds, float marginDistanceScale = 2.0f) { SetArcBallView(new Quaternion(-0.08f, -0.92f, 0.31f, -0.23f), objectBounds.Center, objectBounds.Radius * marginDistanceScale); } /// /// Sets view orientation and position to match the arc ball camera style view for the given orbit radius. /// /// The orbit radius. public void SetArcBallView(float orbitRadius) { SetArcBallView(new Quaternion(-0.08f, -0.92f, 0.31f, -0.23f), Vector3.Zero, orbitRadius); } /// /// Sets view orientation and position to match the arc ball camera style view. /// /// The view rotation. /// The orbit center location. /// The orbit radius. public virtual void SetArcBallView(Quaternion orientation, Vector3 orbitCenter, Real orbitRadius) { // Rotate Viewport.ViewOrientation = orientation; // Move camera to look at orbit center point Vector3 localPosition = Viewport.ViewDirection * (-1 * orbitRadius); Viewport.ViewPosition = orbitCenter + localPosition; } /// public virtual void Update(float deltaTime) { } /// public abstract void UpdateView(float dt, ref Vector3 moveDelta, ref Float2 mouseDelta, out bool centerMouse); } }