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