/**************************************************************************** * Copyright 2019 Nreal Techonology Limited. All rights reserved. * * This file is part of NRSDK. * * https://www.nreal.ai/ * *****************************************************************************/ using UnityEngine; namespace NRKernal { public class NRHandControllerProvider : ControllerProviderBase { public class NRHandControllerStateParser { /// The buttons down. private bool[] m_ButtonsDown = new bool[3]; /// The buttons up. private bool[] m_ButtonsUp = new bool[3]; /// The buttons. private bool[] m_Buttons = new bool[3]; /// The down. private bool[] m_Down = new bool[3]; /// Parser controller state. /// The state. public void ParserControllerState(ControllerState state, HandState handState) { lock (m_Buttons) { lock (m_Down) { for (int i = 0; i < m_Buttons.Length; ++i) { m_Down[i] = m_Buttons[i]; } } m_Buttons[0] = handState.pointerPoseValid && handState.isPinching; //Trigger m_Buttons[1] = false; //App m_Buttons[2] = false; //Home lock (m_ButtonsUp) { lock (m_ButtonsDown) { for (int i = 0; i < m_Buttons.Length; ++i) { m_ButtonsUp[i] = (m_Down[i] & !m_Buttons[i]); m_ButtonsDown[i] = (!m_Down[i] & m_Buttons[i]); } } } } state.buttonsState = (m_Buttons[0] ? ControllerButton.TRIGGER : 0) | (m_Buttons[1] ? ControllerButton.APP : 0) | (m_Buttons[2] ? ControllerButton.HOME : 0); state.buttonsDown = (m_ButtonsDown[0] ? ControllerButton.TRIGGER : 0) | (m_ButtonsDown[1] ? ControllerButton.APP : 0) | (m_ButtonsDown[2] ? ControllerButton.HOME : 0); state.buttonsUp = (m_ButtonsUp[0] ? ControllerButton.TRIGGER : 0) | (m_ButtonsUp[1] ? ControllerButton.APP : 0) | (m_ButtonsUp[2] ? ControllerButton.HOME : 0); } } /// The processed frame. private int m_ProcessedFrame; private NRHandControllerStateParser[] m_StateParsers = new NRHandControllerStateParser[NRInput.MAX_CONTROLLER_STATE_COUNT]; /// Constructor. /// The states. public NRHandControllerProvider(ControllerState[] states) : base(states) { for (int i = 0; i < m_StateParsers.Length; i++) { m_StateParsers[i] = new NRHandControllerStateParser(); } Inited = true; } public override int ControllerCount { get { return 2; } } public override void OnDestroy() { } public override void OnPause() { for (int i = 0; i < states.Length; i++) { states[i].Reset(); } } public override void OnResume() { } public override void Update() { if (m_ProcessedFrame == Time.frameCount) return; m_ProcessedFrame = Time.frameCount; for (int i = 0; i < states.Length; i++) { UpdateControllerState(i, GetHandState(i)); } } private NRHandControllerStateParser GetNRHandControllerStateParser(int index) { if(index < m_StateParsers.Length) { return m_StateParsers[index]; } return null; } private HandState GetHandState(int index) { return NRInput.Hands.GetHandState(index == 0 ? HandEnum.RightHand : HandEnum.LeftHand); } private void UpdateControllerState(int index, HandState handState) { states[index].controllerType = ControllerType.CONTROLLER_TYPE_HAND; states[index].availableFeature = ControllerAvailableFeature.CONTROLLER_AVAILABLE_FEATURE_ROTATION | ControllerAvailableFeature.CONTROLLER_AVAILABLE_FEATURE_POSITION; states[index].connectionState = ControllerConnectionState.CONTROLLER_CONNECTION_STATE_CONNECTED; states[index].rotation = handState.pointerPose.rotation; states[index].position = handState.pointerPose.position; states[index].gyro = Vector3.zero; states[index].accel = Vector3.zero; states[index].mag = Vector3.zero; states[index].touchPos = Vector3.zero; states[index].isTouching = false; states[index].recentered = false; states[index].isCharging = false; states[index].batteryLevel = 0; var stateParser = GetNRHandControllerStateParser(index); if (stateParser != null) { stateParser.ParserControllerState(states[index], handState); } } } }