@@ -22,10 +22,34 @@ public class SRanipalExtTrackingInterface : ExtTrackingModule
2222 lipEnabled = false ,
2323 isViveProEye = false ,
2424 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 ;
2531
26- // Kernel32 SetDllDirectory
2732 [ DllImport ( "kernel32.dll" , CharSet = CharSet . Unicode ) ]
2833 private static extern bool SetDllDirectory ( string lpPathName ) ;
34+ internal static bool Attach ( )
35+ {
36+ var processes = Process . GetProcessesByName ( "sr_runtime" ) ;
37+ if ( processes . Length <= 0 ) return false ;
38+ _process = processes [ 0 ] ;
39+ _processHandle =
40+ Utils . OpenProcess ( Utils . PROCESS_VM_READ ,
41+ false , _process . Id ) ;
42+ return true ;
43+ }
44+
45+ internal static byte [ ] ReadMemory ( int size ) {
46+ var buffer = new byte [ size ] ;
47+
48+ var bytesRead = 0 ;
49+ Utils . ReadProcessMemory ( ( int ) _processHandle , _offset , buffer , size , ref bytesRead ) ;
50+
51+ return bytesRead != size ? null : buffer ;
52+ }
2953
3054 public override ( bool SupportsEye , bool SupportsExpression ) Supported => ( true , true ) ;
3155
@@ -63,10 +87,10 @@ public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAva
6387
6488 SetDllDirectory ( currentDllDirectory + "\\ ModuleLibs\\ " + ( srRuntimeVer . StartsWith ( "1.3.6" ) ? "New" : "Old" ) ) ;
6589
66- if ( eyeAvailable )
67- HandleEye ( ) ;
68- if ( expressionAvailable )
69- HandleLip ( ) ;
90+ SRanipal_API . InitialRuntime ( ) ; // hack to unblock sranipal!!!
91+
92+ eyeEnabled = InitTracker ( SRanipal_Eye_v2 . ANIPAL_TYPE_EYE_V2 , "Eye" ) ;
93+ lipEnabled = InitTracker ( SRanipal_Lip_v2 . ANIPAL_TYPE_LIP_V2 , "Lip" ) ;
7094
7195 if ( eyeEnabled && Utils . HasAdmin )
7296 {
@@ -87,7 +111,7 @@ public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAva
87111 {
88112 _offset = module . BaseAddress ;
89113
90- switch ( _process . MainModule . FileVersionInfo . FileVersion )
114+ switch ( _process . MainModule ? . FileVersionInfo . FileVersion )
91115 {
92116 case "1.3.2.0" :
93117 _offset += 0x19190 ;
@@ -101,8 +125,6 @@ public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAva
101125 UnifiedTracking . EyeImageData . SupportsImage = false ;
102126 break ;
103127 }
104-
105- //(_process.MainModule.FileVersionInfo.FileVersion == "1.3.2.0" ? 0x19190 : 0x19100);
106128 }
107129
108130 UnifiedTracking . EyeImageData . ImageSize = ( 200 , 100 ) ;
@@ -114,7 +136,7 @@ public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAva
114136 UnifiedTracking . LipImageData . SupportsImage = true ;
115137 UnifiedTracking . LipImageData . ImageSize = ( SRanipal_Lip_v2 . ImageWidth , SRanipal_Lip_v2 . ImageHeight ) ;
116138 UnifiedTracking . LipImageData . ImageData = new byte [ UnifiedTracking . LipImageData . ImageSize . x *
117- UnifiedTracking . LipImageData . ImageSize . y ] ;
139+ UnifiedTracking . LipImageData . ImageSize . y ] ;
118140 lipData . image = Marshal . AllocCoTaskMem ( UnifiedTracking . LipImageData . ImageSize . x *
119141 UnifiedTracking . LipImageData . ImageSize . x ) ;
120142 }
@@ -132,116 +154,70 @@ public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAva
132154
133155 isViveProEye = SRanipal_Eye_API . IsViveProEye ( ) ;
134156
135- return ( eyeEnabled , lipEnabled ) ;
157+ return ( eyeAvailable && eyeEnabled , expressionAvailable && lipEnabled ) ;
136158 }
137159
138- private static void HandleEye ( )
160+ private bool InitTracker ( int anipalType , string name )
139161 {
140- var eyeError = SRanipal_API . Initial ( SRanipal_Eye_v2 . ANIPAL_TYPE_EYE_V2 , IntPtr . Zero ) ;
141- eyeEnabled = eyeError == Error . WORK ;
142- }
162+ Logger . LogInformation ( $ "Initializing { name } ...") ;
163+ var error = SRanipal_API . Initial ( anipalType , IntPtr . Zero ) ;
143164
144- private static void HandleLip ( )
145- {
146- var lipError = SRanipal_API . Initial ( SRanipal_Lip_v2 . ANIPAL_TYPE_LIP_V2 , IntPtr . Zero ) ;
147- if ( lipError == Error . FOXIP_SO )
165+ handler :
166+ switch ( error )
148167 {
149- isWireless = true ;
150- while ( lipError == Error . FOXIP_SO )
151- lipError = SRanipal_API . Initial ( SRanipal_Lip_v2 . ANIPAL_TYPE_LIP_V2 , IntPtr . Zero ) ;
168+ case Error . FOXIP_SO : // wireless issue
169+ Logger . LogInformation ( "Vive wireless detected. Forcing initialization..." ) ;
170+ while ( error == Error . FOXIP_SO )
171+ error = SRanipal_API . Initial ( anipalType , IntPtr . Zero ) ;
172+ goto handler ;
173+ case Error . WORK :
174+ Logger . LogInformation ( $ "{ name } successfully started!") ;
175+ return true ;
176+ default :
177+ break ;
152178 }
153-
154- if ( lipError == Error . WORK )
155- lipEnabled = true ;
179+ Logger . LogInformation ( $ "{ name } failed to initialize: { error } ") ;
180+ return false ;
156181 }
157182
158183 public override void Teardown ( )
159184 {
160- // We won't bother terminating sranipal modules here as if this is a shutdown, they'll automatically be released.
185+ SRanipal_API . ReleaseRuntime ( ) ;
161186 }
162187
163- #region Update
164-
165-
166- private bool lipLock ;
167- private bool eyeLock ;
168-
169188 public override void Update ( )
170189 {
171190 Thread . Sleep ( 10 ) ;
172191
173192 if ( Status != ModuleState . Active )
174193 return ;
175-
176- if ( lipEnabled && UpdateMouth ( ) != Error . WORK && ! lipLock )
194+ if ( lipEnabled && ! UpdateMouth ( ) )
177195 {
178- lipLock = true ;
179- Task . Run ( ( ) =>
180- {
181- Logger . LogError ( "An error occured while getting lip data. Reinitializing SRanipal runtime." ) ;
182- if ( isWireless )
183- {
184- Logger . LogWarning ( "Waiting 30 seconds before reinitializing to account for wireless users." ) ;
185- Thread . Sleep ( 30000 ) ;
196+ Logger . LogError ( "An error has occured when updating tracking. Reinitializing needed runtimes." ) ;
197+ //SRanipal_API.InitialRuntime();
198+ InitTracker ( SRanipal_Lip_v2 . ANIPAL_TYPE_LIP_V2 , "Lip" ) ;
186199 }
187- HandleLip ( ) ;
188- lipLock = false ;
189- } ) ;
190- }
191-
192- if ( eyeEnabled && UpdateEye ( ) != Error . WORK && ! eyeLock )
193- {
194- eyeLock = true ;
195- Task . Run ( ( ) =>
196- {
197- Logger . LogError ( "An error occured while getting eye data. Reinitializing SRanipal runtime." ) ;
198- if ( isWireless )
200+ if ( eyeEnabled && ! UpdateEye ( ) )
199201 {
200- Logger . LogWarning ( "Waiting 30 seconds before reinitializing to account for wireless users." ) ;
201- Thread . Sleep ( 30000 ) ;
202- }
203- HandleEye ( ) ;
204- eyeLock = false ;
205- } ) ;
202+ Logger . LogError ( "An error has occured when updating tracking. Reinitializing needed runtimes." ) ;
203+ //SRanipal_API.InitialRuntime();
204+ InitTracker ( SRanipal_Eye_v2 . ANIPAL_TYPE_EYE_V2 , "Eye" ) ;
206205 }
207206 }
208207
209- #endregion
210-
211- private static Process _process ;
212- private static IntPtr _processHandle ;
213- private IntPtr _offset ;
214-
215- private static bool Attach ( )
208+ private bool UpdateEye ( )
216209 {
217- if ( Process . GetProcessesByName ( "sr_runtime" ) . Length <= 0 ) return false ;
218- _process = Process . GetProcessesByName ( "sr_runtime" ) [ 0 ] ;
219- _processHandle =
220- Utils . OpenProcess ( Utils . PROCESS_VM_READ ,
221- false , _process . Id ) ;
222- return true ;
223- }
224-
225- private static byte [ ] ReadMemory ( IntPtr offset , int size ) {
226- var buffer = new byte [ size ] ;
227-
228- var bytesRead = 0 ;
229- Utils . ReadProcessMemory ( ( int ) _processHandle , offset , buffer , size , ref bytesRead ) ;
230-
231- return bytesRead != size ? null : buffer ;
232- }
233-
234- private Error UpdateEye ( )
235- {
236- var updateResult = SRanipal_Eye_API . GetEyeData_v2 ( ref eyeData ) ;
210+ eyeError = SRanipal_Eye_API . GetEyeData_v2 ( ref eyeData ) ;
211+ if ( eyeError != Error . WORK ) return false ;
237212
238213 UpdateEyeParameters ( ref UnifiedTracking . Data . Eye , eyeData . verbose_data ) ;
239214 UpdateEyeExpressions ( ref UnifiedTracking . Data . Shapes , eyeData . expression_data ) ;
240215
241- if ( _processHandle == IntPtr . Zero || ! UnifiedTracking . EyeImageData . SupportsImage ) return updateResult ;
216+ if ( _processHandle == IntPtr . Zero || ! UnifiedTracking . EyeImageData . SupportsImage )
217+ return true ;
242218
243219 // Read 20000 image bytes from the predefined offset. 10000 bytes per eye.
244- var imageBytes = ReadMemory ( _offset , 20000 ) ;
220+ var imageBytes = ReadMemory ( 20000 ) ;
245221
246222 // Concatenate the two images side by side instead of one after the other
247223 byte [ ] leftEye = new byte [ 10000 ] ;
@@ -262,7 +238,7 @@ private Error UpdateEye()
262238 // Write the image to the latest eye data
263239 UnifiedTracking . EyeImageData . ImageData = imageBytes ;
264240
265- return updateResult ;
241+ return true ;
266242 }
267243
268244 private static Vector3 GetConvergenceAngleOffset ( VerboseData external )
@@ -339,18 +315,20 @@ private void UpdateEyeExpressions(ref UnifiedExpressionShape[] data, EyeExpressi
339315 data [ ( int ) UnifiedExpressions . BrowLowererRight ] . Weight = external . right . eye_squeeze ;
340316 }
341317
342- private Error UpdateMouth ( )
318+ private bool UpdateMouth ( )
343319 {
344- var updateResult = SRanipal_Lip_API . GetLipData_v2 ( ref lipData ) ;
345-
320+ lipError = SRanipal_Lip_API . GetLipData_v2 ( ref lipData ) ;
321+ if ( lipError != Error . WORK )
322+ return false ;
346323 UpdateMouthExpressions ( ref UnifiedTracking . Data , lipData . prediction_data ) ;
347324
348- if ( lipData . image == IntPtr . Zero || ! UnifiedTracking . LipImageData . SupportsImage ) return updateResult ;
325+ if ( lipData . image == IntPtr . Zero || ! UnifiedTracking . LipImageData . SupportsImage )
326+ return true ;
349327
350328 Marshal . Copy ( lipData . image , UnifiedTracking . LipImageData . ImageData , 0 , UnifiedTracking . LipImageData . ImageSize . x *
351329 UnifiedTracking . LipImageData . ImageSize . y ) ;
352330
353- return updateResult ;
331+ return true ;
354332 }
355333
356334 private void UpdateMouthExpressions ( ref UnifiedTrackingData data , PredictionData_v2 external )
0 commit comments