PlugIns/GenericEvents/VR-Applications: AutoQUESTGenericMonitorUnityVRTK.cs

File AutoQUESTGenericMonitorUnityVRTK.cs, 17.9 KB (added by pharms, 7 years ago)
Line 
1using System;
2using System.Collections.Generic;
3using UnityEngine;
4using VRTK;
5
6/**
7 * This class can be used to monitor the usage of an AR/VR which uses the VRTK framework. For this, it
8 * uses the full functionality of the base class by considering further relevant game objects from the
9 * VRTK framework and adding for them additional types of event handling.
10 */
11public class AutoQUESTGenericMonitorUnityVRTK : AutoQUESTGenericMonitorUnity
12{
13    /**
14     * Traverses a hierarchy of game objects and adds game objects relevant for event logging to the given list
15     */
16    override protected void addRelevantGameObjects(GameObject gameObject, LinkedList<UnityEngine.Object> currentRelevantGameObjects)
17    {
18        base.addRelevantGameObjects(gameObject, currentRelevantGameObjects);
19
20        if (gameObject)
21        {
22            Component[] vrtkObjects = gameObject.GetComponentsInChildren(typeof(VRTK_InteractableObject));
23            foreach (Component relevantObject in vrtkObjects)
24            {
25                currentRelevantGameObjects.AddLast(relevantObject);
26            }
27
28            Component[] vrtkControllers = gameObject.GetComponentsInChildren(typeof(VRTK_ControllerEvents));
29            foreach (Component relevantObject in vrtkControllers)
30            {
31                currentRelevantGameObjects.AddLast(relevantObject);
32            }
33        }
34    }
35
36    /**
37     * registers event handling for the given relevant object
38     */
39    override protected void ensureEventHandling(UnityEngine.Object relevantObject)
40    {
41        if (relevantObject is VRTK_InteractableObject)
42        {
43            ensureEventHandling((VRTK_InteractableObject)relevantObject);
44        }
45        else if (relevantObject is VRTK_ControllerEvents)
46        {
47            ensureEventHandling((VRTK_ControllerEvents)relevantObject);
48        }
49        else
50        {
51            base.ensureEventHandling(relevantObject);
52        }
53    }
54
55    /**
56     * registers event handling for the given relevant object
57     */
58    private void ensureEventHandling(VRTK_InteractableObject interactableObject)
59    {
60        VRTKListeners listeners = (VRTKListeners) getListeners(interactableObject.gameObject);
61
62        InteractableObjectEventHandler listener = listeners.getCreateListener("objectTouched", interactableObject);
63        // remove the listener first to ensure, it is not registered twice
64        interactableObject.InteractableObjectTouched -= listener;
65        interactableObject.InteractableObjectTouched += listener;
66
67        listener = listeners.getCreateListener("objectUntouched", interactableObject);
68        // remove the listener first to ensure, it is not registered twice
69        interactableObject.InteractableObjectUntouched -= listener;
70        interactableObject.InteractableObjectUntouched += listener;
71
72        listener = listeners.getCreateListener("objectGrabbed", interactableObject);
73        // remove the listener first to ensure, it is not registered twice
74        interactableObject.InteractableObjectGrabbed -= listener;
75        interactableObject.InteractableObjectGrabbed += listener;
76
77        listener = listeners.getCreateListener("objectUngrabbed", interactableObject);
78        // remove the listener first to ensure, it is not registered twice
79        interactableObject.InteractableObjectUngrabbed -= listener;
80        interactableObject.InteractableObjectUngrabbed += listener;
81
82        listener = listeners.getCreateListener("objectUsed", interactableObject);
83        // remove the listener first to ensure, it is not registered twice
84        interactableObject.InteractableObjectUsed -= listener;
85        interactableObject.InteractableObjectUsed += listener;
86
87        listener = listeners.getCreateListener("objectUnused", interactableObject);
88        // remove the listener first to ensure, it is not registered twice
89        interactableObject.InteractableObjectUnused -= listener;
90        interactableObject.InteractableObjectUnused += listener;
91    }
92
93    /**
94     * registers event handling for the given relevant object
95     */
96    private void ensureEventHandling(VRTK_ControllerEvents controller)
97    {
98        VRTKListeners listeners = (VRTKListeners)getListeners(controller.gameObject);
99
100        ControllerInteractionEventHandler listener = listeners.getCreateListener("triggerPressed", controller);
101        // remove the listener first to ensure, it is not registered twice
102        controller.TriggerPressed -= listener;
103        controller.TriggerPressed += listener;
104
105        listener = listeners.getCreateListener("triggerReleased", controller);
106        // remove the listener first to ensure, it is not registered twice
107        controller.TriggerReleased -= listener;
108        controller.TriggerReleased += listener;
109
110        listener = listeners.getCreateListener("triggerTouchStart", controller);
111        // remove the listener first to ensure, it is not registered twice
112        controller.TriggerTouchStart -= listener;
113        controller.TriggerTouchStart += listener;
114
115        listener = listeners.getCreateListener("triggerTouchEnd", controller);
116        // remove the listener first to ensure, it is not registered twice
117        controller.TriggerTouchEnd -= listener;
118        controller.TriggerTouchEnd += listener;
119
120
121        listener = listeners.getCreateListener("triggerHairlineStart", controller);
122        // remove the listener first to ensure, it is not registered twice
123        controller.TriggerHairlineStart -= listener;
124        controller.TriggerHairlineStart += listener;
125
126        listener = listeners.getCreateListener("triggerHairlineEnd", controller);
127        // remove the listener first to ensure, it is not registered twice
128        controller.TriggerHairlineEnd -= listener;
129        controller.TriggerHairlineEnd += listener;
130
131
132        listener = listeners.getCreateListener("triggerClicked", controller);
133        // remove the listener first to ensure, it is not registered twice
134        controller.TriggerClicked -= listener;
135        controller.TriggerClicked += listener;
136
137        listener = listeners.getCreateListener("triggerUnclicked", controller);
138        // remove the listener first to ensure, it is not registered twice
139        controller.TriggerUnclicked -= listener;
140        controller.TriggerUnclicked += listener;
141
142
143        listener = listeners.getCreateListener("triggerAxisChanged", controller);
144        // remove the listener first to ensure, it is not registered twice
145        controller.TriggerAxisChanged -= listener;
146        controller.TriggerAxisChanged += listener;
147
148
149        listener = listeners.getCreateListener("gripPressed", controller);
150        // remove the listener first to ensure, it is not registered twice
151        controller.GripPressed -= listener;
152        controller.GripPressed += listener;
153
154        listener = listeners.getCreateListener("gripReleased", controller);
155        // remove the listener first to ensure, it is not registered twice
156        controller.GripReleased -= listener;
157        controller.GripReleased += listener;
158
159
160        listener = listeners.getCreateListener("gripTouchStart", controller);
161        // remove the listener first to ensure, it is not registered twice
162        controller.GripTouchStart -= listener;
163        controller.GripTouchStart += listener;
164
165        listener = listeners.getCreateListener("gripTouchEnd", controller);
166        // remove the listener first to ensure, it is not registered twice
167        controller.GripTouchEnd -= listener;
168        controller.GripTouchEnd += listener;
169
170
171        listener = listeners.getCreateListener("gripHairlineStart", controller);
172        // remove the listener first to ensure, it is not registered twice
173        controller.GripHairlineStart -= listener;
174        controller.GripHairlineStart += listener;
175
176        listener = listeners.getCreateListener("gripHairlineEnd", controller);
177        // remove the listener first to ensure, it is not registered twice
178        controller.GripHairlineEnd -= listener;
179        controller.GripHairlineEnd += listener;
180
181
182        listener = listeners.getCreateListener("gripClicked", controller);
183        // remove the listener first to ensure, it is not registered twice
184        controller.GripClicked -= listener;
185        controller.GripClicked += listener;
186
187        listener = listeners.getCreateListener("gripUnclicked", controller);
188        // remove the listener first to ensure, it is not registered twice
189        controller.GripUnclicked -= listener;
190        controller.GripUnclicked += listener;
191
192
193        listener = listeners.getCreateListener("gripAxisChanged", controller);
194        // remove the listener first to ensure, it is not registered twice
195        controller.GripAxisChanged -= listener;
196        controller.GripAxisChanged += listener;
197
198
199        listener = listeners.getCreateListener("touchpadPressed", controller);
200        // remove the listener first to ensure, it is not registered twice
201        controller.TouchpadPressed -= listener;
202        controller.TouchpadPressed += listener;
203
204        listener = listeners.getCreateListener("touchpadReleased", controller);
205        // remove the listener first to ensure, it is not registered twice
206        controller.TouchpadReleased -= listener;
207        controller.TouchpadReleased += listener;
208
209
210        listener = listeners.getCreateListener("touchpadTouchStart", controller);
211        // remove the listener first to ensure, it is not registered twice
212        controller.TouchpadTouchStart -= listener;
213        controller.TouchpadTouchStart += listener;
214
215        listener = listeners.getCreateListener("touchpadTouchEnd", controller);
216        // remove the listener first to ensure, it is not registered twice
217        controller.TouchpadTouchEnd -= listener;
218        controller.TouchpadTouchEnd += listener;
219
220
221        listener = listeners.getCreateListener("touchpadAxisChanged", controller);
222        // remove the listener first to ensure, it is not registered twice
223        controller.TouchpadAxisChanged -= listener;
224        controller.TouchpadAxisChanged += listener;
225
226
227        listener = listeners.getCreateListener("buttonOnePressed", controller);
228        // remove the listener first to ensure, it is not registered twice
229        controller.ButtonOnePressed -= listener;
230        controller.ButtonOnePressed += listener;
231
232        listener = listeners.getCreateListener("buttonOneReleased", controller);
233        // remove the listener first to ensure, it is not registered twice
234        controller.ButtonOneReleased -= listener;
235        controller.ButtonOneReleased += listener;
236
237
238        listener = listeners.getCreateListener("buttonOneTouchStart", controller);
239        // remove the listener first to ensure, it is not registered twice
240        controller.ButtonOneTouchStart -= listener;
241        controller.ButtonOneTouchStart += listener;
242
243        listener = listeners.getCreateListener("buttonOneTouchEnd", controller);
244        // remove the listener first to ensure, it is not registered twice
245        controller.ButtonOneTouchEnd -= listener;
246        controller.ButtonOneTouchEnd += listener;
247
248
249        listener = listeners.getCreateListener("buttonTwoPressed", controller);
250        // remove the listener first to ensure, it is not registered twice
251        controller.ButtonTwoPressed -= listener;
252        controller.ButtonTwoPressed += listener;
253
254        listener = listeners.getCreateListener("buttonTwoReleased", controller);
255        // remove the listener first to ensure, it is not registered twice
256        controller.ButtonTwoReleased -= listener;
257        controller.ButtonTwoReleased += listener;
258
259
260        listener = listeners.getCreateListener("buttonTwoTouchStart", controller);
261        // remove the listener first to ensure, it is not registered twice
262        controller.ButtonTwoTouchStart -= listener;
263        controller.ButtonTwoTouchStart += listener;
264
265        listener = listeners.getCreateListener("buttonTwoTouchEnd", controller);
266        // remove the listener first to ensure, it is not registered twice
267        controller.ButtonTwoTouchEnd -= listener;
268        controller.ButtonTwoTouchEnd += listener;
269
270
271        listener = listeners.getCreateListener("startMenuPressed", controller);
272        // remove the listener first to ensure, it is not registered twice
273        controller.StartMenuPressed -= listener;
274        controller.StartMenuPressed += listener;
275
276        listener = listeners.getCreateListener("startMenuReleased", controller);
277        // remove the listener first to ensure, it is not registered twice
278        controller.StartMenuReleased -= listener;
279        controller.StartMenuReleased += listener;
280
281
282        listener = listeners.getCreateListener("controllerEnabled", controller);
283        // remove the listener first to ensure, it is not registered twice
284        controller.ControllerEnabled -= listener;
285        controller.ControllerEnabled += listener;
286
287        listener = listeners.getCreateListener("controllerDisabled", controller);
288        // remove the listener first to ensure, it is not registered twice
289        controller.ControllerDisabled -= listener;
290        controller.ControllerDisabled += listener;
291
292
293        listener = listeners.getCreateListener("controllerIndexChanged", controller);
294        // remove the listener first to ensure, it is not registered twice
295        controller.ControllerIndexChanged -= listener;
296        controller.ControllerIndexChanged += listener;
297
298    }
299
300    /**
301     * creates a new listeners object supporting VRTK
302     */
303    override protected Listeners createListeners()
304    {
305        return new VRTKListeners(LogEvent);
306    }
307
308    /**
309     * inner structure to use for storing listeners for scene objects
310     */
311    protected class VRTKListeners : AutoQUESTGenericMonitorUnity.Listeners
312    {
313        /**
314         * used to pass the event handling callback method
315         */
316        internal VRTKListeners(EventHandlingCallback callback) : base (callback)
317        {
318            // nothing to do
319        }
320
321        /**
322         * returns a listener for the given event type and updates the internal timestamp. If there is no listener
323         * one will be created and registered.
324         */
325        internal InteractableObjectEventHandler getCreateListener(string eventType, VRTK_InteractableObject eventTarget)
326        {
327            InteractableObjectEventHandler listener = null;
328
329            foreach (KeyValuePair<string, object> candidate in listeners)
330            {
331                if (candidate.Key == eventType)
332                {
333                    listener = (InteractableObjectEventHandler)candidate.Value;
334                    break;
335                }
336            }
337
338            if (listener == null)
339            {
340                listener = delegate (object sender, InteractableObjectEventArgs e)
341                {
342                    callback(eventType, eventTarget.gameObject, new KeyValuePair<string, string>("interactingObject", e.interactingObject.name));
343                };
344
345                addListener(eventType, listener);
346                //Debug.Log("ensuring handling of event " + eventType + " for  " + eventTarget);
347            }
348
349            lastTouched = DateTime.UtcNow.Ticks;
350            return listener;
351        }
352
353        /**
354         * returns a listener for the given event type and updates the internal timestamp. If there is no listener
355         * one will be created and registered.
356         */
357        internal ControllerInteractionEventHandler getCreateListener(string eventType, VRTK_ControllerEvents controller)
358        {
359            ControllerInteractionEventHandler listener = null;
360
361            foreach (KeyValuePair<string, object> candidate in listeners)
362            {
363                if (candidate.Key == eventType)
364                {
365                    listener = (ControllerInteractionEventHandler)candidate.Value;
366                    break;
367                }
368            }
369
370            if (listener == null)
371            {
372                listener = delegate (object sender, ControllerInteractionEventArgs e)
373                {
374                    if (eventType.StartsWith("touchpad"))
375                    {
376                        Vector2 axis = e.touchpadAxis;
377                        roundVector(ref axis);
378
379                        callback(eventType, controller.gameObject,
380                                 new KeyValuePair<string, string>("controller", controller.gameObject.name),
381                                 new KeyValuePair<string, string>("touchpadAngle", Math.Round(e.touchpadAngle, 2).ToString()),
382                                 new KeyValuePair<string, string>("touchpadAxis", "(" + axis.x + ", " + axis.y + ")"));
383                    }
384                    else if (eventType.StartsWith("trigger"))
385                    {
386                        callback(eventType, controller.gameObject,
387                                 new KeyValuePair<string, string>("controller", controller.gameObject.name),
388                                 new KeyValuePair<string, string>("buttonPressure", Math.Round(e.buttonPressure, 2).ToString()));
389                    }
390                    else
391                    {
392                        callback(eventType, controller.gameObject,
393                                 new KeyValuePair<string, string>("controller", controller.gameObject.name));
394                    }
395                };
396
397                addListener(eventType, listener);
398                //Debug.Log("ensuring handling of event " + eventType + " for  " + eventTarget);
399            }
400
401            lastTouched = DateTime.UtcNow.Ticks;
402            return listener;
403        }
404
405        /**
406         * convenience method to round the values of a vector to two decimal positions
407         */
408        private void roundVector(ref Vector2 vector)
409        {
410            vector.x = (float)Math.Round(vector.x, 2);
411            vector.y = (float)Math.Round(vector.y, 2);
412        }
413    }
414
415}