289 lines
9.1 KiB
C#
289 lines
9.1 KiB
C#
using CommandUndoRedo;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
|
|
public class CameraOrbit : MonoBehaviour
|
|
{
|
|
public bool LightLock = false;
|
|
public Camera Cam;
|
|
bool controlOn;
|
|
float controlTime;
|
|
|
|
[Header("Light")]
|
|
public GameObject Light;
|
|
public GameObject CameraTargetHelper;
|
|
public Vector3 TargetCenter;
|
|
|
|
EventSystem eventSystem;
|
|
|
|
[Header("Free Camera")]
|
|
bool FreeCamLeft = false;
|
|
bool FreeCamRight = false;
|
|
public Vector3 lookRotation;
|
|
|
|
private CameraSettings _settings => ModelViewerMain.GetInstance().GetCameraHandler().Settings;
|
|
|
|
private CameraTransformCommand _tempCommand;
|
|
|
|
private void Start()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
public CameraOrbit Init()
|
|
{
|
|
Cam = GetComponentInChildren<Camera>();
|
|
eventSystem = EventSystem.current;
|
|
return this;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (ModelViewerMain.GetInstance() == null) return;
|
|
UpdateImmediate();
|
|
}
|
|
|
|
public void UpdateImmediate()
|
|
{
|
|
if (HandleManager.InteractionInProgress || _settings.CameraLock) return;
|
|
|
|
switch (_settings.CameraMode)
|
|
{
|
|
case 0:
|
|
OrbitAround();
|
|
OrbitLight();
|
|
break;
|
|
case 1:
|
|
OrbitAround(true);
|
|
OrbitLight();
|
|
break;
|
|
case 2: FreeCamera(); break;
|
|
}
|
|
}
|
|
|
|
#region Camera
|
|
/// <summary>
|
|
/// Orbit camera around world center
|
|
/// </summary>
|
|
void OrbitAround(bool aroundCharacter = false)
|
|
{
|
|
float x = 0;
|
|
float y = 0;
|
|
var settings = _settings;
|
|
|
|
using (var context = new KeyframeToggleContext(settings))
|
|
{
|
|
if (eventSystem.currentSelectedGameObject == null)
|
|
{
|
|
x = Input.GetAxis("Horizontal");
|
|
y = Input.GetAxis("Vertical");
|
|
}
|
|
|
|
if (aroundCharacter)
|
|
{
|
|
var selectedObject = ModelViewerMain.GetInstance().SelectedObject;
|
|
TargetCenter = selectedObject != null ? selectedObject.GetCenter() : Vector3.zero;
|
|
}
|
|
else
|
|
{
|
|
TargetCenter = Vector3.zero;
|
|
}
|
|
|
|
Cam.fieldOfView = settings.Fov;
|
|
Vector3 position = transform.position;
|
|
Vector3 rotation = Cam.transform.localEulerAngles;
|
|
|
|
if (Input.GetMouseButtonDown(0) && !eventSystem.IsPointerOverGameObject())
|
|
{
|
|
StartKeyframe();
|
|
controlOn = true;
|
|
controlTime = 0;
|
|
}
|
|
if (Input.GetMouseButton(0) && controlOn)
|
|
{
|
|
controlTime += Time.deltaTime;
|
|
position -= Input.GetAxis("Mouse X") * settings.RotSpeed * transform.right;
|
|
settings.SliderCamDist.value -= Input.mouseScrollDelta.y * settings.ZoomSpeed;
|
|
settings.SliderCamHeight.value -= Input.GetAxis("Mouse Y") * settings.RotSpeed;
|
|
}
|
|
else if (controlOn)
|
|
{
|
|
controlOn = false;
|
|
if (controlTime > 0.2f)
|
|
{
|
|
context.ForceSetKeyframe();
|
|
EndKeyframe();
|
|
}
|
|
}
|
|
|
|
if (Input.GetMouseButtonDown(2) && !eventSystem.IsPointerOverGameObject())
|
|
{
|
|
StartKeyframe();
|
|
CameraTargetHelper.SetActive(true);
|
|
controlTime = 0;
|
|
}
|
|
if (Input.GetMouseButton(2) && CameraTargetHelper.activeSelf)
|
|
{
|
|
controlTime += Time.deltaTime;
|
|
settings.SliderTargetHeight.value -= Input.GetAxis("Mouse Y");
|
|
CameraTargetHelper.transform.position = settings.SliderTargetHeight.value * Vector3.up;
|
|
}
|
|
if (CameraTargetHelper.activeSelf && Input.GetMouseButtonUp(2))
|
|
{
|
|
CameraTargetHelper.SetActive(false);
|
|
if (controlTime > 0.2f)
|
|
{
|
|
context.ForceSetKeyframe();
|
|
EndKeyframe();
|
|
}
|
|
}
|
|
|
|
float camDist = settings.CamDist;
|
|
settings.SliderCamHeight.maxValue = camDist + 1 - camDist * 0.2f;
|
|
settings.SliderCamHeight.minValue = -camDist + 1 + camDist * 0.2f;
|
|
settings.SliderCamHeight.value += y * settings.RotSpeed;
|
|
|
|
Vector3 target = TargetCenter + settings.TargetHeight * Vector3.up; //set target offsets
|
|
|
|
position.y = TargetCenter.y + settings.CamHeight; //set camera height
|
|
transform.position = position; //set final position of camera at target
|
|
transform.position += (x * transform.right) * settings.RotSpeed;
|
|
|
|
//Debug.Log(rotation);
|
|
transform.LookAt(target); //look at target position
|
|
Cam.transform.localEulerAngles = settings.CamAngle * Vector3.forward;
|
|
transform.position = target - transform.forward * camDist; //move away from target
|
|
lookRotation = transform.localEulerAngles;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Free Camera, Unity-Style
|
|
/// </summary>
|
|
void FreeCamera()
|
|
{
|
|
var settings = _settings; ;
|
|
//Debug.Log("1 " + lookRotation);
|
|
//Debug.Log("2 " + transform.localEulerAngles);
|
|
//Debug.Log("3 " + transform.eulerAngles);
|
|
Cam.fieldOfView = settings.Fov;
|
|
float moveSpeed = settings.MovSpeed;
|
|
float rotateSpeed = settings.RotSpeed;
|
|
|
|
if (Input.GetMouseButtonDown(0) && !eventSystem.IsPointerOverGameObject())
|
|
{
|
|
StartKeyframe();
|
|
lookRotation = transform.localEulerAngles;
|
|
FreeCamLeft = true;
|
|
controlTime = 0;
|
|
}
|
|
if (Input.GetMouseButton(0) && FreeCamLeft)
|
|
{
|
|
controlTime += Time.deltaTime;
|
|
transform.position += Input.GetAxis("Vertical") * transform.forward * Time.deltaTime * moveSpeed;
|
|
transform.position += Input.GetAxis("Horizontal") * transform.right * Time.deltaTime * moveSpeed;
|
|
|
|
lookRotation.x -= Input.GetAxis("Mouse Y") * rotateSpeed;
|
|
lookRotation.y += Input.GetAxis("Mouse X") * rotateSpeed;
|
|
|
|
lookRotation.x = Mathf.Clamp(lookRotation.x, -90, 90);
|
|
if (lookRotation.y >= 360) lookRotation.y -= 360;
|
|
if (lookRotation.y <= -360) lookRotation.y += 360;
|
|
//x (up down) y (left right) changes
|
|
transform.localRotation = Quaternion.Euler(lookRotation.x, lookRotation.y, lookRotation.z);
|
|
}
|
|
else if (FreeCamLeft)
|
|
{
|
|
FreeCamLeft = false;
|
|
if (controlTime > 0.2f)
|
|
{
|
|
ModelViewerMain.GetInstance().GetCameraHandler().SetKeyframe();
|
|
EndKeyframe();
|
|
}
|
|
}
|
|
|
|
if (Input.GetMouseButtonDown(1) && !eventSystem.IsPointerOverGameObject())
|
|
{
|
|
StartKeyframe();
|
|
FreeCamRight = true;
|
|
controlTime = 0;
|
|
}
|
|
if (Input.GetMouseButton(1) && FreeCamRight)
|
|
{
|
|
controlTime += Time.deltaTime;
|
|
transform.position += Input.GetAxis("Mouse X") * transform.right * Time.deltaTime * moveSpeed;
|
|
transform.position += Input.GetAxis("Mouse Y") * transform.up * Time.deltaTime * moveSpeed;
|
|
}
|
|
else if (FreeCamRight)
|
|
{
|
|
FreeCamRight = false;
|
|
if (controlTime > 0.2f)
|
|
{
|
|
ModelViewerMain.GetInstance().GetCameraHandler().SetKeyframe();
|
|
EndKeyframe();
|
|
}
|
|
}
|
|
Cam.transform.localEulerAngles = settings.CamAngle * Vector3.forward;
|
|
}
|
|
#endregion
|
|
|
|
#region Light
|
|
/// <summary>
|
|
/// Rotate Light Source
|
|
/// </summary>
|
|
private void OrbitLight()
|
|
{
|
|
if (Input.GetMouseButton(1) && !LightLock)
|
|
{
|
|
Light.transform.Rotate(Input.GetAxis("Mouse X") * Vector3.up, Space.Self);
|
|
Light.transform.Rotate(Input.GetAxis("Mouse Y") * Vector3.right, Space.Self);
|
|
}
|
|
}
|
|
|
|
public void SetLightColor(Color color)
|
|
{
|
|
Light.GetComponent<Light>().color = color;
|
|
}
|
|
|
|
public void SetLightIntensity(float value)
|
|
{
|
|
Light.GetComponent<Light>().intensity = value;
|
|
}
|
|
|
|
public void SetLightShadowIntensity(float value)
|
|
{
|
|
Light.GetComponent<Light>().shadowStrength = value;
|
|
}
|
|
|
|
public void SetLightShadows(int value)
|
|
{
|
|
Light.GetComponent<Light>().shadows = (LightShadows)value;
|
|
}
|
|
#endregion
|
|
|
|
private void StartKeyframe()
|
|
{
|
|
var cam = ModelViewerMain.GetInstance().GetCameraHandler();
|
|
if (cam == ModelViewerMain.GetInstance().WorkCameraOrbit)
|
|
{
|
|
_tempCommand = null;
|
|
return;
|
|
}
|
|
_tempCommand = new CameraTransformCommand()
|
|
{
|
|
Container = cam,
|
|
OldValues = cam.SerializeFrame() as KeyframeDataCamera,
|
|
Frame = TimelineController.Instance.CurrentFrame
|
|
};
|
|
}
|
|
|
|
private void EndKeyframe()
|
|
{
|
|
if (_tempCommand != null )
|
|
{
|
|
_tempCommand.NewValues = _tempCommand.Container.SerializeFrame() as KeyframeDataCamera;
|
|
UndoRedoManager.Insert(_tempCommand);
|
|
}
|
|
}
|
|
}
|