|
|
//========= Copyright 2016-2020, HTC Corporation. All rights reserved. ===========
using HTC.UnityPlugin.Utility;using HTC.UnityPlugin.VRModuleManagement;using System;using System.Collections.Generic;using System.Linq;using System.Reflection;using UnityEngine;
namespace HTC.UnityPlugin.Vive{ // This script creates and handles SteamVR_RenderModel using viveRole property or device index
[DisallowMultipleComponent] [AddComponentMenu("VIU/Hooks/Render Model Hook", 10)] public class RenderModelHook : MonoBehaviour, IViveRoleComponent { [AttributeUsage(AttributeTargets.Class)] public class CreatorPriorityAttirbute : Attribute { public int priority { get; set; } public CreatorPriorityAttirbute(int priority = 0) { this.priority = priority; } }
public abstract class RenderModelCreator { public abstract bool shouldActive { get; } protected RenderModelHook hook { get; private set; }
public void Initialize(RenderModelHook hook) { this.hook = hook; } public abstract void UpdateRenderModel(); public abstract void CleanUpRenderModel(); }
[CreatorPriorityAttirbute(1)] public class DefaultRenderModelCreator : RenderModelCreator { private VRModuleDeviceModel m_loadedModelEnum = (VRModuleDeviceModel)(-1); protected GameObject m_model;
public override bool shouldActive { get { return true; } }
public override void UpdateRenderModel() { var index = hook.GetModelDeviceIndex();
if (!VRModule.IsValidDeviceIndex(index)) { if (m_model != null) { m_model.SetActive(false); } } else { var loadModelEnum = VRModuleDeviceModel.Unknown; if (hook.m_overrideModel != OverrideModelEnum.DontOverride) { loadModelEnum = (VRModuleDeviceModel)hook.m_overrideModel; } else { loadModelEnum = VRModule.GetCurrentDeviceState(index).deviceModel; }
if (ChangeProp.Set(ref m_loadedModelEnum, loadModelEnum)) { CleanUpRenderModel();
var prefab = Resources.Load<GameObject>("Models/VIUModel" + m_loadedModelEnum.ToString()); if (prefab != null) { m_model = Instantiate(prefab); m_model.transform.SetParent(hook.transform, false); m_model.gameObject.name = "VIUModel" + m_loadedModelEnum.ToString();
if (hook.m_overrideShader != null) { var renderer = m_model.GetComponentInChildren<Renderer>(); if (renderer != null) { renderer.material.shader = hook.m_overrideShader; } } } }
if (m_model != null) { m_model.SetActive(true); } } }
public override void CleanUpRenderModel() { if (m_model != null) { Destroy(m_model); m_model = null; } } }
public enum Mode { Disable, ViveRole, DeivceIndex, }
public enum Index { None = -1, Hmd, Device1, Device2, Device3, Device4, Device5, Device6, Device7, Device8, Device9, Device10, Device11, Device12, Device13, Device14, Device15, }
public enum OverrideModelEnum { DontOverride = VRModuleDeviceModel.Unknown, ViveController = VRModuleDeviceModel.ViveController, ViveTracker = VRModuleDeviceModel.ViveTracker, ViveBaseStation = VRModuleDeviceModel.ViveBaseStation, OculusTouchLeft = VRModuleDeviceModel.OculusTouchLeft, OculusTouchRight = VRModuleDeviceModel.OculusTouchRight, OculusSensor = VRModuleDeviceModel.OculusSensor, KnucklesLeft = VRModuleDeviceModel.KnucklesLeft, KnucklesRight = VRModuleDeviceModel.KnucklesRight, DaydreamController = VRModuleDeviceModel.DaydreamController, ViveFocusFinch = VRModuleDeviceModel.ViveFocusFinch, OculusGoController = VRModuleDeviceModel.OculusGoController, OculusGearVrController = VRModuleDeviceModel.OculusGearVrController, WMRControllerLeft = VRModuleDeviceModel.WMRControllerLeft, WMRControllerRight = VRModuleDeviceModel.WMRControllerRight, ViveCosmosControllerLeft = VRModuleDeviceModel.ViveCosmosControllerLeft, ViveCosmosControllerRight = VRModuleDeviceModel.ViveCosmosControllerRight, OculusQuestControllerLeft = VRModuleDeviceModel.OculusQuestControllerLeft, OculusQuestControllerRight = VRModuleDeviceModel.OculusQuestControllerRight, IndexHMD = VRModuleDeviceModel.IndexHMD, IndexControllerLeft = VRModuleDeviceModel.IndexControllerLeft, IndexControllerRight = VRModuleDeviceModel.IndexControllerRight, }
[SerializeField] private Mode m_mode = Mode.ViveRole; [SerializeField] private ViveRoleProperty m_viveRole = ViveRoleProperty.New(HandRole.RightHand); [SerializeField] private Transform m_origin; [SerializeField] private Index m_deviceIndex = Index.Hmd; [SerializeField] private OverrideModelEnum m_overrideModel = OverrideModelEnum.DontOverride; [SerializeField] private Shader m_overrideShader = null;
private static readonly Type[] s_creatorTypes; private RenderModelCreator[] m_creators; private int m_activeCreatorIndex = -1; private int m_defaultCreatorIndex = -1; private bool m_isQuiting;
public ViveRoleProperty viveRole { get { return m_viveRole; } }
public Transform origin { get { return m_origin; } set { m_origin = value; } }
public bool applyTracking { get; set; }
public OverrideModelEnum overrideModel { get { return m_overrideModel; } set { m_overrideModel = value; } }
public Shader overrideShader { get { return m_overrideShader; } set { m_overrideShader = value; } }
static RenderModelHook() { try { var creatorTypes = new List<Type>(); foreach (var type in Assembly.GetAssembly(typeof(RenderModelCreator)).GetTypes().Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(RenderModelCreator)))) { creatorTypes.Add(type); } s_creatorTypes = creatorTypes.OrderBy(t => { foreach (var at in t.GetCustomAttributes(typeof(CreatorPriorityAttirbute), true)) { return ((CreatorPriorityAttirbute)at).priority; } return 0; }).ToArray(); } catch (Exception e) { s_creatorTypes = new Type[0]; Debug.LogError(e); } }
#if UNITY_EDITOR
private void OnValidate() { if (isActiveAndEnabled && Application.isPlaying && VRModule.Active) { UpdateModel(); } }#endif
private void Awake() { m_creators = new RenderModelCreator[s_creatorTypes.Length]; for (int i = s_creatorTypes.Length - 1; i >= 0; --i) { m_creators[i] = (RenderModelCreator)Activator.CreateInstance(s_creatorTypes[i]); m_creators[i].Initialize(this);
if (s_creatorTypes[i] == typeof(DefaultRenderModelCreator)) { m_defaultCreatorIndex = i; } } }
protected virtual void OnEnable() { VRModule.onActiveModuleChanged += OnActiveModuleChanged; m_viveRole.onDeviceIndexChanged += OnDeviceIndexChanged; m_viveRole.onRoleChanged += UpdateModel;
UpdateModel(); }
protected virtual void OnDisable() { VRModule.onActiveModuleChanged -= OnActiveModuleChanged; m_viveRole.onDeviceIndexChanged -= OnDeviceIndexChanged; m_viveRole.onRoleChanged -= UpdateModel;
UpdateModel(); }
private void OnDeviceIndexChanged(uint deviceIndex) { UpdateModel(); }
private void OnActiveModuleChanged(VRModuleActiveEnum module) { UpdateModel(); }
private void OnApplicationQuit() { m_isQuiting = true; }
public uint GetModelDeviceIndex() { if (!enabled) { return VRModule.INVALID_DEVICE_INDEX; }
uint result; switch (m_mode) { case Mode.ViveRole: result = m_viveRole.GetDeviceIndex(); break; case Mode.DeivceIndex: result = (uint)m_deviceIndex; break; case Mode.Disable: default: return VRModule.INVALID_DEVICE_INDEX; }
return result; }
private void UpdateModel() { if (m_isQuiting) { return; }
var activeCreatorIndex = -1; if (enabled) { if (m_overrideModel == OverrideModelEnum.DontOverride) { for (int i = 0, imax = m_creators.Length; i < imax; ++i) { if (m_creators[i].shouldActive) { activeCreatorIndex = i; break; } } } else { activeCreatorIndex = m_defaultCreatorIndex; } }
if (m_activeCreatorIndex != activeCreatorIndex) { // clean up model created from previous active creator
if (m_activeCreatorIndex >= 0) { m_creators[m_activeCreatorIndex].CleanUpRenderModel(); } m_activeCreatorIndex = activeCreatorIndex; }
if (m_activeCreatorIndex >= 0) { m_creators[m_activeCreatorIndex].UpdateRenderModel(); } } }}
|