Пример #1
0
        private void AddHeadTrackerEvent(ref List <VREvent> eventList)
        {
            if (Input.GetKey("up"))
            {
                headTrackerPos += 0.1f * Camera.main.transform.forward;
            }
            else if (Input.GetKey("down"))
            {
                headTrackerPos -= 0.1f * Camera.main.transform.forward;
            }
            else if (Input.GetKey("left"))
            {
                headTrackerRot *= Quaternion.AngleAxis(-1.0f, new Vector3(0f, 1f, 0f));
            }
            else if (Input.GetKey("right"))
            {
                headTrackerRot *= Quaternion.AngleAxis(1.0f, new Vector3(0f, 1f, 0f));
            }

            Matrix4x4 m3 = Matrix4x4.TRS(headTrackerPos, headTrackerRot, Vector3.one);

            float[] d3 = VRConvert.ToFloatArray(m3);
            VREvent e  = new VREvent(fakeHeadTrackerEvent);

            e.AddData("EventType", "TrackerMove");
            e.AddData("Transform", d3);
            eventList.Add(e);
        }
Пример #2
0
        void OnVREvent(VREvent e)
        {
            // only respond to tracker move events
            if ((e.ContainsStringField("EventType")) &&
                (e.GetStringData("EventType") == "TrackerMove"))
            {
                string trackerName = e.Name.Remove(e.Name.IndexOf("_Move"), 5);
                if (!trackersToIgnore.Contains(trackerName))
                {
                    float[]    data = e.GetFloatArrayData("Transform");
                    Matrix4x4  m    = VRConvert.ToMatrix4x4(data);
                    Vector3    pos  = m.GetTranslation();
                    Quaternion rot  = m.GetRotation();

                    if (!cursors.ContainsKey(trackerName))
                    {
                        GameObject newCursorObj = Instantiate(cursorPrefab);
                        TextMesh   label        = newCursorObj.GetComponentInChildren <TextMesh>();
                        if (label != null)
                        {
                            label.text = trackerName;
                        }
                        cursors[trackerName] = newCursorObj;
                    }
                    GameObject cursorObj = cursors[trackerName];
                    cursorObj.transform.position = pos;
                    cursorObj.transform.rotation = rot;
                }
            }
        }
Пример #3
0
        // Update is called once per frame
        void Update()
        {
            if (threadingMode == ThreadingMode.SINGLE_THREADED)
            {
                // update the trackers only once per frame
                if (lastTrackerUpdateFrame != Time.frameCount)
                {
                    UpdateTrackers();
                    lastTrackerUpdateFrame = Time.frameCount;
                }

                trackerData = (TrackerData)Marshal.PtrToStructure(trackerDataPointer, typeof(TrackerData));
            }
            else
            {
                // update the trackers only once per frame
                if (lastTrackerUpdateFrame != Time.frameCount)
                {
                    UpdateTrackersMultiThreaded();
                    lastTrackerUpdateFrame = Time.frameCount;
                }

                LockTrackerData(trackerDataPointer);
                trackerData = (TrackerData)Marshal.PtrToStructure(trackerDataPointer, typeof(TrackerData));
                UnlockTrackerData(trackerDataPointer);
            }

            Vector3 transformPosition = transform.position;
            Quaternion transformRotation = transform.rotation;

            this.updateTransformFromTrackerData(ref transformPosition, ref transformRotation);

            // if a custom origin has been specified
            // then update the transform coordinate space
            if (origin != null)
            {
                if (trackingMode != TrackingMode.POSITION_ONLY)
                    transformRotation = origin.rotation * transformRotation;
                else
                    transformRotation = origin.rotation;

                if (trackingMode != TrackingMode.ORIENTATION_ONLY)
                    transformPosition = origin.position + origin.rotation * transformPosition;
                else
                    transformPosition = origin.position;
            }

            Matrix4x4 m3 = Matrix4x4.TRS(transformPosition, transformRotation, Vector3.one);
            float[] d3 = VRConvert.ToFloatArray(m3);
            VREvent e = new VREvent(eventName);
            e.AddData("EventType", "TrackerMove");
            e.AddData("Transform", d3);
            pendingEvents.Add(e);

            if (applyUpdatesToGameObject)
            {
                transform.position = transformPosition;
                transform.rotation = transformRotation;
            }
        }
