// 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);
}
}