You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
379 lines
12 KiB
379 lines
12 KiB
//========= Copyright 2016-2018, HTC Corporation. All rights reserved. =========== |
|
|
|
using HTC.UnityPlugin.Utility; |
|
using HTC.UnityPlugin.VRModuleManagement; |
|
using System; |
|
using System.IO; |
|
using UnityEngine; |
|
|
|
namespace HTC.UnityPlugin.Vive |
|
{ |
|
// This script creates and handles SteamVR_ExternalCamera using viveRole property |
|
[AddComponentMenu("HTC/VIU/Hooks/External Camera Hook", 9)] |
|
[DisallowMultipleComponent] |
|
public class ExternalCameraHook : SingletonBehaviour<ExternalCameraHook>, INewPoseListener, IViveRoleComponent |
|
{ |
|
[Obsolete("Use VIUSettings.EXTERNAL_CAMERA_CONFIG_FILE_PATH_DEFAULT_VALUE instead.")] |
|
public const string AUTO_LOAD_CONFIG_PATH = "externalcamera.cfg"; |
|
|
|
[SerializeField] |
|
private ViveRoleProperty m_viveRole = ViveRoleProperty.New(HandRole.ExternalCamera); |
|
[SerializeField] |
|
private Transform m_origin; |
|
[SerializeField] |
|
private string m_configPath = string.Empty; |
|
|
|
private bool m_quadViewSwitch = false; |
|
private bool m_configInterfaceSwitch = true; |
|
private GameObject m_configUI = null; |
|
|
|
public ViveRoleProperty viveRole { get { return m_viveRole; } } |
|
|
|
public Transform origin { get { return m_origin; } set { m_origin = value; } } |
|
|
|
public bool isTrackingDevice { get { return isActiveAndEnabled && VRModule.IsValidDeviceIndex(m_viveRole.GetDeviceIndex()); } } |
|
|
|
public string configPath |
|
{ |
|
get |
|
{ |
|
return m_configPath; |
|
} |
|
set |
|
{ |
|
m_configPath = value; |
|
#if VIU_STEAMVR |
|
if (m_externalCamera != null && !string.IsNullOrEmpty(m_configPath) && File.Exists(m_configPath)) |
|
{ |
|
m_externalCamera.configPath = m_configPath; |
|
m_externalCamera.ReadConfig(); |
|
} |
|
#endif |
|
} |
|
} |
|
|
|
public bool quadViewEnabled |
|
{ |
|
get { return m_quadViewSwitch; } |
|
set |
|
{ |
|
if (IsInstance && m_quadViewSwitch != value) |
|
{ |
|
m_quadViewSwitch = value; |
|
UpdateActivity(); |
|
} |
|
} |
|
} |
|
|
|
public bool configInterfaceEnabled |
|
{ |
|
get { return m_configInterfaceSwitch; } |
|
set |
|
{ |
|
if (IsInstance && m_configInterfaceSwitch != value) |
|
{ |
|
m_configInterfaceSwitch = value; |
|
UpdateActivity(); |
|
} |
|
} |
|
} |
|
|
|
public bool isQuadViewActive |
|
{ |
|
get |
|
{ |
|
#if VIU_STEAMVR |
|
return isActiveAndEnabled && m_externalCamera != null && m_externalCamera.isActiveAndEnabled; |
|
#else |
|
return false; |
|
#endif |
|
} |
|
} |
|
|
|
public bool isConfigInterfaceActive |
|
{ |
|
get |
|
{ |
|
return isActiveAndEnabled && m_configUI != null && m_configUI.activeSelf; |
|
} |
|
} |
|
|
|
static ExternalCameraHook() |
|
{ |
|
SetDefaultInitGameObjectGetter(DefaultInitGameObject); |
|
} |
|
|
|
private static GameObject DefaultInitGameObject() |
|
{ |
|
var go = new GameObject("[ExternalCamera]"); |
|
go.transform.SetParent(VRModule.Instance.transform, false); |
|
return go; |
|
} |
|
|
|
#if UNITY_EDITOR |
|
private void Reset() |
|
{ |
|
m_configPath = VIUSettings.EXTERNAL_CAMERA_CONFIG_FILE_PATH_DEFAULT_VALUE; |
|
} |
|
|
|
private void OnValidate() |
|
{ |
|
if (Application.isPlaying && isActiveAndEnabled) |
|
{ |
|
UpdateActivity(); |
|
} |
|
} |
|
#endif |
|
|
|
#if VIU_STEAMVR |
|
private SteamVR_ExternalCamera m_externalCamera; |
|
private RigidPose m_staticExCamPose = RigidPose.identity; |
|
|
|
public SteamVR_ExternalCamera externalCamera { get { return m_externalCamera; } } |
|
|
|
[RuntimeInitializeOnLoadMethod] |
|
private static void OnLoad() |
|
{ |
|
if (VRModule.Active && VRModule.activeModule != VRModuleActiveEnum.Uninitialized) |
|
{ |
|
AutoLoadConfig(); |
|
} |
|
else |
|
{ |
|
VRModule.onActiveModuleChanged += OnActiveModuleChanged; |
|
} |
|
} |
|
|
|
private static void OnActiveModuleChanged(VRModuleActiveEnum activatedModule) |
|
{ |
|
if (activatedModule != VRModuleActiveEnum.Uninitialized) |
|
{ |
|
VRModule.onActiveModuleChanged -= OnActiveModuleChanged; |
|
AutoLoadConfig(); |
|
} |
|
} |
|
|
|
private static void AutoLoadConfig() |
|
{ |
|
if (!Active && VIUSettings.autoLoadExternalCameraConfigOnStart) |
|
{ |
|
// if ExternalCameraHook is already exist in current scene, use its property |
|
LoadConfigFromFile(VIUSettings.EXTERNAL_CAMERA_CONFIG_FILE_PATH_DEFAULT_VALUE); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Load config form file if the file exist. |
|
/// Will create an ExternalCameraHook instance into scene if config is availabile and there was no instance. |
|
/// </summary> |
|
/// <param name="">The config file path.</param> |
|
/// <returns>true if config file loaded and external camera instance is created successfully.</returns> |
|
public static bool LoadConfigFromFile(string path) |
|
{ |
|
if (!SteamVR.active || string.IsNullOrEmpty(path) || !File.Exists(path)) |
|
{ |
|
return false; |
|
} |
|
|
|
Instance.configPath = path; |
|
Instance.UpdateActivity(); |
|
return true; |
|
} |
|
|
|
private static bool m_defaultExCamResolved; |
|
private static void ResolveDefaultExCam() |
|
{ |
|
if (m_defaultExCamResolved || VRModule.activeModule != VRModuleActiveEnum.SteamVR || !SteamVR.active) |
|
{ |
|
if (Active && (VRModule.activeModule != VRModuleActiveEnum.SteamVR || !SteamVR.active)) { Instance.m_quadViewSwitch = false; } |
|
return; |
|
} |
|
m_defaultExCamResolved = true; |
|
|
|
SteamVR_Render.instance.externalCameraConfigPath = string.Empty; |
|
|
|
var oldExternalCam = SteamVR_Render.instance.externalCamera; |
|
if (oldExternalCam != null) |
|
{ |
|
if (oldExternalCam.transform.parent != null && oldExternalCam.transform.parent.GetComponent<SteamVR_ControllerManager>() != null) |
|
{ |
|
Destroy(oldExternalCam.transform.parent.gameObject); |
|
SteamVR_Render.instance.externalCamera = null; |
|
} |
|
} |
|
} |
|
|
|
private void OnEnable() |
|
{ |
|
if (IsInstance) |
|
{ |
|
m_viveRole.onDeviceIndexChanged += OnDeviceIndexChanged; |
|
OnDeviceIndexChanged(m_viveRole.GetDeviceIndex()); |
|
} |
|
} |
|
|
|
private void OnDisable() |
|
{ |
|
if (IsInstance) |
|
{ |
|
m_viveRole.onDeviceIndexChanged -= OnDeviceIndexChanged; |
|
OnDeviceIndexChanged(VRModule.INVALID_DEVICE_INDEX); |
|
} |
|
} |
|
|
|
private void OnDeviceIndexChanged(uint deviceIndex) |
|
{ |
|
if (IsInstance) |
|
{ |
|
m_quadViewSwitch = isTrackingDevice; |
|
UpdateActivity(); |
|
} |
|
} |
|
|
|
public virtual void BeforeNewPoses() { } |
|
|
|
public virtual void OnNewPoses() |
|
{ |
|
var deviceIndex = m_viveRole.GetDeviceIndex(); |
|
|
|
if (VRModule.IsValidDeviceIndex(deviceIndex)) |
|
{ |
|
m_staticExCamPose = VivePose.GetPose(deviceIndex); |
|
} |
|
|
|
if (isQuadViewActive) |
|
{ |
|
RigidPose.SetPose(transform, m_staticExCamPose, m_origin); |
|
} |
|
} |
|
|
|
public virtual void AfterNewPoses() { } |
|
|
|
private void Update() |
|
{ |
|
if (VIUSettings.enableExternalCameraSwitch && Input.GetKeyDown(VIUSettings.externalCameraSwitchKey) && (VIUSettings.externalCameraSwitchKeyModifier != KeyCode.None && Input.GetKey(VIUSettings.externalCameraSwitchKeyModifier))) |
|
{ |
|
if (!isQuadViewActive) |
|
{ |
|
m_quadViewSwitch = true; |
|
m_configInterfaceSwitch = true; |
|
} |
|
else |
|
{ |
|
if (m_configInterfaceSwitch) |
|
{ |
|
m_configInterfaceSwitch = false; |
|
} |
|
else |
|
{ |
|
m_quadViewSwitch = false; |
|
m_configInterfaceSwitch = false; |
|
} |
|
} |
|
|
|
UpdateActivity(); |
|
} |
|
} |
|
|
|
private void UpdateActivity() |
|
{ |
|
ResolveDefaultExCam(); |
|
|
|
if (!isActiveAndEnabled) |
|
{ |
|
InternalSetQuadViewActive(false); |
|
InternalSetConfigInterfaceActive(false); |
|
} |
|
else |
|
{ |
|
InternalSetQuadViewActive(m_quadViewSwitch); |
|
InternalSetConfigInterfaceActive(isQuadViewActive && m_configInterfaceSwitch); |
|
} |
|
} |
|
|
|
private void InternalSetQuadViewActive(bool value) |
|
{ |
|
if (value && m_externalCamera == null && !string.IsNullOrEmpty(m_configPath) && File.Exists(m_configPath)) |
|
{ |
|
// don't know why SteamVR_ExternalCamera must be instantiated from the prefab |
|
// when create SteamVR_ExternalCamera using AddComponent, errors came out when disabling |
|
var prefab = Resources.Load<GameObject>("SteamVR_ExternalCamera"); |
|
if (prefab == null) |
|
{ |
|
Debug.LogError("SteamVR_ExternalCamera prefab not found!"); |
|
} |
|
else |
|
{ |
|
var ctrlMgr = Instantiate(prefab); |
|
var extCam = ctrlMgr.transform.GetChild(0); |
|
extCam.gameObject.name = "SteamVR External Camera"; |
|
extCam.SetParent(transform, false); |
|
DestroyImmediate(extCam.GetComponent<SteamVR_TrackedObject>()); |
|
DestroyImmediate(ctrlMgr); |
|
|
|
m_externalCamera = extCam.GetComponent<SteamVR_ExternalCamera>(); |
|
SteamVR_Render.instance.externalCamera = m_externalCamera; |
|
m_externalCamera.configPath = m_configPath; |
|
m_externalCamera.ReadConfig(); |
|
} |
|
} |
|
|
|
if (m_externalCamera != null) |
|
{ |
|
m_externalCamera.gameObject.SetActive(value); |
|
|
|
if (value) |
|
{ |
|
VivePose.AddNewPosesListener(this); |
|
} |
|
else |
|
{ |
|
VivePose.RemoveNewPosesListener(this); |
|
} |
|
} |
|
} |
|
|
|
private void InternalSetConfigInterfaceActive(bool value) |
|
{ |
|
if (value && m_configUI == null) |
|
{ |
|
var prefab = Resources.Load<GameObject>("VIUExCamConfigInterface"); |
|
if (prefab == null) |
|
{ |
|
Debug.LogError("VIUExCamConfigInterface prefab not found!"); |
|
} |
|
else |
|
{ |
|
m_configUI = Instantiate(prefab); |
|
} |
|
} |
|
|
|
if (m_configUI != null) |
|
{ |
|
m_configUI.SetActive(value); |
|
} |
|
} |
|
|
|
public void Recenter() |
|
{ |
|
m_staticExCamPose = RigidPose.identity; |
|
} |
|
|
|
#else |
|
protected virtual void Start() |
|
{ |
|
Debug.LogWarning("SteamVR plugin not found! install it to enable ExternalCamera!"); |
|
} |
|
|
|
private void UpdateActivity() { } |
|
|
|
public virtual void BeforeNewPoses() { } |
|
|
|
public virtual void OnNewPoses() { } |
|
|
|
public virtual void AfterNewPoses() { } |
|
|
|
public void Recenter() { } |
|
#endif |
|
} |
|
} |