Пример #4
0
        private void AddHeadTrackerEvent(ref List <VREvent> eventList)
        {
            // if (Input.GetKey(KeyCode.LeftShift))
            // {
            //     if (Input.GetKey(KeyCode.DownArrow))
            //     {
            //         headTrackerRot *= Quaternion.AngleAxis(-1.0f, new Vector3(1f, 0f, 0f));
            //     }
            //     else if (Input.GetKey(KeyCode.UpArrow))
            //     {
            //         headTrackerRot *= Quaternion.AngleAxis(1.0f, new Vector3(1f, 0f, 0f));
            //     }
            // }
            // else
            if (Input.GetKey(KeyCode.UpArrow))
            {
                headTrackerPos += 0.1f * Camera.main.transform.forward;
            }
            else if (Input.GetKey(KeyCode.DownArrow))
            {
                headTrackerPos -= 0.1f * Camera.main.transform.forward;
            }
            else if (Input.GetKey(KeyCode.LeftArrow))
            {
                headTrackerRot *= Quaternion.AngleAxis(-1.0f, new Vector3(0f, 1f, 0f));
            }
            else if (Input.GetKey(KeyCode.RightArrow))
            {
                headTrackerRot *= Quaternion.AngleAxis(1.0f, new Vector3(0f, 1f, 0f));
            }

            headTrackerRot.Normalize();

            Matrix4x4 m3 = Matrix4x4.TRS(headTrackerPos, headTrackerRot, Vector3.one);

            float[] d3 = VRConvert.ToFloatArray(m3);
            VREvent e  = new VREvent(fakeHeadTrackerEvent);

            e.AddData("EventType", "TrackerMove");
            e.AddData("Transform", d3);
            eventList.Add(e);
        }
Пример #5
0
        private void ProcessCallbacks(VREvent e)
        {
            // These "unfiltered" callbacks are called for every event
            for (int ucb = 0; ucb < genericCallbacksUnfiltered.Count; ucb++)
            {
                genericCallbacksUnfiltered[ucb].Invoke(e);
            }


            // These callbacks are passed the enitre event data structure, which can really contain anything.
            if (genericCallbacks.ContainsKey(e.Name))
            {
                for (int cb = 0; cb < genericCallbacks[e.Name].Count; cb++)
                {
                    genericCallbacks[e.Name][cb].Invoke(e);
                }
            }


            // For these callbacks, we know the type of data, so we pull it out of the dataindex here to
            // make it a bit easier for the user.

            if ((analogCallbacks.ContainsKey(e.Name)) &&
                (e.ContainsStringField("EventType")) &&
                (e.GetStringData("EventType") == "AnalogUpdate"))
            {
                for (int cb = 0; cb < analogCallbacks[e.Name].Count; cb++)
                {
                    analogCallbacks[e.Name][cb].Invoke(e.GetFloatData("AnalogValue"));
                }
            }

            if ((buttonDownCallbacks.ContainsKey(e.Name)) &&
                (e.ContainsStringField("EventType")) &&
                ((e.GetStringData("EventType") == "ButtonDown") || (e.GetStringData("EventType") == "ButtonTouch")))
            {
                for (int cb = 0; cb < buttonDownCallbacks[e.Name].Count; cb++)
                {
                    buttonDownCallbacks[e.Name][cb].Invoke();
                }
            }

            if ((buttonUpCallbacks.ContainsKey(e.Name)) &&
                (e.ContainsStringField("EventType")) &&
                ((e.GetStringData("EventType") == "ButtonUp") || (e.GetStringData("EventType") == "ButtonUntouch")))
            {
                for (int cb = 0; cb < buttonUpCallbacks[e.Name].Count; cb++)
                {
                    buttonUpCallbacks[e.Name][cb].Invoke();
                }
            }

            if ((cursorCallbacks.ContainsKey(e.Name)) &&
                (e.ContainsStringField("EventType")) &&
                (e.GetStringData("EventType") == "CursorMove"))
            {
                float[] pos  = e.GetFloatArrayData("Position");
                float[] npos = e.GetFloatArrayData("NormalizedPosition");
                for (int cb = 0; cb < cursorCallbacks[e.Name].Count; cb++)
                {
                    cursorCallbacks[e.Name][cb].Invoke(new Vector3(pos[0], pos[1], pos[2]), new Vector3(npos[0], npos[1], npos[2]));
                }
            }

            if ((trackerCallbacks.ContainsKey(e.Name)) &&
                (e.ContainsStringField("EventType")) &&
                (e.GetStringData("EventType") == "TrackerMove"))
            {
                float[]    data = e.GetFloatArrayData("Transform");
                Matrix4x4  m    = VRConvert.ToMatrix4x4(data);
                Vector3    pos  = m.GetTranslation();
                Quaternion rot  = m.GetRotation();
                for (int cb = 0; cb < trackerCallbacks[e.Name].Count; cb++)
                {
                    trackerCallbacks[e.Name][cb].Invoke(pos, rot);
                }
            }
        }
