135 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System.Collections;
 | |
| using System.Collections.Generic;
 | |
| using UnityEngine;
 | |
| 
 | |
| public class OVRRuntimeController : MonoBehaviour
 | |
| {
 | |
| 	/// <summary>
 | |
| 	/// The controller that determines whether or not to enable rendering of the controller model.
 | |
| 	/// </summary>
 | |
| 	public OVRInput.Controller m_controller;
 | |
| 
 | |
| 	/// <summary>
 | |
| 	/// Shader that will be used for the controller model
 | |
| 	/// </summary>
 | |
| 	public Shader m_controllerModelShader;
 | |
| 
 | |
| 	private GameObject m_controllerObject;
 | |
| 
 | |
| 	private static string leftControllerModelPath = "/model_fb/controller/left";
 | |
| 	private static string rightControllerModelPath = "/model_fb/controller/right";
 | |
| 	private string m_controllerModelPath;
 | |
| 
 | |
| 	private bool m_modelSupported = false;
 | |
| 
 | |
| 	private bool m_hasInputFocus = true;
 | |
| 	private bool m_hasInputFocusPrev = false;
 | |
| 	private bool m_controllerConnectedPrev = false;
 | |
| 
 | |
| 	// Start is called before the first frame update
 | |
| 	void Start()
 | |
| 	{
 | |
| 		if (m_controller == OVRInput.Controller.LTouch)
 | |
| 			m_controllerModelPath = leftControllerModelPath;
 | |
| 		else if (m_controller == OVRInput.Controller.RTouch)
 | |
| 			m_controllerModelPath = rightControllerModelPath;
 | |
| 
 | |
| 		m_modelSupported = IsModelSupported(m_controllerModelPath);
 | |
| 
 | |
| 		if (m_modelSupported)
 | |
| 		{
 | |
| 			StartCoroutine(UpdateControllerModel());
 | |
| 		}
 | |
| 
 | |
| 		OVRManager.InputFocusAcquired += InputFocusAquired;
 | |
| 		OVRManager.InputFocusLost += InputFocusLost;
 | |
| 	}
 | |
| 
 | |
| 	// Update is called once per frame
 | |
| 	void Update()
 | |
| 	{
 | |
| 		bool controllerConnected = OVRInput.IsControllerConnected(m_controller);
 | |
| 		if (m_hasInputFocus != m_hasInputFocusPrev || controllerConnected != m_controllerConnectedPrev)
 | |
| 		{
 | |
| 			if (m_controllerObject != null)
 | |
| 			{
 | |
| 				m_controllerObject.SetActive(controllerConnected && m_hasInputFocus);
 | |
| 			}
 | |
| 			m_hasInputFocusPrev = m_hasInputFocus;
 | |
| 			m_controllerConnectedPrev = controllerConnected;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private bool IsModelSupported(string modelPath)
 | |
| 	{
 | |
| 		string[] modelPaths = OVRPlugin.GetRenderModelPaths();
 | |
| 		if (modelPaths.Length == 0)
 | |
| 		{
 | |
| 			Debug.LogError("Failed to enumerate model paths from the runtime. Check that the render model feature is enabled in OVRManager.");
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		for (int i = 0; i < modelPaths.Length; i++)
 | |
| 		{
 | |
| 			if (modelPaths[i].Equals(modelPath))
 | |
| 				return true;
 | |
| 		}
 | |
| 		Debug.LogError("Render model path not supported by this device.");
 | |
| 		return false;
 | |
| 	}
 | |
| 	private bool LoadControllerModel(string modelPath)
 | |
| 	{
 | |
| 		var modelProperties = new OVRPlugin.RenderModelProperties();
 | |
| 		if (OVRPlugin.GetRenderModelProperties(modelPath, ref modelProperties))
 | |
| 		{
 | |
| 			if (modelProperties.ModelKey != OVRPlugin.RENDER_MODEL_NULL_KEY)
 | |
| 			{
 | |
| 				byte[] modelData = OVRPlugin.LoadRenderModel(modelProperties.ModelKey);
 | |
| 
 | |
| 				if (modelData != null)
 | |
| 				{
 | |
| 					OVRGLTFLoader loader = new OVRGLTFLoader(modelData);
 | |
| 					loader.SetModelShader(m_controllerModelShader);
 | |
| 					m_controllerObject = loader.LoadGLB().root;
 | |
| 
 | |
| 					if (m_controllerObject != null)
 | |
| 					{
 | |
| 						m_controllerObject.transform.SetParent(transform, false);
 | |
| 
 | |
| 						// Apply the OpenXR grip pose offset so runtime controller models are in the right position
 | |
| 						m_controllerObject.transform.parent.localPosition = new Vector3(0.0f, -0.03f, -0.04f);
 | |
| 						m_controllerObject.transform.parent.localRotation = Quaternion.AngleAxis(-60.0f, new Vector3(1.0f, 0.0f, 0.0f));
 | |
| 						return true;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			Debug.LogError("Retrived a null model key.");
 | |
| 		}
 | |
| 		Debug.LogError("Failed to load controller model");
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	private IEnumerator UpdateControllerModel()
 | |
| 	{
 | |
| 		while (true)
 | |
| 		{
 | |
| 			bool controllerConnected = OVRInput.IsControllerConnected(m_controller);
 | |
| 			if (m_controllerObject == null && controllerConnected)
 | |
| 			{
 | |
| 				LoadControllerModel(m_controllerModelPath);
 | |
| 			}
 | |
| 			yield return new WaitForSeconds(.5f);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public void InputFocusAquired()
 | |
| 	{
 | |
| 		m_hasInputFocus = true;
 | |
| 	}
 | |
| 
 | |
| 	public void InputFocusLost()
 | |
| 	{
 | |
| 		m_hasInputFocus = false;
 | |
| 	}
 | |
| }
 |