AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
RemoteMeshTarget.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 System.IO;
7 #if UNITY_EDITOR || UNITY_STANDALONE_WIN
8 using System.Net;
9 using System.Net.Sockets;
10 #endif
11 using UnityEngine;
12 
13 namespace HoloToolkit.Unity.SpatialMapping
14 {
21  {
22  [Tooltip("The IPv4 Address of the machine running the Unity editor.")]
23  public string ServerIP;
24 
25  [Tooltip("The connection port on the machine to use.")]
26  public int ConnectionPort = 11000;
27 
28 #if UNITY_EDITOR || UNITY_STANDALONE_WIN
29  private TcpListener networkListener;
33 
37  private TcpClient networkClient;
38 
42  private bool clientConnected;
43 
44  // Use this for initialization.
45  private void Start()
46  {
47  // Setup the network listener.
48  IPAddress localAddr = IPAddress.Parse(ServerIP.Trim());
49  networkListener = new TcpListener(localAddr, ConnectionPort);
50  networkListener.Start();
51 
52  // Request the network listener to wait for connections asynchronously.
53  AsyncCallback callback = OnClientConnect;
54  networkListener.BeginAcceptTcpClient(callback, this);
55  }
56 
57  // Update is called once per frame.
58  private void Update()
59  {
60  // If we have a connected client, presumably the client wants to send some meshes.
61  if (clientConnected)
62  {
63  // Get the clients stream.
64  NetworkStream stream = networkClient.GetStream();
65 
66  // Make sure there is data in the stream.
67  if (stream.DataAvailable)
68  {
69  // The first 4 bytes will be the size of the data containing the mesh(es).
70  int datasize = ReadInt(stream);
71 
72  // Allocate a buffer to hold the data.
73  byte[] dataBuffer = new byte[datasize];
74 
75  // Read the data.
76  // The data can come in chunks.
77  int readsize = 0;
78 
79  while (readsize != datasize)
80  {
81  readsize += stream.Read(dataBuffer, readsize, datasize - readsize);
82  }
83 
84  if (readsize != datasize)
85  {
86  Debug.Log("reading mesh failed: " + readsize + " != " + datasize);
87  }
88 
89  // Pass the data to the mesh serializer.
90  List<Mesh> meshes = new List<Mesh>(SimpleMeshSerializer.Deserialize(dataBuffer));
91 
92  if (meshes.Count > 0)
93  {
94  // Use the network-based mapping source to receive meshes in the Unity editor.
95  SpatialMappingManager.Instance.SetSpatialMappingSource(this);
96  }
97 
98  // For each mesh, create a GameObject to render it.
99  for (int index = 0; index < meshes.Count; index++)
100  {
101  int meshID = SurfaceObjects.Count;
102 
103  SurfaceObject surface = CreateSurfaceObject(
104  mesh: meshes[index],
105  objectName: "Beamed-" + meshID,
106  parentObject: transform,
107  meshID: meshID
108  );
109 
110  surface.Object.transform.parent = SpatialMappingManager.Instance.transform;
111 
112  AddSurfaceObject(surface);
113  }
114 
115  // Finally disconnect.
116  clientConnected = false;
117  networkClient.Close();
118 
119  // And wait for the next connection.
120  AsyncCallback callback = OnClientConnect;
121  networkListener.BeginAcceptTcpClient(callback, this);
122  }
123  }
124  }
125 
131  private int ReadInt(Stream stream)
132  {
133  // The bytes arrive in the wrong order, so swap them.
134  byte[] bytes = new byte[4];
135  stream.Read(bytes, 0, 4);
136  byte t = bytes[0];
137  bytes[0] = bytes[3];
138  bytes[3] = t;
139 
140  t = bytes[1];
141  bytes[1] = bytes[2];
142  bytes[2] = t;
143 
144  // Then bitconverter can read the int32.
145  return BitConverter.ToInt32(bytes, 0);
146  }
147 
152  private void OnClientConnect(IAsyncResult result)
153  {
154  if (result.IsCompleted)
155  {
156  networkClient = networkListener.EndAcceptTcpClient(result);
157  if (networkClient != null)
158  {
159  Debug.Log("Connected");
160  clientConnected = true;
161  }
162  }
163  }
164 #endif
165  }
166 }
SimpleMeshSerializer converts a UnityEngine.Mesh object to and from an array of bytes. This class saves minimal mesh data (vertices and triangle indices) in the following format: File header: vertex count (32 bit integer), triangle count (32 bit integer) Vertex list: vertex.x, vertex.y, vertex.z (all 32 bit float) Triangle index list: 32 bit integers
static IEnumerable< Mesh > Deserialize(byte[] data)
Deserializes a list of Mesh objects from the provided byte array.
RemoteMeshTarget will listen for meshes being sent from a remote system (HoloLens). It is intended to run in the Unity Editor with exactly one HoloLens device sending data.
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
The SpatialMappingManager class allows applications to use a SurfaceObserver or a stored Spatial Mapp...