Пример #6
0
        public void AddUnityInputEvents(ref List <VREvent> eventList)
        {
            // Convery Unity Mouse Button events to VREvent ButtonUp/Down events
            if (vrDevice.unityMouseBtnsToVREvents)
            {
                if (Input.GetMouseButtonDown(0))
                {
                    VREvent e = new VREvent("MouseBtnLeft_Down");
                    e.AddData("EventType", "ButtonDown");
                    eventList.Add(e);
                }
                if (Input.GetMouseButtonDown(2))
                {
                    VREvent e = new VREvent("MouseBtnMiddle_Down");
                    e.AddData("EventType", "ButtonDown");
                    eventList.Add(e);
                }
                if (Input.GetMouseButtonDown(1))
                {
                    VREvent e = new VREvent("MouseBtnRight_Down");
                    e.AddData("EventType", "ButtonDown");
                    eventList.Add(e);
                }
                if (Input.GetMouseButtonUp(0))
                {
                    VREvent e = new VREvent("MouseBtnLeft_Up");
                    e.AddData("EventType", "ButtonUp");
                    eventList.Add(e);
                }
                if (Input.GetMouseButtonUp(2))
                {
                    VREvent e = new VREvent("MouseBtnMiddle_Up");
                    e.AddData("EventType", "ButtonUp");
                    eventList.Add(e);
                }
                if (Input.GetMouseButtonUp(1))
                {
                    VREvent e = new VREvent("MouseBtnRight_Up");
                    e.AddData("EventType", "ButtonUp");
                    eventList.Add(e);
                }
            }


            // Convert Unity mouse move events to VREvent Cursor events
            if (vrDevice.unityMouseMovesToVREvents)
            {
                Vector3 pos = Input.mousePosition;
                if (pos != lastMousePos)
                {
                    Vector3 npos = new Vector3(pos[0] / Screen.width, pos[1] / Screen.height, 0.0f);
                    VREvent e    = new VREvent("Mouse_Move");
                    e.AddData("EventType", "CursorMove");
                    e.AddData("Position", VRConvert.ToFloatArray(pos));
                    e.AddData("NormalizedPosition", VRConvert.ToFloatArray(npos));
                    eventList.Add(e);
                    lastMousePos = pos;
                }
            }


            // Convert Unity key up/down events to VREvent ButtonUp/Down events
            for (int i = 0; i < vrDevice.unityKeysToVREvents.Count; i++)
            {
                if (Input.GetKeyDown(vrDevice.unityKeysToVREvents[i]))
                {
                    VREvent e = new VREvent("Kbd" + vrDevice.unityKeysToVREvents[i] + "_Down");
                    e.AddData("EventType", "ButtonDown");
                    eventList.Add(e);
                }
                if (Input.GetKeyDown(vrDevice.unityKeysToVREvents[i]))
                {
                    VREvent e = new VREvent("Kbd" + vrDevice.unityKeysToVREvents[i] + "_Up");
                    e.AddData("EventType", "ButtonUp");
                    eventList.Add(e);
                }
            }

            // Convert Unity Axis values to VREvent AnalogUpdate events
            for (int i = 0; i < vrDevice.unityAxesToVREvents.Count; i++)
            {
                float current = Input.GetAxis(vrDevice.unityAxesToVREvents[i]);
                bool  update  = false;
                if (axesStates.ContainsKey(vrDevice.unityAxesToVREvents[i]))
                {
                    float last = axesStates[vrDevice.unityAxesToVREvents[i]];
                    if (current != last)
                    {
                        axesStates[vrDevice.unityAxesToVREvents[i]] = current;
                        update = true;
                    }
                }
                else
                {
                    axesStates.Add(vrDevice.unityAxesToVREvents[i], current);
                    update = true;
                }
                if (update)
                {
                    VREvent e = new VREvent(vrDevice.unityAxesToVREvents[i] + "_Update");
                    e.AddData("EventType", "AnalogUpdate");
                    e.AddData("AnalogValue", current);
                    eventList.Add(e);
                }
            }


            // TODO: Convert other Unity inputs as needed (touch, accelerometer, etc.)
        }
