/****************************************************************************
* 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);
};
}
}