@@ -16,14 +16,44 @@ namespace SRanipalExtTrackingInterface
1616{
1717 public class SRanipalExtTrackingInterface : ExtTrackingModule
1818 {
19- LipData_v2 lipData ;
20- EyeData_v2 eyeData ;
21- private static bool eyeEnabled , lipEnabled , isViveProEye ;
19+ LipData_v2 lipData = default ;
20+ EyeData_v2 eyeData = default ;
21+ private static bool eyeEnabled = false ,
22+ lipEnabled = false ,
23+ isViveProEye = false ,
24+ isWireless = false ;
25+ private static Error eyeError = Error . UNDEFINED ;
26+ private static Error lipError = Error . UNDEFINED ;
27+
28+ internal static Process ? _process ;
29+ internal static IntPtr _processHandle ;
30+ internal static IntPtr _offset ;
31+
2232 private static byte [ ] eyeImageCache , lipImageCache ;
2333
2434 // Kernel32 SetDllDirectory
2535 [ DllImport ( "kernel32.dll" , CharSet = CharSet . Unicode ) ]
2636 private static extern bool SetDllDirectory ( string lpPathName ) ;
37+
38+ private static bool Attach ( )
39+ {
40+ var processes = Process . GetProcessesByName ( "sr_runtime" ) ;
41+ if ( processes . Length <= 0 ) return false ;
42+ _process = processes [ 0 ] ;
43+ _processHandle =
44+ Utils . OpenProcess ( Utils . PROCESS_VM_READ ,
45+ false , _process . Id ) ;
46+ return true ;
47+ }
48+
49+ private static byte [ ] ReadMemory ( IntPtr offset , ref byte [ ] buf ) {
50+ var bytesRead = 0 ;
51+ var size = buf . Length ;
52+
53+ Utils . ReadProcessMemory ( ( int ) _processHandle , offset , buf , size , ref bytesRead ) ;
54+
55+ return bytesRead != size ? null : buf ;
56+ }
2757
2858 public override ( bool SupportsEye , bool SupportsExpression ) Supported => ( true , true ) ;
2959
@@ -83,15 +113,10 @@ public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAva
83113
84114 SetDllDirectory ( currentDllDirectory + "\\ ModuleLibs\\ " + ( srRuntimeVer . StartsWith ( "1.3.6" ) ? "New" : "Old" ) ) ;
85115
86- Error eyeError = Error . UNDEFINED , lipError = Error . UNDEFINED ;
87-
88- if ( eyeAvailable )
89- eyeError = SRanipal_API . Initial ( SRanipal_Eye_v2 . ANIPAL_TYPE_EYE_V2 , IntPtr . Zero ) ;
90-
91- if ( expressionAvailable )
92- lipError = SRanipal_API . Initial ( SRanipal_Lip_v2 . ANIPAL_TYPE_LIP_V2 , IntPtr . Zero ) ;
116+ SRanipal_API . InitialRuntime ( ) ; // hack to unblock sranipal!!!
93117
94- HandleSrErrors ( eyeError , lipError ) ;
118+ eyeEnabled = InitTracker ( SRanipal_Eye_v2 . ANIPAL_TYPE_EYE_V2 , "Eye" ) ;
119+ lipEnabled = InitTracker ( SRanipal_Lip_v2 . ANIPAL_TYPE_LIP_V2 , "Lip" ) ;
95120
96121 if ( eyeEnabled && Utils . HasAdmin )
97122 {
@@ -112,7 +137,7 @@ public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAva
112137 {
113138 _offset = module . BaseAddress ;
114139
115- switch ( _process . MainModule . FileVersionInfo . FileVersion )
140+ switch ( _process . MainModule ? . FileVersionInfo . FileVersion )
116141 {
117142 case "1.3.2.0" :
118143 _offset += 0x19190 ;
@@ -126,8 +151,6 @@ public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAva
126151 UnifiedTracking . EyeImageData . SupportsImage = false ;
127152 break ;
128153 }
129-
130- //(_process.MainModule.FileVersionInfo.FileVersion == "1.3.2.0" ? 0x19190 : 0x19100);
131154 }
132155
133156 UnifiedTracking . EyeImageData . ImageSize = ( 200 , 100 ) ;
@@ -140,12 +163,10 @@ public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAva
140163 {
141164 UnifiedTracking . LipImageData . SupportsImage = true ;
142165 UnifiedTracking . LipImageData . ImageSize = ( SRanipal_Lip_v2 . ImageWidth , SRanipal_Lip_v2 . ImageHeight ) ;
143- UnifiedTracking . LipImageData . ImageData = new byte [ SRanipal_Lip_v2 . ImageWidth *
144- SRanipal_Lip_v2 . ImageHeight * 4 ] ;
145-
146166 lipData . image = Marshal . AllocCoTaskMem ( UnifiedTracking . LipImageData . ImageSize . x *
147167 UnifiedTracking . LipImageData . ImageSize . x ) ;
148168
169+ UnifiedTracking . LipImageData . ImageData = new byte [ SRanipal_Lip_v2 . ImageWidth * SRanipal_Lip_v2 . ImageHeight * 4 ] ;
149170 lipImageCache = new byte [ SRanipal_Lip_v2 . ImageWidth * SRanipal_Lip_v2 . ImageHeight ] ;
150171 }
151172
@@ -162,89 +183,67 @@ public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAva
162183
163184 isViveProEye = SRanipal_Eye_API . IsViveProEye ( ) ;
164185
165- return ( eyeEnabled , lipEnabled ) ;
186+ return ( eyeAvailable && eyeEnabled , expressionAvailable && lipEnabled ) ;
166187 }
167188
168- private static void HandleSrErrors ( Error eyeError , Error lipError )
189+ private bool InitTracker ( int anipalType , string name )
169190 {
170- if ( eyeError == Error . WORK )
171- eyeEnabled = true ;
191+ Logger . LogInformation ( $ "Initializing { name } ..." ) ;
192+ var error = SRanipal_API . Initial ( anipalType , IntPtr . Zero ) ;
172193
173- if ( lipError == Error . FOXIP_SO )
174- while ( lipError == Error . FOXIP_SO )
175- lipError = SRanipal_API . Initial ( SRanipal_Lip_v2 . ANIPAL_TYPE_LIP_V2 , IntPtr . Zero ) ;
176-
177- if ( lipError == Error . WORK )
178- lipEnabled = true ;
194+ handler :
195+ switch ( error )
196+ {
197+ case Error . FOXIP_SO : // wireless issue
198+ Logger . LogInformation ( "Vive wireless detected. Forcing initialization..." ) ;
199+ while ( error == Error . FOXIP_SO )
200+ error = SRanipal_API . Initial ( anipalType , IntPtr . Zero ) ;
201+ goto handler ;
202+ case Error . WORK :
203+ Logger . LogInformation ( $ "{ name } successfully started!") ;
204+ return true ;
205+ default :
206+ break ;
207+ }
208+ Logger . LogInformation ( $ "{ name } failed to initialize: { error } ") ;
209+ return false ;
179210 }
180211
181212 public override void Teardown ( )
182213 {
183- // We won't bother terminating sranipal modules here as if this is a shutdown, they'll automatically be released.
214+ SRanipal_API . ReleaseRuntime ( ) ;
184215 }
185216
186- #region Update
187-
188-
189217 public override void Update ( )
190218 {
191219 Thread . Sleep ( 10 ) ;
192220
193221 if ( Status != ModuleState . Active )
194222 return ;
195-
196- if ( lipEnabled && UpdateMouth ( ) != Error . WORK )
223+ if ( lipEnabled && ! UpdateMouth ( ) )
197224 {
198- Logger . LogError ( "An error occured while getting lip data. This might be a wireless crash." ) ;
199- Logger . LogWarning ( "Waiting 30 seconds before reinitializing to account for wireless users." ) ;
200- Thread . Sleep ( 30000 ) ;
201- // UnifiedLibManager.Initialize();
202- return ;
225+ Logger . LogError ( "An error has occured when updating tracking. Reinitializing needed runtimes." ) ;
226+ SRanipal_API . InitialRuntime ( ) ;
227+ InitTracker ( SRanipal_Lip_v2 . ANIPAL_TYPE_LIP_V2 , "Lip" ) ;
203228 }
204-
205- if ( eyeEnabled && UpdateEye ( ) != Error . WORK )
229+ if ( eyeEnabled && ! UpdateEye ( ) )
206230 {
207- Logger . LogError ( "An error occured while getting eye data. This might be a wireless crash." ) ;
208- Logger . LogWarning ( "Waiting 30 seconds before reinitializing to account for wireless users." ) ;
209- Thread . Sleep ( 30000 ) ;
210- //UnifiedLibManager.Initialize();
211- return ;
231+ Logger . LogError ( "An error has occured when updating tracking. Reinitializing needed runtimes." ) ;
232+ SRanipal_API . InitialRuntime ( ) ;
233+ InitTracker ( SRanipal_Eye_v2 . ANIPAL_TYPE_EYE_V2 , "Eye" ) ;
212234 }
213235 }
214236
215- #endregion
216-
217- private static Process _process ;
218- private static IntPtr _processHandle ;
219- private IntPtr _offset ;
220-
221- private static bool Attach ( )
222- {
223- if ( Process . GetProcessesByName ( "sr_runtime" ) . Length <= 0 ) return false ;
224- _process = Process . GetProcessesByName ( "sr_runtime" ) [ 0 ] ;
225- _processHandle =
226- Utils . OpenProcess ( Utils . PROCESS_VM_READ ,
227- false , _process . Id ) ;
228- return true ;
229- }
230-
231- private static byte [ ] ReadMemory ( IntPtr offset , ref byte [ ] buf ) {
232- var bytesRead = 0 ;
233- var size = buf . Length ;
234-
235- Utils . ReadProcessMemory ( ( int ) _processHandle , offset , buf , size , ref bytesRead ) ;
236-
237- return bytesRead != size ? null : buf ;
238- }
239-
240- private Error UpdateEye ( )
237+ private bool UpdateEye ( )
241238 {
242- var updateResult = SRanipal_Eye_API . GetEyeData_v2 ( ref eyeData ) ;
239+ eyeError = SRanipal_Eye_API . GetEyeData_v2 ( ref eyeData ) ;
240+ if ( eyeError != Error . WORK ) return false ;
243241
244242 UpdateEyeParameters ( ref UnifiedTracking . Data . Eye , eyeData . verbose_data ) ;
245243 UpdateEyeExpressions ( ref UnifiedTracking . Data . Shapes , eyeData . expression_data ) ;
246244
247- if ( _processHandle == IntPtr . Zero || ! UnifiedTracking . EyeImageData . SupportsImage ) return updateResult ;
245+ if ( _processHandle == IntPtr . Zero || ! UnifiedTracking . EyeImageData . SupportsImage )
246+ return true ;
248247
249248 // Read 20000 image bytes from the predefined offset. 10000 bytes per eye.
250249 var imageBytes = ReadMemory ( _offset , ref eyeImageCache ) ;
@@ -280,7 +279,7 @@ private Error UpdateEye()
280279 }
281280 }
282281
283- return updateResult ;
282+ return true ;
284283 }
285284
286285 private static Vector3 GetConvergenceAngleOffset ( VerboseData external )
@@ -357,13 +356,15 @@ private void UpdateEyeExpressions(ref UnifiedExpressionShape[] data, EyeExpressi
357356 data [ ( int ) UnifiedExpressions . BrowLowererRight ] . Weight = external . right . eye_squeeze ;
358357 }
359358
360- private Error UpdateMouth ( )
359+ private bool UpdateMouth ( )
361360 {
362- var updateResult = SRanipal_Lip_API . GetLipData_v2 ( ref lipData ) ;
363-
361+ lipError = SRanipal_Lip_API . GetLipData_v2 ( ref lipData ) ;
362+ if ( lipError != Error . WORK )
363+ return false ;
364364 UpdateMouthExpressions ( ref UnifiedTracking . Data , lipData . prediction_data ) ;
365365
366- if ( lipData . image == IntPtr . Zero || ! UnifiedTracking . LipImageData . SupportsImage ) return updateResult ;
366+ if ( lipData . image == IntPtr . Zero || ! UnifiedTracking . LipImageData . SupportsImage )
367+ return true ;
367368
368369 Marshal . Copy ( lipData . image , lipImageCache , 0 , UnifiedTracking . LipImageData . ImageSize . x *
369370 UnifiedTracking . LipImageData . ImageSize . y ) ;
@@ -383,7 +384,7 @@ private Error UpdateMouth()
383384 }
384385 }
385386
386- return updateResult ;
387+ return true ;
387388 }
388389
389390 private void UpdateMouthExpressions ( ref UnifiedTrackingData data , PredictionData_v2 external )
0 commit comments