AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
RemoteHeadManager.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License. See LICENSE in the project root for license information.
3 
4 using System;
5 using System.Collections.Generic;
6 using UnityEngine;
7 using HoloToolkit.Unity;
8 
9 namespace HoloToolkit.Sharing.Tests
10 {
16  public class RemoteHeadManager : Singleton<RemoteHeadManager>
17  {
18  public class RemoteHeadInfo
19  {
20  public long UserID;
21  public GameObject HeadObject;
22  }
23 
27  private Dictionary<long, RemoteHeadInfo> remoteHeads = new Dictionary<long, RemoteHeadInfo>();
28 
29  private void Start()
30  {
31  CustomMessages.Instance.MessageHandlers[CustomMessages.TestMessageID.HeadTransform] = UpdateHeadTransform;
32 
33  // SharingStage should be valid at this point, but we may not be connected.
34  if (SharingStage.Instance.IsConnected)
35  {
36  Connected();
37  }
38  else
39  {
40  SharingStage.Instance.SharingManagerConnected += Connected;
41  }
42  }
43 
44  private void Connected(object sender = null, EventArgs e = null)
45  {
46  SharingStage.Instance.SharingManagerConnected -= Connected;
47 
48  SharingStage.Instance.SessionUsersTracker.UserJoined += UserJoinedSession;
49  SharingStage.Instance.SessionUsersTracker.UserLeft += UserLeftSession;
50  }
51 
52  private void Update()
53  {
54  // Grab the current head transform and broadcast it to all the other users in the session
55  Transform headTransform = CameraCache.Main.transform;
56 
57  // Transform the head position and rotation from world space into local space
58  Vector3 headPosition = transform.InverseTransformPoint(headTransform.position);
59  Quaternion headRotation = Quaternion.Inverse(transform.rotation) * headTransform.rotation;
60 
61  CustomMessages.Instance.SendHeadTransform(headPosition, headRotation);
62  }
63 
64  protected override void OnDestroy()
65  {
66  if (SharingStage.Instance != null)
67  {
68  if (SharingStage.Instance.SessionUsersTracker != null)
69  {
70  SharingStage.Instance.SessionUsersTracker.UserJoined -= UserJoinedSession;
71  SharingStage.Instance.SessionUsersTracker.UserLeft -= UserLeftSession;
72  }
73  }
74 
75  base.OnDestroy();
76  }
77 
82  private void UserLeftSession(User user)
83  {
84  int userId = user.GetID();
85  if (userId != SharingStage.Instance.Manager.GetLocalUser().GetID())
86  {
87  RemoveRemoteHead(remoteHeads[userId].HeadObject);
88  remoteHeads.Remove(userId);
89  }
90  }
91 
96  private void UserJoinedSession(User user)
97  {
98  if (user.GetID() != SharingStage.Instance.Manager.GetLocalUser().GetID())
99  {
100  GetRemoteHeadInfo(user.GetID());
101  }
102  }
103 
109  public RemoteHeadInfo GetRemoteHeadInfo(long userId)
110  {
111  RemoteHeadInfo headInfo;
112 
113  // Get the head info if its already in the list, otherwise add it
114  if (!remoteHeads.TryGetValue(userId, out headInfo))
115  {
116  headInfo = new RemoteHeadInfo();
117  headInfo.UserID = userId;
118  headInfo.HeadObject = CreateRemoteHead();
119 
120  remoteHeads.Add(userId, headInfo);
121  }
122 
123  return headInfo;
124  }
125 
130  private void UpdateHeadTransform(NetworkInMessage msg)
131  {
132  // Parse the message
133  long userID = msg.ReadInt64();
134 
135  Vector3 headPos = CustomMessages.Instance.ReadVector3(msg);
136 
137  Quaternion headRot = CustomMessages.Instance.ReadQuaternion(msg);
138 
139  RemoteHeadInfo headInfo = GetRemoteHeadInfo(userID);
140  headInfo.HeadObject.transform.localPosition = headPos;
141  headInfo.HeadObject.transform.localRotation = headRot;
142  }
143 
148  private GameObject CreateRemoteHead()
149  {
150  GameObject newHeadObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
151  newHeadObj.transform.parent = gameObject.transform;
152  newHeadObj.transform.localScale = Vector3.one * 0.2f;
153  return newHeadObj;
154  }
155 
161  private void RemoveRemoteHead(GameObject remoteHeadObject)
162  {
163  DestroyImmediate(remoteHeadObject);
164  }
165  }
166 }
RemoteHeadInfo GetRemoteHeadInfo(long userId)
Gets the data structure for the remote users&#39; head position.
virtual int GetID()
Definition: User.cs:49
TestMessageID
Message enum containing our information bytes to share. The first message type has to start with User...
The purpose of this class is to provide a cached reference to the main camera. Calling Camera...
Definition: CameraCache.cs:12
static T Instance
Returns the Singleton instance of the classes type. If no instance is found, then we search for an in...
Definition: Singleton.cs:26
static Camera Main
Returns a cached reference to the main camera and uses Camera.main if it hasn&#39;t been cached yet...
Definition: CameraCache.cs:20
Test class for demonstrating how to send custom messages between clients.
The SharingStage is in charge of managing the core networking layer for the application.
Definition: SharingStage.cs:14
Broadcasts the head transform of the local user to other users in the session, and adds and updates t...
override void OnDestroy()
Base OnDestroy method that destroys the Singleton&#39;s unique instance. Called by Unity when destroying ...
Singleton behaviour class, used for components that should only have one instance.
Definition: Singleton.cs:14