t1 / TFDContents / Assets / KinectScripts / KinectDataServer.cs @ 9
이력 | 보기 | 이력해설 | 다운로드 (24.4 KB)
1 | 3 | KTH | using UnityEngine; |
---|---|---|---|
2 | using UnityEngine.UI; |
||
3 | using System.Collections; |
||
4 | using UnityEngine.Networking; |
||
5 | using System.Collections.Generic; |
||
6 | using System.Text; |
||
7 | using System.Net; |
||
8 | using System.Net.Sockets; |
||
9 | using UnityEngine.Networking.Types; |
||
10 | |||
11 | /// <summary> |
||
12 | /// Kinect data server is the component that transmits the Kinect body data to Kinect data clients over the network. |
||
13 | /// </summary> |
||
14 | public class KinectDataServer : MonoBehaviour |
||
15 | { |
||
16 | [Tooltip("Port to be used for incoming connections.")] |
||
17 | public int listenOnPort = 8888; |
||
18 | |||
19 | [Tooltip("Port used for server broadcast discovery.")] |
||
20 | public int broadcastPort = 8889; |
||
21 | |||
22 | [Tooltip("Maximum number of allowed connections.")] |
||
23 | public int maxConnections = 5; |
||
24 | |||
25 | [Tooltip("Whether the server should run as websocket host or not.")] |
||
26 | public bool websocketHost = false; |
||
27 | |||
28 | [Tooltip("Transform representing this sensor's position and rotation in world space. If missing, the sensor height and angle settings from KinectManager-component are used.")] |
||
29 | public Transform sensorTransform; |
||
30 | |||
31 | [Tooltip("GUI-texture used to display the tracked users on scene background.")] |
||
32 | public GUITexture backgroundImage; |
||
33 | |||
34 | [Tooltip("GUI-Text to display connection status messages.")] |
||
35 | public GUIText connStatusText; |
||
36 | |||
37 | [Tooltip("GUI-Text to display server status messages.")] |
||
38 | public GUIText serverStatusText; |
||
39 | |||
40 | [Tooltip("UI-Text to display server console.")] |
||
41 | public Text consoleMessages; |
||
42 | |||
43 | |||
44 | private ConnectionConfig serverConfig; |
||
45 | private int serverChannelId; |
||
46 | |||
47 | private HostTopology serverTopology; |
||
48 | private int serverHostId = -1; |
||
49 | private int broadcastHostId = -1; |
||
50 | |||
51 | private const int bufferSize = 32768; |
||
52 | private byte[] recBuffer = new byte[bufferSize]; |
||
53 | |||
54 | private byte[] broadcastOutBuffer = null; |
||
55 | |||
56 | private const int maxSendSize = 1400; |
||
57 | |||
58 | // private string sendFvMsg = string.Empty; |
||
59 | // private int sendFvNextOfs = 0; |
||
60 | // |
||
61 | // private string sendFtMsg = string.Empty; |
||
62 | // private int sendFtNextOfs = 0; |
||
63 | |||
64 | private KinectManager manager; |
||
65 | // private FacetrackingManager faceManager; |
||
66 | private VisualGestureManager gestureManager; |
||
67 | private SpeechManager speechManager; |
||
68 | |||
69 | private byte[] compressBuffer = new byte[bufferSize]; |
||
70 | private LZ4Sharp.ILZ4Compressor compressor; |
||
71 | private LZ4Sharp.ILZ4Decompressor decompressor; |
||
72 | |||
73 | private long liRelTime = 0; |
||
74 | private float fCurrentTime = 0f; |
||
75 | |||
76 | private Dictionary<int, HostConnection> dictConnection = new Dictionary<int, HostConnection>(); |
||
77 | private List<int> alConnectionId = new List<int>(); |
||
78 | |||
79 | |||
80 | private struct HostConnection |
||
81 | { |
||
82 | public int hostId; |
||
83 | public int connectionId; |
||
84 | public int channelId; |
||
85 | |||
86 | public bool keepAlive; |
||
87 | public string reqDataType; |
||
88 | //public bool matrixSent; |
||
89 | //public int errorCount; |
||
90 | } |
||
91 | |||
92 | |||
93 | // enables or disables the speech recognition component |
||
94 | public void EnableSpeechRecognition(bool bEnable) |
||
95 | { |
||
96 | SpeechManager speechManager = gameObject.GetComponent<SpeechManager>(); |
||
97 | |||
98 | if (speechManager) |
||
99 | { |
||
100 | speechManager.enabled = bEnable; |
||
101 | LogToConsole("Speech recognition is " + (bEnable ? "enabled" : "disabled")); |
||
102 | |||
103 | if (bEnable) |
||
104 | { |
||
105 | StartCoroutine(CheckSpeechManager()); |
||
106 | } |
||
107 | } |
||
108 | else |
||
109 | { |
||
110 | LogErrorToConsole("SpeechManager-component not found."); |
||
111 | } |
||
112 | } |
||
113 | |||
114 | |||
115 | // enables or disables the visual gestures component |
||
116 | public void EnableVisualGestures(bool bEnable) |
||
117 | { |
||
118 | VisualGestureManager vgbManager = gameObject.GetComponent<VisualGestureManager>(); |
||
119 | |||
120 | if (vgbManager) |
||
121 | { |
||
122 | vgbManager.enabled = bEnable; |
||
123 | LogToConsole("Visual gestures are " + (bEnable ? "enabled" : "disabled")); |
||
124 | |||
125 | if (bEnable) |
||
126 | { |
||
127 | StartCoroutine(CheckVisualGestureManager()); |
||
128 | } |
||
129 | |||
130 | // enable SimpleVisualGestureListener as well |
||
131 | SimpleVisualGestureListener vgbListener = gameObject.GetComponent<SimpleVisualGestureListener>(); |
||
132 | if (vgbListener) |
||
133 | { |
||
134 | vgbListener.enabled = bEnable; |
||
135 | } |
||
136 | } |
||
137 | else |
||
138 | { |
||
139 | LogErrorToConsole("VisualGestureManager-component not found."); |
||
140 | } |
||
141 | } |
||
142 | |||
143 | |||
144 | // checks if SpeechManager is initialized or not |
||
145 | private IEnumerator CheckSpeechManager() |
||
146 | { |
||
147 | // wait for 2 seconds |
||
148 | yield return new WaitForSeconds(2f); |
||
149 | |||
150 | string sStatusMsg = string.Empty; |
||
151 | SpeechManager speechManager = SpeechManager.Instance; |
||
152 | |||
153 | if (!speechManager) |
||
154 | sStatusMsg = "SpeechManager is missing!"; |
||
155 | else if(!speechManager.IsSapiInitialized()) |
||
156 | sStatusMsg = "SpeechManager not initialized! Check the log-file for details."; |
||
157 | else |
||
158 | LogToConsole("SpeechManager is ready."); |
||
159 | |||
160 | if (sStatusMsg.Length > 0) |
||
161 | { |
||
162 | LogErrorToConsole(sStatusMsg); |
||
163 | } |
||
164 | } |
||
165 | |||
166 | |||
167 | // checks if VisualGestureManager is initialized or not |
||
168 | private IEnumerator CheckVisualGestureManager() |
||
169 | { |
||
170 | // wait for 2 seconds |
||
171 | yield return new WaitForSeconds(2f); |
||
172 | |||
173 | string sStatusMsg = string.Empty; |
||
174 | VisualGestureManager vgbManager = VisualGestureManager.Instance; |
||
175 | |||
176 | if (!vgbManager) |
||
177 | sStatusMsg = "VisualGestureManager is missing!"; |
||
178 | else if(!vgbManager.IsVisualGestureInitialized()) |
||
179 | sStatusMsg = "VisualGestureManager not initialized! Check the log-file for details."; |
||
180 | else |
||
181 | LogToConsole("VisualGestureManager is ready."); |
||
182 | |||
183 | if (sStatusMsg.Length > 0) |
||
184 | { |
||
185 | LogErrorToConsole(sStatusMsg); |
||
186 | } |
||
187 | } |
||
188 | |||
189 | |||
190 | // logs message to the console |
||
191 | private void LogToConsole(string sMessage) |
||
192 | { |
||
193 | Debug.Log(sMessage); |
||
194 | |||
195 | if (consoleMessages) |
||
196 | { |
||
197 | consoleMessages.text += "\r\n" + sMessage; |
||
198 | |||
199 | // scroll to end |
||
200 | ScrollRect scrollRect = consoleMessages.gameObject.GetComponentInParent<ScrollRect>(); |
||
201 | if (scrollRect) |
||
202 | { |
||
203 | Canvas.ForceUpdateCanvases(); |
||
204 | scrollRect.verticalScrollbar.value = 0f; |
||
205 | Canvas.ForceUpdateCanvases(); |
||
206 | } |
||
207 | } |
||
208 | } |
||
209 | |||
210 | |||
211 | // logs error message to the console |
||
212 | private void LogErrorToConsole(string sMessage) |
||
213 | { |
||
214 | Debug.LogError(sMessage); |
||
215 | |||
216 | if (consoleMessages) |
||
217 | { |
||
218 | consoleMessages.text += "\r\n" + sMessage; |
||
219 | |||
220 | // scroll to end |
||
221 | ScrollRect scrollRect = consoleMessages.gameObject.GetComponentInParent<ScrollRect>(); |
||
222 | if (scrollRect) |
||
223 | { |
||
224 | Canvas.ForceUpdateCanvases(); |
||
225 | scrollRect.verticalScrollbar.value = 0f; |
||
226 | Canvas.ForceUpdateCanvases(); |
||
227 | } |
||
228 | } |
||
229 | } |
||
230 | |||
231 | |||
232 | // logs error message to the console |
||
233 | private void LogErrorToConsole(System.Exception ex) |
||
234 | { |
||
235 | LogErrorToConsole(ex.Message + "\n" + ex.StackTrace); |
||
236 | } |
||
237 | |||
238 | |||
239 | void Awake () |
||
240 | { |
||
241 | try |
||
242 | { |
||
243 | NetworkTransport.Init(); |
||
244 | |||
245 | serverConfig = new ConnectionConfig(); |
||
246 | serverChannelId = serverConfig.AddChannel(QosType.StateUpdate); // QosType.UnreliableFragmented |
||
247 | serverConfig.MaxSentMessageQueueSize = 2048; // 128 by default |
||
248 | |||
249 | // start data server |
||
250 | serverTopology = new HostTopology(serverConfig, maxConnections); |
||
251 | |||
252 | if(!websocketHost) |
||
253 | serverHostId = NetworkTransport.AddHost(serverTopology, listenOnPort); |
||
254 | else |
||
255 | serverHostId = NetworkTransport.AddWebsocketHost(serverTopology, listenOnPort); |
||
256 | |||
257 | if(serverHostId < 0) |
||
258 | { |
||
259 | throw new UnityException("AddHost failed for port " + listenOnPort); |
||
260 | } |
||
261 | |||
262 | // add broadcast host |
||
263 | if(broadcastPort > 0 && !websocketHost) |
||
264 | { |
||
265 | broadcastHostId = NetworkTransport.AddHost(serverTopology, 0); |
||
266 | |||
267 | if(broadcastHostId < 0) |
||
268 | { |
||
269 | throw new UnityException("AddHost failed for broadcast discovery"); |
||
270 | } |
||
271 | } |
||
272 | |||
273 | // set broadcast data |
||
274 | string sBroadcastData = string.Empty; |
||
275 | |||
276 | #if !UNITY_WSA |
||
277 | try |
||
278 | { |
||
279 | string strHostName = System.Net.Dns.GetHostName(); |
||
280 | IPHostEntry ipEntry = Dns.GetHostEntry(strHostName); |
||
281 | IPAddress[] addr = ipEntry.AddressList; |
||
282 | |||
283 | string sHostInfo = "Host: " + strHostName; |
||
284 | for (int i = 0; i < addr.Length; i++) |
||
285 | { |
||
286 | if (addr[i].AddressFamily == AddressFamily.InterNetwork) |
||
287 | { |
||
288 | sHostInfo += ", IP: " + addr[i].ToString(); |
||
289 | sBroadcastData = "KinectDataServer:" + addr[i].ToString() + ":" + listenOnPort; |
||
290 | break; |
||
291 | } |
||
292 | } |
||
293 | |||
294 | sHostInfo += ", Port: " + listenOnPort; |
||
295 | LogToConsole(sHostInfo); |
||
296 | |||
297 | if(serverStatusText) |
||
298 | { |
||
299 | serverStatusText.text = sHostInfo; |
||
300 | } |
||
301 | } |
||
302 | catch (System.Exception ex) |
||
303 | { |
||
304 | LogErrorToConsole(ex.Message + "\n\n" + ex.StackTrace); |
||
305 | |||
306 | if(serverStatusText) |
||
307 | { |
||
308 | serverStatusText.text = "Use 'ipconfig' to see the host IP; Port: " + listenOnPort; |
||
309 | } |
||
310 | } |
||
311 | #else |
||
312 | sBroadcastData = "KinectDataServer:" + "127.0.0.1" + ":" + listenOnPort; |
||
313 | #endif |
||
314 | |||
315 | // start broadcast discovery |
||
316 | if(broadcastHostId >= 0) |
||
317 | { |
||
318 | broadcastOutBuffer = System.Text.Encoding.UTF8.GetBytes(sBroadcastData); |
||
319 | byte error = 0; |
||
320 | |||
321 | if (!NetworkTransport.StartBroadcastDiscovery(broadcastHostId, broadcastPort, 8888, 1, 0, broadcastOutBuffer, broadcastOutBuffer.Length, 2000, out error)) |
||
322 | { |
||
323 | throw new UnityException("Start broadcast discovery failed: " + (NetworkError)error); |
||
324 | } |
||
325 | } |
||
326 | |||
327 | liRelTime = 0; |
||
328 | fCurrentTime = Time.time; |
||
329 | |||
330 | System.DateTime dtNow = System.DateTime.UtcNow; |
||
331 | LogToConsole("Kinect data server started at " + dtNow.ToString()); |
||
332 | |||
333 | if(consoleMessages) |
||
334 | { |
||
335 | consoleMessages.text = "Kinect data server started at " + dtNow.ToString(); |
||
336 | } |
||
337 | |||
338 | if(connStatusText) |
||
339 | { |
||
340 | connStatusText.text = "Server running: 0 connection(s)"; |
||
341 | } |
||
342 | } |
||
343 | catch (System.Exception ex) |
||
344 | { |
||
345 | LogErrorToConsole(ex.Message + "\n" + ex.StackTrace); |
||
346 | |||
347 | if(connStatusText) |
||
348 | { |
||
349 | connStatusText.text = ex.Message; |
||
350 | } |
||
351 | } |
||
352 | } |
||
353 | |||
354 | void Start() |
||
355 | { |
||
356 | if(manager == null) |
||
357 | { |
||
358 | manager = KinectManager.Instance; |
||
359 | } |
||
360 | |||
361 | if (manager && manager.IsInitialized ()) |
||
362 | { |
||
363 | if (sensorTransform != null) |
||
364 | { |
||
365 | manager.SetKinectToWorldMatrix (sensorTransform.position, sensorTransform.rotation, Vector3.one); |
||
366 | } |
||
367 | |||
368 | if(backgroundImage) |
||
369 | { |
||
370 | Vector3 localScale = backgroundImage.transform.localScale; |
||
371 | localScale.x = (float)manager.GetDepthImageWidth() * (float)Screen.height / ((float)manager.GetDepthImageHeight() * (float)Screen.width); |
||
372 | localScale.y = -1f; |
||
373 | |||
374 | backgroundImage.transform.localScale = localScale; |
||
375 | } |
||
376 | } |
||
377 | |||
378 | // create lz4 compressor & decompressor |
||
379 | compressor = LZ4Sharp.LZ4CompressorFactory.CreateNew(); |
||
380 | decompressor = LZ4Sharp.LZ4DecompressorFactory.CreateNew(); |
||
381 | } |
||
382 | |||
383 | void OnDestroy() |
||
384 | { |
||
385 | // clear connections |
||
386 | dictConnection.Clear(); |
||
387 | |||
388 | // stop broadcast |
||
389 | if (broadcastHostId >= 0) |
||
390 | { |
||
391 | NetworkTransport.StopBroadcastDiscovery(); |
||
392 | NetworkTransport.RemoveHost(broadcastHostId); |
||
393 | broadcastHostId = -1; |
||
394 | } |
||
395 | |||
396 | // close the server port |
||
397 | if (serverHostId >= 0) |
||
398 | { |
||
399 | NetworkTransport.RemoveHost(serverHostId); |
||
400 | serverHostId = -1; |
||
401 | } |
||
402 | |||
403 | // shitdown the transport layer |
||
404 | NetworkTransport.Shutdown(); |
||
405 | } |
||
406 | |||
407 | void Update () |
||
408 | { |
||
409 | int recHostId; |
||
410 | int connectionId; |
||
411 | int recChannelId; |
||
412 | int dataSize; |
||
413 | |||
414 | bool connListUpdated = false; |
||
415 | |||
416 | if(backgroundImage && backgroundImage.texture == null) |
||
417 | { |
||
418 | backgroundImage.texture = manager ? manager.GetUsersLblTex() : null; |
||
419 | } |
||
420 | |||
421 | // if(faceManager == null) |
||
422 | // { |
||
423 | // faceManager = FacetrackingManager.Instance; |
||
424 | // } |
||
425 | |||
426 | if (gestureManager == null) |
||
427 | { |
||
428 | gestureManager = VisualGestureManager.Instance; |
||
429 | } |
||
430 | |||
431 | if (speechManager == null) |
||
432 | { |
||
433 | speechManager = SpeechManager.Instance; |
||
434 | } |
||
435 | |||
436 | try |
||
437 | { |
||
438 | byte error = 0; |
||
439 | NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId, out recChannelId, recBuffer, bufferSize, out dataSize, out error); |
||
440 | |||
441 | switch (recData) |
||
442 | { |
||
443 | case NetworkEventType.Nothing: //1 |
||
444 | break; |
||
445 | case NetworkEventType.ConnectEvent: //2 |
||
446 | if(recHostId == serverHostId && recChannelId == serverChannelId && |
||
447 | !dictConnection.ContainsKey(connectionId)) |
||
448 | { |
||
449 | HostConnection conn = new HostConnection(); |
||
450 | conn.hostId = recHostId; |
||
451 | conn.connectionId = connectionId; |
||
452 | conn.channelId = recChannelId; |
||
453 | conn.keepAlive = true; |
||
454 | conn.reqDataType = "ka,kb,km,kh"; |
||
455 | //conn.matrixSent = false; |
||
456 | |||
457 | dictConnection[connectionId] = conn; |
||
458 | connListUpdated = true; |
||
459 | |||
460 | //LogToConsole(connectionId + "-conn: " + conn.reqDataType); |
||
461 | } |
||
462 | |||
463 | // // reset chunked face messages |
||
464 | // sendFvMsg = string.Empty; |
||
465 | // sendFvNextOfs = 0; |
||
466 | // |
||
467 | // sendFtMsg = string.Empty; |
||
468 | // sendFtNextOfs = 0; |
||
469 | break; |
||
470 | case NetworkEventType.DataEvent: //3 |
||
471 | if(recHostId == serverHostId && recChannelId == serverChannelId && |
||
472 | dictConnection.ContainsKey(connectionId)) |
||
473 | { |
||
474 | HostConnection conn = dictConnection[connectionId]; |
||
475 | |||
476 | int decompSize = 0; |
||
477 | if(decompressor != null && (recBuffer[0] > 127 || recBuffer[0] < 32)) |
||
478 | { |
||
479 | decompSize = decompressor.Decompress(recBuffer, 0, compressBuffer, 0, dataSize); |
||
480 | } |
||
481 | else |
||
482 | { |
||
483 | System.Buffer.BlockCopy(recBuffer, 0, compressBuffer, 0, dataSize); |
||
484 | decompSize = dataSize; |
||
485 | } |
||
486 | |||
487 | string sRecvMessage = System.Text.Encoding.UTF8.GetString(compressBuffer, 0, decompSize); |
||
488 | |||
489 | if(sRecvMessage.StartsWith("ka")) |
||
490 | { |
||
491 | if(sRecvMessage == "ka") // vr-examples v1.0 keep-alive message |
||
492 | sRecvMessage = "ka,kb,km,kh"; |
||
493 | |||
494 | conn.keepAlive = true; |
||
495 | conn.reqDataType = sRecvMessage; |
||
496 | dictConnection[connectionId] = conn; |
||
497 | |||
498 | //LogToConsole(connectionId + "-recv: " + conn.reqDataType); |
||
499 | |||
500 | // check for SR phrase-reset |
||
501 | int iIndexSR = sRecvMessage.IndexOf(",sr"); |
||
502 | if(iIndexSR >= 0 && speechManager) |
||
503 | { |
||
504 | speechManager.ClearPhraseRecognized(); |
||
505 | //LogToConsole("phrase cleared"); |
||
506 | } |
||
507 | } |
||
508 | } |
||
509 | break; |
||
510 | case NetworkEventType.DisconnectEvent: //4 |
||
511 | if(dictConnection.ContainsKey(connectionId)) |
||
512 | { |
||
513 | dictConnection.Remove(connectionId); |
||
514 | connListUpdated = true; |
||
515 | } |
||
516 | break; |
||
517 | } |
||
518 | |||
519 | if(connListUpdated) |
||
520 | { |
||
521 | // get all connection IDs |
||
522 | alConnectionId.Clear(); |
||
523 | alConnectionId.AddRange(dictConnection.Keys); |
||
524 | |||
525 | // display the number of connections |
||
526 | StringBuilder sbConnStatus = new StringBuilder(); |
||
527 | sbConnStatus.AppendFormat("Server running: {0} connection(s)", dictConnection.Count); |
||
528 | |||
529 | foreach(int connId in dictConnection.Keys) |
||
530 | { |
||
531 | HostConnection conn = dictConnection[connId]; |
||
532 | int iPort = 0; string sAddress = string.Empty; NetworkID network; NodeID destNode; |
||
533 | |||
534 | NetworkTransport.GetConnectionInfo(conn.hostId, conn.connectionId, out sAddress, out iPort, out network, out destNode, out error); |
||
535 | if(error == (int)NetworkError.Ok) |
||
536 | { |
||
537 | sbConnStatus.AppendLine().Append(" ").Append(sAddress).Append(":").Append(iPort); |
||
538 | } |
||
539 | } |
||
540 | |||
541 | LogToConsole(sbConnStatus.ToString()); |
||
542 | |||
543 | if(connStatusText) |
||
544 | { |
||
545 | connStatusText.text = sbConnStatus.ToString(); |
||
546 | } |
||
547 | } |
||
548 | |||
549 | // send body frame to available connections |
||
550 | const char delimiter = ','; |
||
551 | string sBodyFrame = manager ? manager.GetBodyFrameData(ref liRelTime, ref fCurrentTime, delimiter) : string.Empty; |
||
552 | |||
553 | if(sBodyFrame.Length > 0 && dictConnection.Count > 0) |
||
554 | { |
||
555 | StringBuilder sbSendMessage = new StringBuilder(); |
||
556 | |||
557 | sbSendMessage.Append(manager.GetWorldMatrixData(delimiter)).Append('|'); |
||
558 | sbSendMessage.Append(sBodyFrame).Append('|'); |
||
559 | sbSendMessage.Append(manager.GetBodyHandData(ref liRelTime, delimiter)).Append('|'); |
||
560 | |||
561 | if(gestureManager && gestureManager.IsVisualGestureInitialized()) |
||
562 | { |
||
563 | sbSendMessage.Append(gestureManager.GetGestureDataAsCsv(delimiter)).Append('|'); |
||
564 | } |
||
565 | |||
566 | if(speechManager && speechManager.IsSapiInitialized()) |
||
567 | { |
||
568 | sbSendMessage.Append(speechManager.GetSpeechDataAsCsv(delimiter)).Append('|'); |
||
569 | } |
||
570 | |||
571 | if(sbSendMessage.Length > 0 && sbSendMessage[sbSendMessage.Length - 1] == '|') |
||
572 | { |
||
573 | sbSendMessage.Remove(sbSendMessage.Length - 1, 1); |
||
574 | } |
||
575 | |||
576 | byte[] btSendMessage = System.Text.Encoding.UTF8.GetBytes(sbSendMessage.ToString()); |
||
577 | |||
578 | //Debug.Log("Message " + sbSendMessage.Length + " chars: " + sbSendMessage.ToString()); |
||
579 | //Debug.Log("Encoded into " + btSendMessage.Length + " bytes: " + ByteArrayToString(btSendMessage, btSendMessage.Length)); |
||
580 | |||
581 | int compSize = 0; |
||
582 | if(compressor != null && btSendMessage.Length > 100 && !websocketHost) |
||
583 | { |
||
584 | compSize = compressor.Compress(btSendMessage, 0, btSendMessage.Length, compressBuffer, 0); |
||
585 | } |
||
586 | else |
||
587 | { |
||
588 | System.Buffer.BlockCopy(btSendMessage, 0, compressBuffer, 0, btSendMessage.Length); |
||
589 | compSize = btSendMessage.Length; |
||
590 | } |
||
591 | |||
592 | //Debug.Log("Compressed into " + compSize + " bytes: " + ByteArrayToString(compressBuffer, compSize)); |
||
593 | |||
594 | // // check face-tracking requests |
||
595 | // bool bFaceParams = false, bFaceVertices = false, bFaceUvs = false, bFaceTriangles = false; |
||
596 | // if(faceManager && faceManager.IsFaceTrackingInitialized()) |
||
597 | // CheckFacetrackRequests(out bFaceParams, out bFaceVertices, out bFaceUvs, out bFaceTriangles); |
||
598 | // |
||
599 | // byte[] btFaceParams = null; |
||
600 | // if(bFaceParams) |
||
601 | // { |
||
602 | // string sFaceParams = faceManager.GetFaceParamsAsCsv(); |
||
603 | // if(!string.IsNullOrEmpty(sFaceParams)) |
||
604 | // btFaceParams = System.Text.Encoding.UTF8.GetBytes(sFaceParams); |
||
605 | // } |
||
606 | // |
||
607 | // // next chunk of data for face vertices |
||
608 | // byte[] btFaceVertices = null; |
||
609 | // string sFvMsgHead = string.Empty; |
||
610 | // GetNextFaceVertsChunk(bFaceVertices, bFaceUvs, ref btFaceVertices, out sFvMsgHead); |
||
611 | // |
||
612 | // // next chunk of data for face triangles |
||
613 | // byte[] btFaceTriangles = null; |
||
614 | // string sFtMsgHead = string.Empty; |
||
615 | // GetNextFaceTrisChunk(bFaceTriangles, ref btFaceTriangles, out sFtMsgHead); |
||
616 | |||
617 | foreach(int connId in alConnectionId) |
||
618 | { |
||
619 | HostConnection conn = dictConnection[connId]; |
||
620 | |||
621 | if(conn.keepAlive) |
||
622 | { |
||
623 | conn.keepAlive = false; |
||
624 | dictConnection[connId] = conn; |
||
625 | |||
626 | if(conn.reqDataType != null && conn.reqDataType.Contains("kb,")) |
||
627 | { |
||
628 | //LogToConsole(conn.connectionId + "-sendkb: " + conn.reqDataType); |
||
629 | |||
630 | error = 0; |
||
631 | //if(!NetworkTransport.Send(conn.hostId, conn.connectionId, conn.channelId, btSendMessage, btSendMessage.Length, out error)) |
||
632 | if(!NetworkTransport.Send(conn.hostId, conn.connectionId, conn.channelId, compressBuffer, compSize, out error)) |
||
633 | { |
||
634 | string sMessage = "Error sending body data via conn " + conn.connectionId + ": " + (NetworkError)error; |
||
635 | LogErrorToConsole(sMessage); |
||
636 | |||
637 | if(serverStatusText) |
||
638 | { |
||
639 | serverStatusText.text = sMessage; |
||
640 | } |
||
641 | } |
||
642 | } |
||
643 | |||
644 | // if(bFaceParams && btFaceParams != null && |
||
645 | // conn.reqDataType != null && conn.reqDataType.Contains("fp,")) |
||
646 | // { |
||
647 | // //Debug.Log(conn.connectionId + "-sendfp: " + conn.reqDataType); |
||
648 | // |
||
649 | // error = 0; |
||
650 | // if(!NetworkTransport.Send(conn.hostId, conn.connectionId, conn.channelId, btFaceParams, btFaceParams.Length, out error)) |
||
651 | // { |
||
652 | // string sMessage = "Error sending face params via conn " + conn.connectionId + ": " + (NetworkError)error; |
||
653 | // Debug.LogError(sMessage); |
||
654 | // |
||
655 | // if(serverStatusText) |
||
656 | // { |
||
657 | // serverStatusText.text = sMessage; |
||
658 | // } |
||
659 | // } |
||
660 | // } |
||
661 | // |
||
662 | // if(bFaceVertices && btFaceVertices != null && |
||
663 | // conn.reqDataType != null && conn.reqDataType.Contains("fv,")) |
||
664 | // { |
||
665 | // //Debug.Log(conn.connectionId + "-sendfv: " + conn.reqDataType + " - " + sFvMsgHead); |
||
666 | // |
||
667 | // error = 0; |
||
668 | // if(!NetworkTransport.Send(conn.hostId, conn.connectionId, conn.channelId, btFaceVertices, btFaceVertices.Length, out error)) |
||
669 | // { |
||
670 | // string sMessage = "Error sending face verts via conn " + conn.connectionId + ": " + (NetworkError)error; |
||
671 | // Debug.LogError(sMessage); |
||
672 | // |
||
673 | // if(serverStatusText) |
||
674 | // { |
||
675 | // serverStatusText.text = sMessage; |
||
676 | // } |
||
677 | // } |
||
678 | // } |
||
679 | // |
||
680 | // if(bFaceTriangles && btFaceTriangles != null && |
||
681 | // conn.reqDataType != null && conn.reqDataType.Contains("ft,")) |
||
682 | // { |
||
683 | // //Debug.Log(conn.connectionId + "-sendft: " + conn.reqDataType + " - " + sFtMsgHead); |
||
684 | // |
||
685 | // error = 0; |
||
686 | // if(!NetworkTransport.Send(conn.hostId, conn.connectionId, conn.channelId, btFaceTriangles, btFaceTriangles.Length, out error)) |
||
687 | // { |
||
688 | // string sMessage = "Error sending face tris via conn " + conn.connectionId + ": " + (NetworkError)error; |
||
689 | // Debug.LogError(sMessage); |
||
690 | // |
||
691 | // if(serverStatusText) |
||
692 | // { |
||
693 | // serverStatusText.text = sMessage; |
||
694 | // } |
||
695 | // } |
||
696 | // } |
||
697 | |||
698 | } |
||
699 | } |
||
700 | } |
||
701 | |||
702 | } |
||
703 | catch (System.Exception ex) |
||
704 | { |
||
705 | LogErrorToConsole(ex.Message + "\n" + ex.StackTrace); |
||
706 | |||
707 | if(serverStatusText) |
||
708 | { |
||
709 | serverStatusText.text = ex.Message; |
||
710 | } |
||
711 | } |
||
712 | } |
||
713 | |||
714 | |||
715 | // converts byte array to string |
||
716 | public string ByteArrayToString(byte[] ba, int baLength) |
||
717 | { |
||
718 | StringBuilder hex = new StringBuilder(ba.Length * 2); |
||
719 | |||
720 | for (int i = 0; i < baLength; i++) |
||
721 | { |
||
722 | byte b = ba[i]; |
||
723 | hex.AppendFormat("{0:x2}", b); |
||
724 | } |
||
725 | |||
726 | return hex.ToString(); |
||
727 | } |
||
728 | |||
729 | // converts byte array to string, by using the system bit-converter |
||
730 | public string ByteArrayToString2(byte[] ba) |
||
731 | { |
||
732 | string hex = System.BitConverter.ToString(ba); |
||
733 | return hex.Replace("-",""); |
||
734 | } |
||
735 | |||
736 | // converts string to byte array |
||
737 | public byte[] StringToByteArray(string hex) |
||
738 | { |
||
739 | int NumberChars = hex.Length; |
||
740 | byte[] bytes = new byte[NumberChars / 2]; |
||
741 | for (int i = 0; i < NumberChars; i += 2) |
||
742 | bytes[i / 2] = System.Convert.ToByte(hex.Substring(i, 2), 16); |
||
743 | return bytes; |
||
744 | } |
||
745 | |||
746 | // // checks whether facetracking data was requested by any connection |
||
747 | // private void CheckFacetrackRequests(out bool bFaceParams, out bool bFaceVertices, out bool bFaceUvs, out bool bFaceTriangles) |
||
748 | // { |
||
749 | // bFaceParams = bFaceVertices = bFaceUvs = bFaceTriangles = false; |
||
750 | // |
||
751 | // foreach (int connId in alConnectionId) |
||
752 | // { |
||
753 | // HostConnection conn = dictConnection [connId]; |
||
754 | // |
||
755 | // if (conn.keepAlive && conn.reqDataType != null) |
||
756 | // { |
||
757 | // if (conn.reqDataType.Contains ("fp,")) |
||
758 | // bFaceParams = true; |
||
759 | // if (conn.reqDataType.Contains ("fv,")) |
||
760 | // bFaceVertices = true; |
||
761 | // if (conn.reqDataType.Contains ("fu,")) |
||
762 | // bFaceUvs = true; |
||
763 | // if (conn.reqDataType.Contains ("ft,")) |
||
764 | // bFaceTriangles = true; |
||
765 | // } |
||
766 | // } |
||
767 | // } |
||
768 | // |
||
769 | // // returns next chunk of face-vertices data |
||
770 | // private bool GetNextFaceVertsChunk(bool bFaceVertices, bool bFaceUvs, ref byte[] btFaceVertices, out string chunkHead) |
||
771 | // { |
||
772 | // btFaceVertices = null; |
||
773 | // chunkHead = string.Empty; |
||
774 | // |
||
775 | // if (bFaceVertices) |
||
776 | // { |
||
777 | // chunkHead = "pv2"; // end |
||
778 | // |
||
779 | // if (sendFvNextOfs >= sendFvMsg.Length) |
||
780 | // { |
||
781 | // sendFvMsg = faceManager.GetFaceVerticesAsCsv (); |
||
782 | // if (bFaceUvs) |
||
783 | // sendFvMsg += "|" + faceManager.GetFaceUvsAsCsv (); |
||
784 | // |
||
785 | // byte[] uncompressed = System.Text.Encoding.UTF8.GetBytes(sendFvMsg); |
||
786 | // byte[] compressed = compressor.Compress(uncompressed); |
||
787 | // sendFvMsg = System.Convert.ToBase64String(compressed); |
||
788 | // |
||
789 | // sendFvNextOfs = 0; |
||
790 | // } |
||
791 | // |
||
792 | // if (sendFvNextOfs < sendFvMsg.Length) |
||
793 | // { |
||
794 | // int chunkLen = sendFvMsg.Length - sendFvNextOfs; |
||
795 | // |
||
796 | // if (chunkLen > maxSendSize) |
||
797 | // { |
||
798 | // chunkLen = maxSendSize; |
||
799 | // chunkHead = sendFvNextOfs == 0 ? "pv0" : "pv1"; // start or middle |
||
800 | // } |
||
801 | // else if (sendFvNextOfs == 0) |
||
802 | // { |
||
803 | // chunkHead = "pv3"; // all |
||
804 | // } |
||
805 | // |
||
806 | // btFaceVertices = System.Text.Encoding.UTF8.GetBytes (chunkHead + sendFvMsg.Substring (sendFvNextOfs, chunkLen)); |
||
807 | // sendFvNextOfs += chunkLen; |
||
808 | // } |
||
809 | // } |
||
810 | // |
||
811 | // return (btFaceVertices != null); |
||
812 | // } |
||
813 | // |
||
814 | // // returns next chunk of face-triangles data |
||
815 | // private bool GetNextFaceTrisChunk(bool bFaceTriangles, ref byte[] btFaceTriangles, out string chunkHead) |
||
816 | // { |
||
817 | // btFaceTriangles = null; |
||
818 | // chunkHead = string.Empty; |
||
819 | // |
||
820 | // if (bFaceTriangles) |
||
821 | // { |
||
822 | // chunkHead = "pt2"; // end |
||
823 | // |
||
824 | // if (sendFtNextOfs >= sendFtMsg.Length) |
||
825 | // { |
||
826 | // sendFtMsg = faceManager.GetFaceTrianglesAsCsv (); |
||
827 | // |
||
828 | // byte[] uncompressed = System.Text.Encoding.UTF8.GetBytes(sendFtMsg); |
||
829 | // byte[] compressed = compressor.Compress(uncompressed); |
||
830 | // sendFtMsg = System.Convert.ToBase64String(compressed); |
||
831 | // |
||
832 | // sendFtNextOfs = 0; |
||
833 | // } |
||
834 | // |
||
835 | // if (sendFtNextOfs < sendFtMsg.Length) |
||
836 | // { |
||
837 | // int chunkLen = sendFtMsg.Length - sendFtNextOfs; |
||
838 | // |
||
839 | // if (chunkLen > maxSendSize) |
||
840 | // { |
||
841 | // chunkLen = maxSendSize; |
||
842 | // chunkHead = sendFtNextOfs == 0 ? "pt0" : "pt1"; // start or middle |
||
843 | // } |
||
844 | // else if (sendFvNextOfs == 0) |
||
845 | // { |
||
846 | // chunkHead = "pt3"; // all |
||
847 | // } |
||
848 | // |
||
849 | // btFaceTriangles = System.Text.Encoding.UTF8.GetBytes (chunkHead + sendFtMsg.Substring (sendFtNextOfs, chunkLen)); |
||
850 | // sendFtNextOfs += chunkLen; |
||
851 | // } |
||
852 | // } |
||
853 | // |
||
854 | // return (btFaceTriangles != null); |
||
855 | // } |
||
856 | |||
857 | } |