1+ using HTC . UnityPlugin . Utility ;
2+ using UnityEngine ;
3+ #if VIU_WAVEVR && UNITY_ANDROID
4+ using wvr ;
5+ #endif
6+
7+ namespace HTC . UnityPlugin . VRModuleManagement
8+ {
9+ public class WaveVRModule : VRModule . ModuleBase
10+ {
11+ #if VIU_WAVEVR && UNITY_ANDROID
12+ private const uint HMD_INDEX = 0 ;
13+ private const uint RIGHT_INDEX = 1 ;
14+ private const uint LEFT_INDEX = 2 ;
15+ private const uint DEVICE_COUNT = 3 ;
16+ private const uint INPUT_TYPE = ( uint ) ( WVR_InputType . WVR_InputType_Button | WVR_InputType . WVR_InputType_Touch | WVR_InputType . WVR_InputType_Analog ) ;
17+
18+ public static readonly Vector3 DEFAULT_NECK_POSITION = new Vector3 ( 0.0f , - 0.15f , 0.0f ) ;
19+ public static readonly Vector3 DEFAULT_ELBOW_REST_POSITION = new Vector3 ( 0.195f , - 0.5f , 0.005f ) ;
20+ public static readonly Vector3 DEFAULT_WRIST_REST_POSITION = new Vector3 ( 0.0f , 0.0f , 0.25f ) ;
21+ public static readonly Vector3 DEFAULT_CONTROLLER_REST_POSITION = new Vector3 ( 0.0f , 0.0f , 0.05f ) ;
22+ public static readonly Vector3 DEFAULT_ARM_EXTENSION_OFFSET = new Vector3 ( - 0.13f , 0.14f , 0.08f ) ;
23+ public static readonly Vector3 RIGHT_ARM_MULTIPLIER = new Vector3 ( 1f , 1f , 1f ) ;
24+ public static readonly Vector3 LEFT_ARM_MULTIPLIER = new Vector3 ( 1f , 1f , 1f ) ;
25+ public const float DEFAULT_ELBOW_BEND_RATIO = 0.6f ;
26+ public const float MIN_EXTENSION_ANGLE = 7.0f ;
27+ public const float MAX_EXTENSION_ANGLE = 60.0f ;
28+ public const float EXTENSION_WEIGHT = 0.4f ;
29+
30+ private Vector3 handedMultiplier ;
31+
32+ private WVR_DeviceType [ ] m_deviceTypes = new WVR_DeviceType [ ]
33+ {
34+ WVR_DeviceType . WVR_DeviceType_HMD ,
35+ WVR_DeviceType . WVR_DeviceType_Controller_Right ,
36+ WVR_DeviceType . WVR_DeviceType_Controller_Left ,
37+ } ;
38+ private WVR_DevicePosePair_t [ ] m_poses = new WVR_DevicePosePair_t [ DEVICE_COUNT ] ; // HMD, R, L controllers.
39+ private WVR_AnalogState_t [ ] m_analogStates = new WVR_AnalogState_t [ 2 ] ;
40+
41+ public override bool ShouldActiveModule ( )
42+ {
43+ return true ;
44+ }
45+
46+ public override void OnActivated ( )
47+ {
48+ var instance = Object . FindObjectOfType < WaveVR_Init > ( ) ;
49+ if ( instance == null )
50+ {
51+ VRModule . Instance . gameObject . AddComponent < WaveVR_Init > ( ) ;
52+ }
53+ }
54+
55+ public override void OnDeactivated ( ) { }
56+
57+ public override uint GetRightControllerDeviceIndex ( ) { return RIGHT_INDEX ; }
58+
59+ public override uint GetLeftControllerDeviceIndex ( ) { return LEFT_INDEX ; }
60+
61+ public override void UpdateDeviceState ( IVRModuleDeviceState [ ] prevState , IVRModuleDeviceStateRW [ ] currState )
62+ {
63+ if ( WaveVR . Instance == null ) { return ; }
64+
65+ WVR_PoseOriginModel poseOrigin ;
66+ switch ( VRModule . trackingSpaceType )
67+ {
68+ case VRModuleTrackingSpaceType . RoomScale :
69+ { poseOrigin = WVR_PoseOriginModel . WVR_PoseOriginModel_OriginOnGround ; break ; }
70+ case VRModuleTrackingSpaceType . Stationary :
71+ default :
72+ { poseOrigin = WVR_PoseOriginModel . WVR_PoseOriginModel_OriginOnHead ; break ; }
73+ }
74+
75+ IVRModuleDeviceStateRW headState = null ;
76+ IVRModuleDeviceStateRW rightState = null ;
77+ IVRModuleDeviceStateRW leftState = null ;
78+
79+ Interop . WVR_GetSyncPose ( poseOrigin , m_poses , DEVICE_COUNT ) ;
80+
81+ for ( int i = 0 ; i < DEVICE_COUNT ; ++ i )
82+ {
83+ var deviceType = m_poses [ i ] . type ;
84+ var devicePose = m_poses [ i ] . pose ;
85+
86+ if ( deviceType == m_deviceTypes [ i ] && devicePose . IsValidPose )
87+ {
88+ currState [ i ] . isConnected = true ;
89+ if ( deviceType == WVR_DeviceType . WVR_DeviceType_HMD )
90+ {
91+ currState [ i ] . deviceClass = VRModuleDeviceClass . HMD ;
92+ currState [ i ] . deviceModel = VRModuleDeviceModel . ViveFocusHMD ;
93+ }
94+ else
95+ {
96+ currState [ i ] . deviceClass = VRModuleDeviceClass . Controller ;
97+ currState [ i ] . deviceModel = VRModuleDeviceModel . ViveFocusFinch ;
98+ }
99+
100+ var rigidTransform = new WaveVR_Utils . RigidTransform ( devicePose . PoseMatrix ) ;
101+
102+ currState [ i ] . isPoseValid = true ;
103+ currState [ i ] . isOutOfRange = false ;
104+ currState [ i ] . isCalibrating = false ;
105+ currState [ i ] . isUninitialized = false ;
106+
107+ currState [ i ] . velocity = new Vector3 ( devicePose . Velocity . v0 , devicePose . Velocity . v1 , - devicePose . Velocity . v2 ) ;
108+ currState [ i ] . angularVelocity = new Vector3 ( - devicePose . AngularVelocity . v0 , - devicePose . AngularVelocity . v1 , devicePose . AngularVelocity . v2 ) ;
109+
110+ currState [ i ] . position = rigidTransform . pos ;
111+ currState [ i ] . rotation = rigidTransform . rot ;
112+
113+ switch ( deviceType )
114+ {
115+ case WVR_DeviceType . WVR_DeviceType_HMD :
116+ headState = currState [ i ] ;
117+ break ;
118+ case WVR_DeviceType . WVR_DeviceType_Controller_Right :
119+ rightState = currState [ i ] ;
120+ break ;
121+ case WVR_DeviceType . WVR_DeviceType_Controller_Left :
122+ leftState = currState [ i ] ;
123+ break ;
124+ }
125+
126+ uint buttons = 0 ;
127+ uint touches = 0 ;
128+
129+ // FIXME: What does WVR_GetInputTypeCount means?
130+ //var analogCount = Interop.WVR_GetInputTypeCount(deviceType, WVR_InputType.WVR_InputType_Analog);
131+ //if (m_analogStates == null || m_analogStates.Length < analogCount) { m_analogStates = new WVR_AnalogState_t[analogCount]; }
132+
133+ if ( Interop . WVR_GetInputDeviceState ( deviceType , INPUT_TYPE , ref buttons , ref touches , m_analogStates , m_analogStates . Length ) )
134+ {
135+ const uint dpadMask =
136+ ( 1 << ( int ) ( WVR_InputId . WVR_InputId_Alias1_Touchpad ) ) |
137+ ( 1 << ( int ) ( WVR_InputId . WVR_InputId_Alias1_DPad_Left ) ) |
138+ ( 1 << ( int ) ( WVR_InputId . WVR_InputId_Alias1_DPad_Up ) ) |
139+ ( 1 << ( int ) ( WVR_InputId . WVR_InputId_Alias1_DPad_Right ) ) |
140+ ( 1 << ( int ) ( WVR_InputId . WVR_InputId_Alias1_DPad_Down ) ) ;
141+
142+ const uint triggerBumperMask =
143+ ( 1 << ( int ) ( WVR_InputId . WVR_InputId_Alias1_Trigger ) ) |
144+ ( 1 << ( int ) ( WVR_InputId . WVR_InputId_Alias1_Bumper ) ) ;
145+
146+ currState [ i ] . SetButtonPress ( VRModuleRawButton . System , ( buttons & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_System ) ) != 0u ) ;
147+ currState [ i ] . SetButtonPress ( VRModuleRawButton . ApplicationMenu , ( buttons & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_Menu ) ) != 0u ) ;
148+ currState [ i ] . SetButtonPress ( VRModuleRawButton . Touchpad , ( buttons & dpadMask ) != 0u ) ;
149+ currState [ i ] . SetButtonPress ( VRModuleRawButton . Trigger , ( buttons & triggerBumperMask ) != 0u ) ;
150+ currState [ i ] . SetButtonPress ( VRModuleRawButton . Grip , ( buttons & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_Grip ) ) != 0u ) ;
151+ currState [ i ] . SetButtonPress ( VRModuleRawButton . DPadLeft , ( buttons & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_DPad_Left ) ) != 0u ) ;
152+ currState [ i ] . SetButtonPress ( VRModuleRawButton . DPadUp , ( buttons & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_DPad_Up ) ) != 0u ) ;
153+ currState [ i ] . SetButtonPress ( VRModuleRawButton . DPadRight , ( buttons & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_DPad_Right ) ) != 0u ) ;
154+ currState [ i ] . SetButtonPress ( VRModuleRawButton . DPadDown , ( buttons & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_DPad_Down ) ) != 0u ) ;
155+
156+ currState [ i ] . SetButtonTouch ( VRModuleRawButton . System , ( touches & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_System ) ) != 0u ) ;
157+ currState [ i ] . SetButtonTouch ( VRModuleRawButton . ApplicationMenu , ( touches & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_Menu ) ) != 0u ) ;
158+ currState [ i ] . SetButtonTouch ( VRModuleRawButton . Touchpad , ( touches & dpadMask ) != 0u ) ;
159+ currState [ i ] . SetButtonTouch ( VRModuleRawButton . Trigger , ( touches & triggerBumperMask ) != 0u ) ;
160+ currState [ i ] . SetButtonTouch ( VRModuleRawButton . Grip , ( touches & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_Grip ) ) != 0u ) ;
161+ currState [ i ] . SetButtonTouch ( VRModuleRawButton . DPadLeft , ( touches & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_DPad_Left ) ) != 0u ) ;
162+ currState [ i ] . SetButtonTouch ( VRModuleRawButton . DPadUp , ( touches & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_DPad_Up ) ) != 0u ) ;
163+ currState [ i ] . SetButtonTouch ( VRModuleRawButton . DPadRight , ( touches & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_DPad_Right ) ) != 0u ) ;
164+ currState [ i ] . SetButtonTouch ( VRModuleRawButton . DPadDown , ( touches & ( 1 << ( int ) WVR_InputId . WVR_InputId_Alias1_DPad_Down ) ) != 0u ) ;
165+
166+ for ( int j = 0 , jmax = m_analogStates . Length ; j < jmax ; ++ j )
167+ {
168+ switch ( m_analogStates [ j ] . id )
169+ {
170+ case WVR_InputId . WVR_InputId_Alias1_Trigger :
171+ if ( m_analogStates [ j ] . type == WVR_AnalogType . WVR_AnalogType_Trigger )
172+ {
173+ currState [ i ] . SetAxisValue ( VRModuleRawAxis . Trigger , m_analogStates [ j ] . axis . x ) ;
174+ }
175+ break ;
176+ case WVR_InputId . WVR_InputId_Alias1_Touchpad :
177+ if ( m_analogStates [ j ] . type == WVR_AnalogType . WVR_AnalogType_TouchPad && currState [ i ] . GetButtonTouch ( VRModuleRawButton . Touchpad ) )
178+ {
179+ currState [ i ] . SetAxisValue ( VRModuleRawAxis . TouchpadX , m_analogStates [ j ] . axis . x ) ;
180+ currState [ i ] . SetAxisValue ( VRModuleRawAxis . TouchpadY , m_analogStates [ j ] . axis . y ) ;
181+ }
182+ else
183+ {
184+ currState [ i ] . SetAxisValue ( VRModuleRawAxis . TouchpadX , 0f ) ;
185+ currState [ i ] . SetAxisValue ( VRModuleRawAxis . TouchpadY , 0f ) ;
186+ }
187+ break ;
188+ }
189+ }
190+ }
191+ else
192+ {
193+ currState [ i ] . buttonPressed = 0u ;
194+ currState [ i ] . buttonTouched = 0u ;
195+ for ( int j = 0 , jmax = currState [ i ] . axisValue . Length ; j < jmax ; ++ j ) { currState [ i ] . axisValue [ j ] = 0f ; }
196+ }
197+ }
198+ else
199+ {
200+ if ( prevState [ i ] . isConnected )
201+ {
202+ currState [ i ] . Reset ( ) ;
203+ }
204+ }
205+ }
206+
207+ // add right arm
208+ if ( rightState != null && rightState . isConnected && rightState . position == Vector3 . zero )
209+ {
210+ rightState . position = GetControllerPositionWithVirtualArm ( GetNeckPose ( headState . pose ) , rightState . rotation , RIGHT_ARM_MULTIPLIER ) ;
211+ }
212+
213+ // add left arm
214+ if ( leftState != null && leftState . isConnected && leftState . position == Vector3 . zero )
215+ {
216+ leftState . position = GetControllerPositionWithVirtualArm ( GetNeckPose ( headState . pose ) , leftState . rotation , LEFT_ARM_MULTIPLIER ) ;
217+ }
218+ }
219+
220+ private static RigidPose GetNeckPose ( RigidPose headPose )
221+ {
222+ var headForward = headPose . forward ;
223+ return new RigidPose ( headPose . pos + DEFAULT_NECK_POSITION , Quaternion . FromToRotation ( Vector3 . forward , new Vector3 ( headForward . x , 0f , headForward . z ) ) ) ;
224+ }
225+
226+ private static float GetExtensionRatio ( Vector3 v )
227+ {
228+ var xAngle = 90f - Vector3 . Angle ( v , Vector3 . up ) ;
229+ return Mathf . Clamp01 ( Mathf . InverseLerp ( MIN_EXTENSION_ANGLE , MAX_EXTENSION_ANGLE , xAngle ) ) ;
230+ }
231+
232+ private static Quaternion GetLerpRotation ( Quaternion xyRotation , float extensionRatio )
233+ {
234+ float totalAngle = Quaternion . Angle ( xyRotation , Quaternion . identity ) ;
235+ float lerpSuppresion = 1.0f - Mathf . Pow ( totalAngle / 180.0f , 6.0f ) ;
236+ float inverseElbowBendRatio = 1.0f - DEFAULT_ELBOW_BEND_RATIO ;
237+ float lerpValue = inverseElbowBendRatio + DEFAULT_ELBOW_BEND_RATIO * extensionRatio * EXTENSION_WEIGHT ;
238+ lerpValue *= lerpSuppresion ;
239+ return Quaternion . Lerp ( Quaternion . identity , xyRotation , lerpValue ) ;
240+ }
241+
242+ private static Vector3 GetControllerPositionWithVirtualArm ( RigidPose neckPose , Quaternion ctrlRot , Vector3 sideMultiplier )
243+ {
244+ var localCtrlForward = ( Quaternion . Inverse ( neckPose . rot ) * ctrlRot ) * Vector3 . forward ;
245+ var localCtrlXYRot = Quaternion . FromToRotation ( Vector3 . forward , localCtrlForward ) ;
246+ var extensionRatio = GetExtensionRatio ( localCtrlForward ) ;
247+ var lerpRotation = GetLerpRotation ( localCtrlXYRot , extensionRatio ) ;
248+
249+ var elbowPose = new RigidPose (
250+ Vector3 . Scale ( DEFAULT_ELBOW_REST_POSITION , sideMultiplier ) + Vector3 . Scale ( DEFAULT_ARM_EXTENSION_OFFSET , sideMultiplier ) * extensionRatio ,
251+ Quaternion . Inverse ( lerpRotation ) * localCtrlXYRot ) ;
252+ var wristPose = new RigidPose (
253+ Vector3 . Scale ( DEFAULT_WRIST_REST_POSITION , sideMultiplier ) ,
254+ lerpRotation ) ;
255+ var palmPose = new RigidPose (
256+ Vector3 . Scale ( DEFAULT_CONTROLLER_REST_POSITION , sideMultiplier ) ,
257+ Quaternion . identity ) ;
258+
259+ var finalCtrlPose = neckPose * elbowPose * wristPose * palmPose ;
260+ return finalCtrlPose . pos ;
261+ }
262+
263+ public override void TriggerViveControllerHaptic ( uint deviceIndex , ushort durationMicroSec = 500 )
264+ {
265+ Interop . WVR_TriggerVibrator ( m_deviceTypes [ deviceIndex ] , WVR_InputId . WVR_InputId_Alias1_Touchpad , durationMicroSec ) ;
266+ }
267+ #endif
268+ }
269+ }
0 commit comments