Пример #7
0
        // AT THE START OF EACH FRAME: SYNCHRONIZE INPUT EVENTS AND CALL ONVREVENT CALLBACK FUNCTIONS
        void PreUpdate()
        {
            // TODO: Add input events generated in Unity to the list of inputEvents to sync them across all clients

            /*
             * int brushType = 1;
             * VRDataIndex myEventData = new VRDataIndex();
             * myEventData.AddData("BrushType", brushType);
             * VRMain.AddInputEvent(new VREvent("BrushTypeChange", myEventData));
             */

            /*
             * foreach (var item in clientEvents) {
             *      inputEvents.Add (item);
             *      clientEvents.Clear ();
             * }*/

            if (fakeTrackersForDebugging)
            {
                float x = Input.mousePosition.x;
                float y = Input.mousePosition.y;
                // first time through
                if (lastx == -9999)
                {
                    lastx = x;
                    lasty = y;
                    return;
                }

                if (Input.GetKeyDown("1"))
                {
                    curTracker = 0;
                }
                else if (Input.GetKeyDown("2"))
                {
                    curTracker = 1;
                }

                if (Input.GetKey("x"))
                {
                    float angle = 0.1f * (x - lastx);
                    if (curTracker == 0)
                    {
                        tracker1Rot = Quaternion.AngleAxis(angle, new Vector3(1f, 0f, 0f)) * tracker1Rot;
                    }
                    else if (curTracker == 1)
                    {
                        tracker2Rot = Quaternion.AngleAxis(angle, new Vector3(1f, 0f, 0f)) * tracker2Rot;
                    }
                }
                else if (Input.GetKey("y"))
                {
                    float angle = 0.1f * (x - lastx);
                    if (curTracker == 0)
                    {
                        tracker1Rot = Quaternion.AngleAxis(angle, new Vector3(0f, 1f, 0f)) * tracker1Rot;
                    }
                    else if (curTracker == 1)
                    {
                        tracker2Rot = Quaternion.AngleAxis(angle, new Vector3(0f, 1f, 0f)) * tracker2Rot;
                    }
                }
                else if (Input.GetKey("z"))
                {
                    float angle = 0.1f * (x - lastx);
                    if (curTracker == 0)
                    {
                        tracker1Rot = Quaternion.AngleAxis(angle, new Vector3(0f, 0f, 1f)) * tracker1Rot;
                    }
                    else if (curTracker == 1)
                    {
                        tracker2Rot = Quaternion.AngleAxis(angle, new Vector3(0f, 0f, 1f)) * tracker2Rot;
                    }
                }
                else if (Input.GetKey("left shift"))
                {
                    float depth = 0.005f * (y - lasty);
                    if (curTracker == 0)
                    {
                        tracker1Pos += depth * Camera.main.transform.forward;
                    }
                    else if (curTracker == 1)
                    {
                        tracker2Pos += depth * Camera.main.transform.forward;
                    }
                }
                else
                {
                    Ray   ray  = Camera.main.ScreenPointToRay(new Vector3(x, y, 0f));
                    Plane p    = new Plane();
                    float dist = 0.0f;
                    if (curTracker == 0)
                    {
                        p.SetNormalAndPosition(-Camera.main.transform.forward, tracker1Pos);
                        if (p.Raycast(ray, out dist))
                        {
                            tracker1Pos = ray.GetPoint(dist);
                        }
                    }
                    else if (curTracker == 1)
                    {
                        p.SetNormalAndPosition(-Camera.main.transform.forward, tracker2Pos);
                        if (p.Raycast(ray, out dist))
                        {
                            tracker2Pos = ray.GetPoint(dist);
                        }
                    }
                }

                Matrix4x4   m1    = Matrix4x4.TRS(tracker1Pos, tracker1Rot, Vector3.one);
                double[]    d1    = VRConvert.ToDoubleArray(m1);
                VRDataIndex data1 = new VRDataIndex();
                data1.AddData("Transform", d1);
                inputEvents.Add(new VREvent(fakeTracker1Event, data1));
                Matrix4x4   m2    = Matrix4x4.TRS(tracker2Pos, tracker2Rot, Vector3.one);
                double[]    d2    = VRConvert.ToDoubleArray(m2);
                VRDataIndex data2 = new VRDataIndex();
                data2.AddData("Transform", d2);
                inputEvents.Add(new VREvent(fakeTracker2Event, data2));
                lastx = x;
                lasty = y;
            }
            if (fakeHeadTracking)
            {
                if (Input.GetKey("up"))
                {
                    headTrackerPos += 0.1f * Camera.main.transform.forward;
                }
                else if (Input.GetKey("down"))
                {
                    headTrackerPos -= 0.1f * Camera.main.transform.forward;
                }
                else if (Input.GetKey("left"))
                {
                    headTrackerRot *= Quaternion.AngleAxis(-1.0f, new Vector3(0f, 1f, 0f));
                }
                else if (Input.GetKey("right"))
                {
                    headTrackerRot *= Quaternion.AngleAxis(1.0f, new Vector3(0f, 1f, 0f));
                }
                Matrix4x4   m3    = Matrix4x4.TRS(headTrackerPos, headTrackerRot, Vector3.one);
                double[]    d3    = VRConvert.ToDoubleArray(m3);
                VRDataIndex data3 = new VRDataIndex();
                data3.AddData("Transform", d3);
                inputEvents.Add(new VREvent(fakeHeadTrackerEvent, data3));
            }
            // ----- END FAKE TRACKER INPUT -----


            // Synchronize with the server
            if (_netClient != null)
            {
                _netClient.SynchronizeInputEventsAcrossAllNodes(ref inputEvents);
            }

            // Call any event callback functions that have been registered with the VREventHandler
            for (int i = 0; i < inputEvents.Count; i++)
            {
                if (VREventHandler != null)
                {
                    VREventHandler(inputEvents [i]);
                }
            }
            _state = NetState.PostRenderNext;
        }
