1+ using System . IO . Pipes ;
2+ using System . Runtime . InteropServices ;
3+
4+ /*
5+ * library created by Rin.
6+ * discord: Riɳ#0001
7+ *
8+ * This library is for interacting with the openGloves driver.
9+ * More specifically, it is designed to send glove inputs via named pipes to control the buttons, fingers, and other inputs.
10+ *
11+ * written in c# for those like me who are scared of c++
12+ *
13+ * --------------------Thanks To--------------------
14+ *
15+ * danwillm - He helped a ton with formatting the InputData struct.
16+ * I couldn't have done this without him so huge thanks.
17+ *
18+ * L4rs - This library took heavy inspiration from his c# library for sending force feedback inputs to the glove via named pipes. I would have been very lost without him.
19+ * https://github.com/Hydr4bytes/OpenGlovesLib - his library linked here.
20+ *
21+ * -------------------------------------------------
22+ */
23+
24+ namespace GloveInputLib
25+ {
26+ //Struct InputData is a struct that contains all of the button, finger, and linear inputs. This is what's sent to the driver via the named pipe.
27+ [ StructLayout ( LayoutKind . Sequential ) ]
28+ public unsafe struct InputData
29+ {
30+ [ MarshalAs ( UnmanagedType . ByValArray , SizeConst = 20 ) ]
31+ public float [ ] flexion ; //range: 0 -> 1
32+ [ MarshalAs ( UnmanagedType . ByValArray , SizeConst = 5 ) ]
33+ public float [ ] splay ; //range: -1 -> 1
34+ public float joyX ; //range: -1 -> 1
35+ public float joyY ; //range: -1 -> 1
36+ [ MarshalAs ( UnmanagedType . I1 ) ]
37+ public bool joyButton ;
38+ [ MarshalAs ( UnmanagedType . I1 ) ]
39+ public bool trgButton ;
40+ [ MarshalAs ( UnmanagedType . I1 ) ]
41+ public bool aButton ;
42+ [ MarshalAs ( UnmanagedType . I1 ) ]
43+ public bool bButton ;
44+ [ MarshalAs ( UnmanagedType . I1 ) ]
45+ public bool grab ;
46+ [ MarshalAs ( UnmanagedType . I1 ) ]
47+ public bool pinch ;
48+ [ MarshalAs ( UnmanagedType . I1 ) ]
49+ public bool menu ;
50+ [ MarshalAs ( UnmanagedType . I1 ) ]
51+ public bool calibrate ;
52+ public float trgValue ; //range: 0 -> 1
53+
54+ //constructor that uses a 1d array for flexion.
55+ public InputData ( float [ ] flexion , float [ ] splay , float joyX , float joyY , bool joyButton , bool trgButton , bool aButton , bool bButton , bool grab , bool pinch , bool menu , bool calibrate , float trgValue )
56+ {
57+ this . flexion = flexion ;
58+ this . splay = splay ;
59+ this . joyX = joyX ;
60+ this . joyY = joyY ;
61+ this . joyButton = joyButton ;
62+ this . trgButton = trgButton ;
63+ this . aButton = aButton ;
64+ this . bButton = bButton ;
65+ this . grab = grab ;
66+ this . pinch = pinch ;
67+ this . menu = menu ;
68+ this . calibrate = calibrate ;
69+ this . trgValue = trgValue ;
70+ }
71+
72+ //this constructor is for if you want to instead use a 2d array for the flexion. it's an array of 5 arrays of 4 floats. (float[5,4] flexion). each finger is represented by an array. each float in the array represents a joint.
73+ public InputData ( float [ , ] flexion , float [ ] splay , float joyX , float joyY , bool joyButton , bool trgButton , bool aButton , bool bButton , bool grab , bool pinch , bool menu , bool calibrate , float trgValue )
74+ {
75+ this . flexion = new float [ 20 ] ;
76+ //nested for loops to turn the 2d array to a 1d array.
77+ int flexIndex = 0 ;
78+ for ( int finger = 0 ; finger < 5 ; finger ++ )
79+ {
80+ for ( int joint = 0 ; joint < 4 ; joint ++ )
81+ {
82+ this . flexion [ flexIndex ++ ] = flexion [ finger , joint ] ;
83+ }
84+ }
85+ this . splay = splay ;
86+ this . joyX = joyX ;
87+ this . joyY = joyY ;
88+ this . joyButton = joyButton ;
89+ this . trgButton = trgButton ;
90+ this . aButton = aButton ;
91+ this . bButton = bButton ;
92+ this . grab = grab ;
93+ this . pinch = pinch ;
94+ this . menu = menu ;
95+ this . calibrate = calibrate ;
96+ this . trgValue = trgValue ;
97+ }
98+
99+ //default constructor that sets all booleon values to false and all float values to 0.
100+ public InputData ( )
101+ {
102+ flexion = new float [ 20 ] { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
103+ splay = new float [ 5 ] { 0 , 0 , 0 , 0 , 0 } ;
104+ joyX = 0 ;
105+ joyY = 0 ;
106+ joyButton = false ;
107+ trgButton = false ;
108+ aButton = false ;
109+ bButton = false ;
110+ grab = false ;
111+ pinch = false ;
112+ menu = false ;
113+ calibrate = false ;
114+ trgValue = 0 ;
115+ }
116+ }
117+
118+
119+ //The GloveInputLink class is used for actually sending inputs to
120+ public class GloveInputLink
121+ {
122+ private NamedPipeClientStream pipe ;
123+
124+ //Handness is an enum used to pass what hand the GloveInputLink object will write to
125+ public enum Handness
126+ {
127+ Left ,
128+ Right
129+ }
130+
131+ //Constructor. takes handness parameter to tell it to write to specific hand.
132+ public GloveInputLink ( Handness handness )
133+ {
134+ string hand = handness == Handness . Right ? "right" : "left" ;
135+ pipe = new NamedPipeClientStream ( "." , $ "vrapplication\\ input\\ glove\\ v2\\ { hand } ", PipeDirection . Out ) ;
136+ //connect to the pipe
137+ Console . WriteLine ( $ "Connecting to { hand } hand pipe...") ;
138+ try
139+ {
140+ //try to connect to the pipe, timeout after 5 seconds
141+ pipe . Connect ( 5000 ) ;
142+ }
143+ catch ( Exception e )
144+ {
145+ //if an error is thrown log the message
146+ Console . WriteLine ( e . Message ) ;
147+ }
148+ if ( pipe . IsConnected )
149+ Console . WriteLine ( $ "Connected! CanWrite:{ pipe . CanWrite } ") ;
150+ else
151+ Console . WriteLine ( "Connection failed" ) ;
152+ }
153+
154+ //set all input values to default.
155+ public void Relax ( )
156+ {
157+ Write ( new InputData ( ) ) ;
158+ }
159+
160+ //send values to the driver.
161+ public void Write ( InputData input )
162+ {
163+ if ( ! pipe . IsConnected ) return ;
164+
165+ int size = Marshal . SizeOf ( input ) ;
166+ //Console.WriteLine(size);
167+ byte [ ] arr = new byte [ size ] ;
168+
169+ IntPtr ptr = Marshal . AllocHGlobal ( size ) ;
170+ Marshal . StructureToPtr ( input , ptr , true ) ;
171+ Marshal . Copy ( ptr , arr , 0 , size ) ;
172+ Marshal . FreeHGlobal ( ptr ) ;
173+
174+ pipe . Write ( arr , 0 , size ) ;
175+ }
176+ }
177+ }
0 commit comments