/**************************************************************************** * Copyright 2019 Nreal Techonology Limited. All rights reserved. * * This file is part of NRSDK. * * https://www.nreal.ai/ * *****************************************************************************/ namespace NRKernal { using System; using System.Runtime.InteropServices; using UnityEngine; /// A controller for handling natives. internal partial class NativeController { /// Handle of the controller. private UInt64 m_ControllerHandle = 0; /// The state handles. private UInt64[] m_StateHandles = new UInt64[NRInput.MAX_CONTROLLER_STATE_COUNT] { 0, 0 }; /// Initializes this object. /// True if it succeeds, false if it fails. public bool Init() { NRDebugger.Debug("[NativeController] Init"); NativeResult result = NativeApi.NRControllerCreate(ref m_ControllerHandle); if (result == NativeResult.Success) { //manually start controller NativeApi.NRControllerStart(m_ControllerHandle); int count = GetControllerCount(); NRDebugger.Debug("[NativeController] Get controller count:" + count); for (int i = 0; i < count; i++) { result = NativeApi.NRControllerStateCreate(m_ControllerHandle, i, ref m_StateHandles[i]); if (result != NativeResult.Success) { NRDebugger.Error("[NativeController] Create Failed!" + result.ToString()); return false; } } NRDebugger.Debug("[NativeController] Created Successed"); return true; } NRDebugger.Error("[NativeController] Create Failed!"); m_ControllerHandle = 0; return false; } //public void TestApi(int index) //{ //string msg = "GetControllerCount:" + GetControllerCount() + "\n" //+"GetAvailableFeatures:" + GetAvailableFeatures(index) + "\n" //+ "GetControllerType:" + GetControllerType(index) + "\n" //+ "GetConnectionState:" + GetConnectionState(index) + "\n" //+ "GetBatteryLevel:" + GetBatteryLevel(index) + "\n" //+ "IsCharging:" + IsCharging(index) + "\n" //+ "GetPose:" + GetPose(index).ToString("F3") + "\n" //+ "GetGyro:" + GetGyro(index).ToString("F3") + "\n" //+ "GetAccel:" + GetAccel(index).ToString("F3") + "\n" //+ "GetMag:" + GetMag(index).ToString("F3") + "\n" //+ "GetButtonState:" + GetButtonState(index) + "\n" //+ "GetButtonUp:" + GetButtonUp(index) + "\n" //+ "GetButtonDown:" + GetButtonDown(index) + "\n" //+ "IsTouching:" + IsTouching(index) + "\n" //+ "GetTouchUp:" + GetTouchUp(index) + "\n" //+ "GetTouchDown:" + GetTouchDown(index) + "\n" //+ "GetTouch:" + GetTouch(index).ToString("F3") + "\n"; //NRDebugger.Info(msg); //} /// Gets controller count. /// The controller count. public int GetControllerCount() { if (m_ControllerHandle == 0) { return 0; } int count = 0; if (NativeApi.NRControllerGetCount(m_ControllerHandle, ref count) != NativeResult.Success) NRDebugger.Error("Get Controller Count Failed!"); return Mathf.Min(count, m_StateHandles.Length); } /// Pauses this object. public void Pause() { if (m_ControllerHandle == 0) { return; } NativeApi.NRControllerPause(m_ControllerHandle); } /// Resumes this object. public void Resume() { if (m_ControllerHandle == 0) { return; } NativeApi.NRControllerResume(m_ControllerHandle); } /// Stops this object. public void Stop() { if (m_ControllerHandle == 0) { return; } NativeApi.NRControllerStop(m_ControllerHandle); } /// Destroys this object. public void Destroy() { if (m_ControllerHandle == 0) { return; } Stop(); NativeApi.NRControllerDestroy(m_ControllerHandle); } /// Gets available features. /// Zero-based index of the controller. /// The available features. public uint GetAvailableFeatures(int controllerIndex) { if (m_ControllerHandle == 0) { return 0; } uint availableFeature = 0; NativeApi.NRControllerGetAvailableFeatures(m_ControllerHandle, controllerIndex, ref availableFeature); return availableFeature; } /// Gets controller type. /// Zero-based index of the controller. /// The controller type. public ControllerType GetControllerType(int controllerIndex) { if (m_ControllerHandle == 0) { return ControllerType.CONTROLLER_TYPE_UNKNOWN; } ControllerType controllerType = ControllerType.CONTROLLER_TYPE_UNKNOWN; NativeApi.NRControllerGetType(m_ControllerHandle, controllerIndex, ref controllerType); return controllerType; } /// Recenter controller. /// Zero-based index of the controller. public void RecenterController(int controllerIndex) { if (m_ControllerHandle == 0) { return; } NativeApi.NRControllerRecenter(m_ControllerHandle, controllerIndex); } /// Trigger haptic vibrate. /// Zero-based index of the controller. /// The duration. /// The frequency. /// The amplitude. public void TriggerHapticVibrate(int controllerIndex, Int64 duration, float frequency, float amplitude) { if (m_ControllerHandle == 0) { return; } NativeApi.NRControllerHapticVibrate(m_ControllerHandle, controllerIndex, duration, frequency, amplitude); } /// Updates the state described by controllerIndex. /// Zero-based index of the controller. /// True if it succeeds, false if it fails. public bool UpdateState(int controllerIndex) { if (m_ControllerHandle == 0) { return false; } if (m_StateHandles[controllerIndex] == 0) NativeApi.NRControllerStateCreate(m_ControllerHandle, controllerIndex, ref m_StateHandles[controllerIndex]); if (m_StateHandles[controllerIndex] == 0) return false; NativeResult result = NativeApi.NRControllerStateUpdate(m_StateHandles[controllerIndex]); return result == NativeResult.Success; } /// Destroys the state described by controllerIndex. /// Zero-based index of the controller. public void DestroyState(int controllerIndex) { NativeApi.NRControllerStateDestroy(m_StateHandles[controllerIndex]); } /// Gets connection state. /// Zero-based index of the controller. /// The connection state. public ControllerConnectionState GetConnectionState(int controllerIndex) { ControllerConnectionState state = ControllerConnectionState.CONTROLLER_CONNECTION_STATE_NOT_INITIALIZED; NativeApi.NRControllerStateGetConnectionState(m_StateHandles[controllerIndex], ref state); return state; } /// Gets battery level. /// Zero-based index of the controller. /// The battery level. public int GetBatteryLevel(int controllerIndex) { int batteryLevel = -1; NativeApi.NRControllerStateGetBatteryLevel(m_StateHandles[controllerIndex], ref batteryLevel); return batteryLevel; } /// Query if 'controllerIndex' is charging. /// Zero-based index of the controller. /// True if charging, false if not. public bool IsCharging(int controllerIndex) { int isCharging = 0; NativeApi.NRControllerStateGetCharging(m_StateHandles[controllerIndex], ref isCharging); return isCharging == 1; } /// Gets a pose. /// Zero-based index of the controller. /// The pose. public Pose GetPose(int controllerIndex) { Pose controllerPos = Pose.identity; NativeMat4f mat4f = new NativeMat4f(Matrix4x4.identity); NativeResult result = NativeApi.NRControllerStateGetPose(m_StateHandles[controllerIndex], ref mat4f); if (result == NativeResult.Success) ConversionUtility.ApiPoseToUnityPose(mat4f, out controllerPos); return controllerPos; } /// Gets a gyro. /// Zero-based index of the controller. /// The gyro. public Vector3 GetGyro(int controllerIndex) { NativeVector3f vec3f = new NativeVector3f(); NativeResult result = NativeApi.NRControllerStateGetGyro(m_StateHandles[controllerIndex], ref vec3f); if (result == NativeResult.Success) return vec3f.ToUnityVector3(); return Vector3.zero; } /// Gets an accel. /// Zero-based index of the controller. /// The accel. public Vector3 GetAccel(int controllerIndex) { NativeVector3f vec3f = new NativeVector3f(); NativeResult result = NativeApi.NRControllerStateGetAccel(m_StateHandles[controllerIndex], ref vec3f); if (result == NativeResult.Success) return vec3f.ToUnityVector3(); return Vector3.zero; } /// Gets a magnitude. /// Zero-based index of the controller. /// The magnitude. public Vector3 GetMag(int controllerIndex) { NativeVector3f vec3f = new NativeVector3f(); NativeResult result = NativeApi.NRControllerStateGetMag(m_StateHandles[controllerIndex], ref vec3f); if (result == NativeResult.Success) return vec3f.ToUnityVector3(); return Vector3.zero; } /// Gets button state. /// Zero-based index of the controller. /// The button state. public uint GetButtonState(int controllerIndex) { uint buttonPress = 0; NativeApi.NRControllerStateGetButtonState(m_StateHandles[controllerIndex], ref buttonPress); return buttonPress; } /// Gets button up. /// Zero-based index of the controller. /// The button up. public uint GetButtonUp(int controllerIndex) { uint buttonUp = 0; NativeApi.NRControllerStateGetButtonUp(m_StateHandles[controllerIndex], ref buttonUp); return buttonUp; } /// Gets button down. /// Zero-based index of the controller. /// The button down. public uint GetButtonDown(int controllerIndex) { uint buttonDown = 0; NativeApi.NRControllerStateGetButtonDown(m_StateHandles[controllerIndex], ref buttonDown); return buttonDown; } /// Query if 'controllerIndex' is touching. /// Zero-based index of the controller. /// True if touching, false if not. public bool IsTouching(int controllerIndex) { uint touchState = 0; NativeApi.NRControllerStateTouchState(m_StateHandles[controllerIndex], ref touchState); return touchState == 1; } /// Gets touch up. /// Zero-based index of the controller. /// True if it succeeds, false if it fails. public bool GetTouchUp(int controllerIndex) { uint touchUp = 0; NativeApi.NRControllerStateGetTouchUp(m_StateHandles[controllerIndex], ref touchUp); return touchUp == 1; } /// Gets touch down. /// Zero-based index of the controller. /// True if it succeeds, false if it fails. public bool GetTouchDown(int controllerIndex) { uint touchDown = 0; NativeApi.NRControllerStateGetTouchDown(m_StateHandles[controllerIndex], ref touchDown); return touchDown == 1; } /// Gets a touch. /// Zero-based index of the controller. /// The touch. public Vector2 GetTouch(int controllerIndex) { NativeVector2f touchPos = new NativeVector2f(); NativeResult result = NativeApi.NRControllerStateGetTouchPose(m_StateHandles[controllerIndex], ref touchPos); if (result == NativeResult.Success) return touchPos.ToUnityVector2(); return Vector3.zero; } /// Updates the head pose described by hmdPose. /// The hmd pose. public void UpdateHeadPose(Pose hmdPose) { NativeMat4f apiPose; ConversionUtility.UnityPoseToApiPose(hmdPose, out apiPose); NativeApi.NRControllerSetHeadPose(m_ControllerHandle, ref apiPose); } /// Gets a version. /// Zero-based index of the controller. /// The version. public string GetVersion(int controllerIndex) { if (m_ControllerHandle == 0) { return ""; } byte[] bytes = new byte[128]; var result = NativeApi.NRControllerGetVersion(m_ControllerHandle, controllerIndex, bytes, bytes.Length); if (result == NativeResult.Success) { return System.Text.Encoding.ASCII.GetString(bytes, 0, bytes.Length); } else { return ""; } } public HandednessType GetHandednessType() { HandednessType handedness_type = HandednessType.RIGHT_HANDEDNESS; var result = NativeApi.NRControllerGetHandednessType(m_ControllerHandle, ref handedness_type); NativeErrorListener.Check(result, this, "GetHandednessType"); return handedness_type; } private partial struct NativeApi { /// Nr controller create. /// [in,out] Handle of the out controller. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerCreate(ref UInt64 out_controller_handle); /// Nr controller start. /// Handle of the controller. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStart(UInt64 controller_handle); /// Nr controller pause. /// Handle of the controller. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerPause(UInt64 controller_handle); /// Nr controller resume. /// Handle of the controller. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerResume(UInt64 controller_handle); /// Nr controller stop. /// Handle of the controller. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStop(UInt64 controller_handle); /// Nr controller destroy. /// Handle of the controller. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerDestroy(UInt64 controller_handle); /// Nr controller get count. /// Handle of the controller. /// [in,out] Number of out controllers. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerGetCount(UInt64 controller_handle, ref int out_controller_count); /// Nr controller get available features. /// Handle of the controller. /// Zero-based index of the controller. /// [in,out] The out controller available /// features. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerGetAvailableFeatures(UInt64 controller_handle, int controller_index, ref uint out_controller_available_features); /// Nr controller get type. /// Handle of the controller. /// Zero-based index of the controller. /// [in,out] Type of the out controller. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerGetType(UInt64 controller_handle, int controller_index, ref ControllerType out_controller_type); /// Nr controller recenter. /// Handle of the controller. /// Zero-based index of the controller. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerRecenter(UInt64 controller_handle, int controller_index); /// Nr controller state create. /// Handle of the controller. /// Zero-based index of the controller. /// [in,out] Handle of the out controller state. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateCreate(UInt64 controller_handle, int controller_index, ref UInt64 out_controller_state_handle); /// Nr controller state update. /// Handle of the controller state. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateUpdate(UInt64 controller_state_handle); /// Nr controller state destroy. /// Handle of the controller state. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateDestroy(UInt64 controller_state_handle); /// duration(nanoseconds), frequency(Hz), amplitude(0.0f ~ 1.0f) /// Handle of the controller. /// Zero-based index of the controller. /// The duration. /// The frequency. /// The amplitude. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerHapticVibrate(UInt64 controller_handle, int controller_index, Int64 duration, float frequency, float amplitude); /// Nr controller state get connection state. /// Handle of the controller state. /// [in,out] State of the out controller /// connection. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateGetConnectionState(UInt64 controller_state_handle, ref ControllerConnectionState out_controller_connection_state); /// Nr controller state get battery level. /// Handle of the controller state. /// [in,out] The out controller battery level. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateGetBatteryLevel(UInt64 controller_state_handle, ref int out_controller_battery_level); /// Nr controller state get charging. /// Handle of the controller state. /// [in,out] The out controller charging. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateGetCharging(UInt64 controller_state_handle, ref int out_controller_charging); /// Nr controller state get pose. /// Handle of the controller state. /// [in,out] The out controller pose. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateGetPose(UInt64 controller_state_handle, ref NativeMat4f out_controller_pose); /// Nr controller state get gyro. /// Handle of the controller state. /// [in,out] The out controller gyro. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateGetGyro(UInt64 controller_state_handle, ref NativeVector3f out_controller_gyro); /// Nr controller state get accel. /// Handle of the controller state. /// [in,out] The out controller accel. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateGetAccel(UInt64 controller_state_handle, ref NativeVector3f out_controller_accel); /// Nr controller state get magnitude. /// Handle of the controller state. /// [in,out] The out controller magnitude. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateGetMag(UInt64 controller_state_handle, ref NativeVector3f out_controller_mag); /// Nr controller state get button state. /// Handle of the controller state. /// [in,out] State of the out controller button. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateGetButtonState(UInt64 controller_state_handle, ref uint out_controller_button_state); /// Nr controller state get button up. /// Handle of the controller state. /// [in,out] The out controller button up. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateGetButtonUp(UInt64 controller_state_handle, ref uint out_controller_button_up); /// Nr controller state get button down. /// Handle of the controller state. /// [in,out] The out controller button down. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateGetButtonDown(UInt64 controller_state_handle, ref uint out_controller_button_down); /// Nr controller state touch state. /// Handle of the controller state. /// [in,out] State of the out controller touch. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateTouchState(UInt64 controller_state_handle, ref uint out_controller_touch_state); /// Nr controller state get touch up. /// Handle of the controller state. /// [in,out] The out controller touch up. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateGetTouchUp(UInt64 controller_state_handle, ref uint out_controller_touch_up); /// Nr controller state get touch down. /// Handle of the controller state. /// [in,out] The out controller touch down. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateGetTouchDown(UInt64 controller_state_handle, ref uint out_controller_touch_down); /// Nr controller state get touch pose. /// Handle of the controller state. /// [in,out] The out controller touch pose. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerStateGetTouchPose(UInt64 controller_state_handle, ref NativeVector2f out_controller_touch_pose); /// Nr controller set head pose. /// Handle of the controller. /// [in,out] The out controller pose. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerSetHeadPose(UInt64 controller_handle, ref NativeMat4f out_controller_pose); /// Nr controller get version. /// Handle of the controller. /// Zero-based index of the controller. /// The out version. /// The length. /// A NativeResult. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerGetVersion(UInt64 controller_handle, int controller_index, byte[] out_version, int len); /// Get the handedness left or right. /// The handle of controller state object. /// The handedness type returned. /// The result of operation. [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRControllerGetHandednessType(UInt64 controller_handle, ref HandednessType handedness_type); }; } }