Пример #8
0
        private void AddTrackerEvents(ref List <VREvent> eventList)
        {
            float x = Input.mousePosition.x;
            float y = Input.mousePosition.y;

            // first time through
            if (float.IsNaN(lastx))
            {
                lastx = x;
                lasty = y;
                return;
            }

            if (Input.GetKeyDown("1"))
            {
                curTracker = 0;
            }
            else if (Input.GetKeyDown("2"))
            {
                curTracker = 1;
            }

            if (Input.GetKey("x"))
            {
                float angle = 0.1f * (x - lastx);
                if (curTracker == 0)
                {
                    tracker1Rot = Quaternion.AngleAxis(angle, new Vector3(1f, 0f, 0f)) * tracker1Rot;
                }
                else if (curTracker == 1)
                {
                    tracker2Rot = Quaternion.AngleAxis(angle, new Vector3(1f, 0f, 0f)) * tracker2Rot;
                }
            }
            else if (Input.GetKey("y"))
            {
                float angle = 0.1f * (x - lastx);
                if (curTracker == 0)
                {
                    tracker1Rot = Quaternion.AngleAxis(angle, new Vector3(0f, 1f, 0f)) * tracker1Rot;
                }
                else if (curTracker == 1)
                {
                    tracker2Rot = Quaternion.AngleAxis(angle, new Vector3(0f, 1f, 0f)) * tracker2Rot;
                }
            }
            else if (Input.GetKey("z"))
            {
                float angle = 0.1f * (x - lastx);
                if (curTracker == 0)
                {
                    tracker1Rot = Quaternion.AngleAxis(angle, new Vector3(0f, 0f, 1f)) * tracker1Rot;
                }
                else if (curTracker == 1)
                {
                    tracker2Rot = Quaternion.AngleAxis(angle, new Vector3(0f, 0f, 1f)) * tracker2Rot;
                }
            }
            else if (Input.GetKey("left shift"))
            {
                float depth = 0.005f * (y - lasty);
                if (curTracker == 0)
                {
                    tracker1Pos += depth * Camera.main.transform.forward;
                }
                else if (curTracker == 1)
                {
                    tracker2Pos += depth * Camera.main.transform.forward;
                }
            }
            else
            {
                Ray   ray  = Camera.main.ScreenPointToRay(new Vector3(x, y, 0f));
                Plane p    = new Plane();
                float dist = 0.0f;
                if (curTracker == 0)
                {
                    p.SetNormalAndPosition(-Camera.main.transform.forward, tracker1Pos);
                    if (p.Raycast(ray, out dist))
                    {
                        tracker1Pos = ray.GetPoint(dist);
                    }
                }
                else if (curTracker == 1)
                {
                    p.SetNormalAndPosition(-Camera.main.transform.forward, tracker2Pos);
                    if (p.Raycast(ray, out dist))
                    {
                        tracker2Pos = ray.GetPoint(dist);
                    }
                }
            }

            // for fake traker 1
            Matrix4x4 m1 = Matrix4x4.TRS(tracker1Pos, tracker1Rot, Vector3.one);

            float[] d1 = VRConvert.ToFloatArray(m1);
            VREvent e1 = new VREvent(fakeTracker1Event);

            e1.AddData("EventType", "TrackerMove");
            e1.AddData("Transform", d1);
            eventList.Add(e1);

            // for fake traker 2
            Matrix4x4 m2 = Matrix4x4.TRS(tracker2Pos, tracker2Rot, Vector3.one);

            float[] d2 = VRConvert.ToFloatArray(m2);
            VREvent e2 = new VREvent(fakeTracker2Event);

            e2.AddData("EventType", "TrackerMove");
            e2.AddData("Transform", d2);
            eventList.Add(e2);

            //
            this.lastx = x;
            this.lasty = y;
        }
        void OnVREvent(VREvent e)
        {
            if (e.Name == user1HeadTrackingEvent)
            {
                Matrix4x4 m = VRConvert.ToMatrix4x4(e.DataIndex.GetValueAsDoubleArray(matrix4x4DataField));

                if (user_id == 1)
                {
                    transform.position = m.GetTranslation();
                    transform.rotation = m.GetRotation();
                }
                //Debug.Log("Head Position = " + m.GetTranslation().ToString());
                //Debug.Log("Head Rotation = " + m.GetRotation().ToString());

                //------------------ Avatar 1 movement ------------------------
                // position
                Vector3 pos = m.GetTranslation();
                user1Avatar.transform.position = new Vector3(pos.x, user1Avatar.transform.position.y, pos.z);


                // rotation
                Quaternion rot = m.GetRotation();
                // 3rd column of a rotation matrix is the z-axis
                Vector3 z = new Vector3(m.GetColumn(2).x, m.GetColumn(2).y, m.GetColumn(2).z);
                // z-axis of the tracker projected onto a horizontal plane
                Vector3 zHorizontal = (z - Vector3.Dot(z, Vector3.up) * Vector3.up).normalized;

                // align the z axis of the avatar with zHorizontal
                Quaternion newRot = Quaternion.FromToRotation(new Vector3(0, 0, 1), zHorizontal);
                user1Avatar.transform.rotation = newRot;

                //------------------ Menu movement ------------------------
                if (user_id == 1)
                {
                    /*
                     * GameObject terrain = GameObject.Find ("Terrain");
                     * MenuContainer.transform.position = new Vector3 (pos.x, terrain.transform.position.y, pos.z);
                     * MenuContainer.transform.rotation = newRot;
                     */

                    Text hPos = GameObject.Find("MinVRUnityClient/VRCameraPair/HeadPosition").GetComponent <Text> ();
                    Text mPos = GameObject.Find("MinVRUnityClient/VRCameraPair/MenuPosition").GetComponent <Text> ();
                    Text bPos = GameObject.Find("MinVRUnityClient/VRCameraPair/BrushPosition").GetComponent <Text> ();

                    //MenuContainer.transform.position = new Vector3 (pos.x, pos.y - 50, pos.z);
                    //MenuContainer.transform.rotation = newRot;

                    hPos.text = "H pos: " + pos.ToString();
                    mPos.text = "m Pos: " + MenuContainer.transform.position.ToString();
                    bPos.text = "b Pos: " + brush1.transform.position.ToString();
                }
            }
            else if (e.Name == user2HeadTrackingEvent)
            {
                Matrix4x4 m = VRConvert.ToMatrix4x4(e.DataIndex.GetValueAsDoubleArray(matrix4x4DataField));

                if (user_id == 2)
                {
                    transform.position = m.GetTranslation();
                    transform.rotation = m.GetRotation();
                }
                //Debug.Log("Head Position = " + m.GetTranslation().ToString());
                //Debug.Log("Head Rotation = " + m.GetRotation().ToString());

                //------------------ Avatar 2 movement ------------------------
                // position
                Vector3 pos = m.GetTranslation();
                user2Avatar.transform.position = new Vector3(pos.x, user2Avatar.transform.position.y, pos.z);

                // rotation
                Quaternion rot = m.GetRotation();
                // 3rd column of a rotation matrix is the z-axis
                Vector3 z = new Vector3(m.GetColumn(2).x, m.GetColumn(2).y, m.GetColumn(2).z);
                // z-axis of the tracker projected onto a horizontal plane
                Vector3 zHorizontal = (z - Vector3.Dot(z, Vector3.up) * Vector3.up).normalized;

                // align the z axis of the avatar with zHorizontal
                Quaternion newRot = Quaternion.FromToRotation(new Vector3(0, 0, 1), zHorizontal);
                user2Avatar.transform.rotation = newRot;

                //------------------ Menu movement ------------------------
                if (user_id == 2)
                {
                    Text hPos = GameObject.Find("MinVRUnityClient/VRCameraPair/HeadPosition").GetComponent <Text> ();
                    Text mPos = GameObject.Find("MinVRUnityClient/VRCameraPair/MenuPosition").GetComponent <Text> ();
                    Text bPos = GameObject.Find("MinVRUnityClient/VRCameraPair/BrushPosition").GetComponent <Text> ();

                    //MenuContainer.transform.position = new Vector3 (pos.x, pos.y - 50, pos.z);
                    //MenuContainer.transform.rotation = newRot;

                    hPos.text = "H pos: " + pos.ToString();
                    mPos.text = "m Pos: " + MenuContainer.transform.position.ToString();
                    bPos.text = "b Pos: " + brush2.transform.position.ToString();
                }
            }
        }