1
2 #include "GraphicsServerExample.h"
3 #include "../CommonInterfaces/CommonGraphicsAppInterface.h"
4 #include "../CommonInterfaces/CommonRenderInterface.h"
5 #include "PosixSharedMemory.h"
6 #include "Win32SharedMemory.h"
7 #include "../CommonInterfaces/CommonExampleInterface.h"
8 #include "LinearMath/btTransform.h"
9 #include "../CommonInterfaces/CommonGUIHelperInterface.h"
10 #include "Bullet3Common/b3AlignedObjectArray.h"
11 #include "GraphicsSharedMemoryBlock.h"
12 #include "../CommonInterfaces/CommonGUIHelperInterface.h"
13 #include "SharedMemoryPublic.h"
14 #include "../MultiThreading/b3ThreadSupportInterface.h"
15 #include "../Utils/b3Clock.h"
16
17 #ifdef BT_ENABLE_CLSOCKET
18
19 #include "PassiveSocket.h" // Include header for active socket object definition
20 #include <stdio.h>
21 #include "../CommonInterfaces/CommonGUIHelperInterface.h"
22 #include "Bullet3Common/b3CommandLineArgs.h"
23 #include "RemoteGUIHelper.h"
24 #include "GraphicsSharedMemoryPublic.h"
25 #include "GraphicsSharedMemoryCommands.h"
26
27
28 bool gVerboseNetworkMessagesServer = true;
29
MySerializeInt(unsigned int sz,unsigned char * output)30 void MySerializeInt(unsigned int sz, unsigned char* output)
31 {
32 unsigned int tmp = sz;
33 output[0] = tmp & 255;
34 tmp = tmp >> 8;
35 output[1] = tmp & 255;
36 tmp = tmp >> 8;
37 output[2] = tmp & 255;
38 tmp = tmp >> 8;
39 output[3] = tmp & 255;
40 }
41
submitStatus(CActiveSocket * pClient,GraphicsSharedMemoryStatus & serverStatus,b3AlignedObjectArray<char> & buffer)42 void submitStatus(CActiveSocket* pClient, GraphicsSharedMemoryStatus& serverStatus, b3AlignedObjectArray<char>& buffer)
43 {
44 b3AlignedObjectArray<unsigned char> packetData;
45 unsigned char* statBytes = (unsigned char*)&serverStatus;
46
47
48 //create packetData with [int packetSizeInBytes, status, streamBytes)
49 packetData.resize(4 + sizeof(GraphicsSharedMemoryStatus) + serverStatus.m_numDataStreamBytes);
50 int sz = packetData.size();
51 int curPos = 0;
52
53 if (gVerboseNetworkMessagesServer)
54 {
55 printf("buffer.size = %d\n", buffer.size());
56 printf("serverStatus packed size = %d\n", sz);
57 }
58
59 MySerializeInt(sz, &packetData[curPos]);
60 curPos += 4;
61 for (int i = 0; i < sizeof(GraphicsSharedMemoryStatus); i++)
62 {
63 packetData[i + curPos] = statBytes[i];
64 }
65 curPos += sizeof(GraphicsSharedMemoryStatus);
66 if (gVerboseNetworkMessagesServer)
67 printf("serverStatus.m_numDataStreamBytes=%d\n", serverStatus.m_numDataStreamBytes);
68 for (int i = 0; i < serverStatus.m_numDataStreamBytes; i++)
69 {
70 packetData[i + curPos] = buffer[i];
71 }
72
73 pClient->Send(&packetData[0], packetData.size());
74 if (gVerboseNetworkMessagesServer)
75 printf("pClient->Send serverStatus: %d\n", packetData.size());
76 }
77
78
79 #endif //BT_ENABLE_CLSOCKET
80
81
82 #define MAX_GRAPHICS_SHARED_MEMORY_BLOCKS 1
83
84
85 struct TCPArgs
86 {
TCPArgsTCPArgs87 TCPArgs()
88 : m_cs(0),
89 m_port(6667),
90 m_numClientCommands(0),
91 m_numServerCommands(0),
92 m_cmdPtr(0)
93 {
94 m_dataSlots.resize(10);
95 }
96
submitCommandTCPArgs97 void submitCommand()
98 {
99 m_cs->lock();
100 m_serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_FAILED;
101 m_serverStatus.m_numDataStreamBytes = 0;
102 btAssert(m_numServerCommands == m_numClientCommands);
103 m_numClientCommands++;
104 m_cs->unlock();
105 }
processCommandTCPArgs106 void processCommand()
107 {
108 m_cs->lock();
109 btAssert(m_numServerCommands == (m_numClientCommands - 1));
110 m_numServerCommands++;
111 m_cs->unlock();
112 }
isCommandOutstandingTCPArgs113 bool isCommandOutstanding()
114 {
115 m_cs->lock();
116 bool result = m_numClientCommands > m_numServerCommands;
117 m_cs->unlock();
118 return result;
119 }
120
121
122 b3CriticalSection* m_cs;
123 int m_port;
124 b3AlignedObjectArray< b3AlignedObjectArray<unsigned char> > m_dataSlots;
125 int m_numClientCommands;
126 int m_numServerCommands;
127 GraphicsSharedMemoryCommand* m_cmdPtr;
128 GraphicsSharedMemoryStatus m_serverStatus;
129 };
130
131 struct TCPThreadLocalStorage
132 {
133 int threadId;
134 };
135
136
137 enum TCPCommunicationEnums
138 {
139 eTCPRequestTerminate = 11,
140 eTCPIsUnInitialized,
141 eTCPIsInitialized,
142 eTCPInitializationFailed,
143 eTCPHasTerminated
144 };
145
TCPThreadFunc(void * userPtr,void * lsMemory)146 void TCPThreadFunc(void* userPtr, void* lsMemory)
147 {
148 printf("TCPThreadFunc thread started\n");
149
150 TCPArgs* args = (TCPArgs*)userPtr;
151 //int workLeft = true;
152 b3Clock clock;
153 clock.reset();
154 b3Clock sleepClock;
155 bool init = true;
156 if (init)
157 {
158 unsigned int cachedSharedParam = eTCPIsInitialized;
159
160 args->m_cs->lock();
161 args->m_cs->setSharedParam(0, eTCPIsInitialized);
162 args->m_cs->unlock();
163
164 double deltaTimeInSeconds = 0;
165 int numCmdSinceSleep1ms = 0;
166 unsigned long long int prevTime = clock.getTimeMicroseconds();
167
168 #ifdef BT_ENABLE_CLSOCKET
169 b3Clock clock;
170 double timeOutInSeconds = 10;
171
172
173 bool isPhysicsClientConnected = true;
174 bool exitRequested = false;
175
176
177 if (!isPhysicsClientConnected)
178 {
179 printf("TCP thread error connecting to shared memory. Machine needs a reboot?\n");
180 }
181 btAssert(isPhysicsClientConnected);
182
183 printf("Starting TCP server using port %d\n", args->m_port);
184
185 CPassiveSocket socket;
186 CActiveSocket* pClient = NULL;
187
188 //--------------------------------------------------------------------------
189 // Initialize our socket object
190 //--------------------------------------------------------------------------
191 socket.Initialize();
192
193 socket.Listen("localhost", args->m_port);
194
195 socket.SetBlocking();
196
197 int curNumErr = 0;
198
199 #endif
200
201 do
202 {
203
204 {
205 b3Clock::usleep(0);
206 }
207 ///////////////////////////////
208
209 #ifdef BT_ENABLE_CLSOCKET
210
211 {
212 b3Clock::usleep(0);
213
214 if ((pClient = socket.Accept()) != NULL)
215 {
216 socket.SetReceiveTimeout(60, 0);// (1, 0);
217 socket.SetSendTimeout(60, 0);
218
219 b3AlignedObjectArray<char> bytesReceived;
220
221 int clientPort = socket.GetClientPort();
222 if (gVerboseNetworkMessagesServer)
223 printf("connected from %s:%d\n", socket.GetClientAddr(), clientPort);
224
225 if (pClient->Receive(4))
226 {
227 int clientKey = *(int*)pClient->GetData();
228
229 if (clientKey == GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER)
230 {
231 printf("Client version OK %d\n", clientKey);
232 }
233 else
234 {
235 printf("Server version (%d) mismatches Client Version (%d)\n", GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER, clientKey);
236 continue;
237 }
238 }
239
240 //----------------------------------------------------------------------
241 // Receive request from the client.
242 //----------------------------------------------------------------------
243
244 while (cachedSharedParam != eTCPRequestTerminate)
245 {
246
247 bool receivedData = false;
248
249 int maxLen = 4 + sizeof(GraphicsSharedMemoryCommand) + GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE;
250
251
252 if (pClient->Receive(maxLen))
253 {
254
255 //heuristic to detect disconnected clients
256 CSimpleSocket::CSocketError err = pClient->GetSocketError();
257
258 if (err != CSimpleSocket::SocketSuccess || !pClient->IsSocketValid())
259 {
260 b3Clock::usleep(100);
261
262 curNumErr++;
263
264 if (curNumErr > 100)
265 {
266 ///printf("TCP Connection error = %d, curNumErr = %d\n", (int)err, curNumErr);
267
268 }
269 }
270
271 curNumErr = 0;
272 char* msg2 = (char*)pClient->GetData();
273 int numBytesRec2 = pClient->GetBytesReceived();
274 if (gVerboseNetworkMessagesServer)
275 printf("numBytesRec2=%d\n", numBytesRec2);
276 if (numBytesRec2 < 0)
277 {
278 numBytesRec2 = 0;
279 }
280 int curSize = bytesReceived.size();
281 bytesReceived.resize(bytesReceived.size() + numBytesRec2);
282 for (int i = 0; i < numBytesRec2; i++)
283 {
284 bytesReceived[curSize + i] = msg2[i];
285 }
286
287 if (bytesReceived.size() >= 4)
288 {
289 int numBytesRec = bytesReceived.size();
290 if (numBytesRec >= 10)
291 {
292 if (strncmp(&bytesReceived[0], "disconnect", 10) == 0)
293 {
294 printf("Disconnect request received\n");
295 bytesReceived.clear();
296 break;
297 }
298
299
300 }
301
302 if (gVerboseNetworkMessagesServer)
303 {
304 printf("received message length [%d]\n", numBytesRec);
305 }
306
307 receivedData = true;
308
309
310 args->m_cmdPtr = 0;
311
312
313 int type = *(int*)&bytesReceived[0];
314
315
316 if (numBytesRec == sizeof(GraphicsSharedMemoryCommand))
317 {
318 args->m_cmdPtr = (GraphicsSharedMemoryCommand*)&bytesReceived[0];
319 }
320
321 if (args->m_cmdPtr)
322 {
323
324 b3AlignedObjectArray<char> buffer;
325 buffer.resize(GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
326 bool hasStatus = true;
327 if (gVerboseNetworkMessagesServer)
328 printf("processing command:");
329 switch (args->m_cmdPtr->m_type)
330 {
331 case GFX_CMD_0:
332 {
333 int axis = args->m_cmdPtr->m_upAxisYCommand.m_enableUpAxisY ? 1 : 2;
334 args->submitCommand();
335 while (args->isCommandOutstanding())
336 {
337 clock.usleep(0);
338 }
339 bool done = false;
340 //guiHelper.setUpAxis(axis);
341
342
343 if (gVerboseNetworkMessagesServer)
344 printf("GFX_CMD_0\n");
345 break;
346 }
347
348 case GFX_CMD_SET_VISUALIZER_FLAG:
349 {
350 //disable single step rendering for GraphicsServer
351 if (args->m_cmdPtr->m_visualizerFlagCommand.m_visualizerFlag == COV_ENABLE_SINGLE_STEP_RENDERING)
352 {
353 args->m_cmdPtr->m_visualizerFlagCommand.m_visualizerFlag = 0;
354 }
355 args->submitCommand();
356 while (args->isCommandOutstanding())
357 {
358 clock.usleep(0);
359 }
360 //guiHelper.setVisualizerFlag(
361 // args->m_cmdPtr->m_visualizerFlagCommand.m_visualizerFlag,
362 // args->m_cmdPtr->m_visualizerFlagCommand.m_enable);
363 //serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_COMPLETED;
364 if (gVerboseNetworkMessagesServer)
365 printf("GFX_CMD_SET_VISUALIZER_FLAG\n");
366 break;
367 }
368 case GFX_CMD_UPLOAD_DATA:
369 {
370 int slot = args->m_cmdPtr->m_uploadDataCommand.m_dataSlot;
371
372 int numBytes = args->m_cmdPtr->m_uploadDataCommand.m_numBytes;
373
374
375 submitStatus(pClient, args->m_serverStatus, buffer);
376
377 //now receive numBytes
378 if (gVerboseNetworkMessagesServer)
379 printf("GFX_CMD_UPLOAD_DATA receiving data\n");
380 int received = 0;
381 int offset = 0;
382 args->m_dataSlots[slot].resize(numBytes);
383 while (received < numBytes)
384 {
385 if (pClient->Receive(args->m_cmdPtr->m_uploadDataCommand.m_numBytes))
386 {
387 //heuristic to detect disconnected clients
388 CSimpleSocket::CSocketError err = pClient->GetSocketError();
389 if (err != CSimpleSocket::SocketSuccess || !pClient->IsSocketValid())
390 {
391 curNumErr++;
392 //printf("TCP Connection error = %d, curNumErr = %d\n", (int)err, curNumErr);
393 }
394 char* msg2 = (char*)pClient->GetData();
395 int numBytesRec2 = pClient->GetBytesReceived();
396 if (gVerboseNetworkMessagesServer)
397 printf("received %d bytes (total=%d)\n", numBytesRec2, received);
398
399 for (int i = 0; i < numBytesRec2; i++)
400 {
401 args->m_dataSlots[slot][i+ offset] = msg2[i];
402 }
403 offset += numBytesRec2;
404 received += numBytesRec2;
405 }
406 }
407 if (gVerboseNetworkMessagesServer)
408 printf("received all bytes!\n");
409 args->m_serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_COMPLETED;
410 if (gVerboseNetworkMessagesServer)
411 printf("GFX_CMD_UPLOAD_DATA\n");
412 break;
413 }
414 case GFX_CMD_REGISTER_TEXTURE:
415 {
416 args->submitCommand();
417 while (args->isCommandOutstanding())
418 {
419 clock.usleep(0);
420 }
421 //const unsigned char* texels = (const unsigned char*)&args->m_dataSlots[0][0];
422 //args->m_serverStatus.m_registerTextureStatus.m_textureId = guiHelper.registerTexture(texels, args->m_cmdPtr->m_registerTextureCommand.m_width,
423 // args->m_cmdPtr->m_registerTextureCommand.m_height);
424 //serverStatus.m_type = GFX_CMD_REGISTER_TEXTURE_COMPLETED;
425 if (gVerboseNetworkMessagesServer)
426 printf("GFX_CMD_REGISTER_TEXTURE\n");
427 break;
428 }
429 case GFX_CMD_REGISTER_GRAPHICS_SHAPE:
430 {
431 args->submitCommand();
432 while (args->isCommandOutstanding())
433 {
434 clock.usleep(0);
435 }
436 if (gVerboseNetworkMessagesServer)
437 printf("GFX_CMD_REGISTER_GRAPHICS_SHAPE\n");
438 break;
439 }
440 case GFX_CMD_REGISTER_GRAPHICS_INSTANCE:
441 {
442 args->submitCommand();
443 while (args->isCommandOutstanding())
444 {
445 clock.usleep(0);
446 }
447
448 if (gVerboseNetworkMessagesServer)
449 printf("GFX_CMD_REGISTER_GRAPHICS_INSTANCE\n");
450 break;
451 }
452 case GFX_CMD_SYNCHRONIZE_TRANSFORMS:
453 {
454 args->submitCommand();
455 while (args->isCommandOutstanding())
456 {
457 clock.usleep(0);
458 }
459 if (gVerboseNetworkMessagesServer)
460 printf("GFX_CMD_SYNCHRONIZE_TRANSFORMS\n");
461 break;
462 }
463 case GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES:
464 {
465 args->submitCommand();
466 while (args->isCommandOutstanding())
467 {
468 clock.usleep(0);
469 }
470 if (gVerboseNetworkMessagesServer)
471 printf("GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES\n");
472 break;
473 }
474 case GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE:
475 {
476 args->submitCommand();
477 while (args->isCommandOutstanding())
478 {
479 clock.usleep(0);
480 }
481 if (gVerboseNetworkMessagesServer)
482 printf("GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE\n");
483 break;
484 }
485 case GFX_CMD_CHANGE_RGBA_COLOR:
486 {
487 args->submitCommand();
488 while (args->isCommandOutstanding())
489 {
490 clock.usleep(0);
491 }
492 if (gVerboseNetworkMessagesServer)
493 printf("GFX_CMD_CHANGE_RGBA_COLOR\n");
494 break;
495 }
496 case GFX_CMD_CHANGE_SCALING:
497 {
498 args->submitCommand();
499 while (args->isCommandOutstanding())
500 {
501 clock.usleep(0);
502 }
503 if (gVerboseNetworkMessagesServer)
504 printf("GFX_CMD_CHANGE_SCALING\n");
505 break;
506 }
507
508 case GFX_CMD_GET_CAMERA_INFO:
509 {
510 args->submitCommand();
511 while (args->isCommandOutstanding())
512 {
513 clock.usleep(0);
514 }
515 //bool RemoteGUIHelper::getCameraInfo(int* width, int* height,
516 // float viewMatrix[16], float projectionMatrix[16],
517 // float camUp[3], float camForward[3], float hor[3], float vert[3],
518 // float* yaw, float* pitch, float* camDist, float camTarget[3]) const
519 #if 0
520 guiHelper.getCameraInfo(&serverStatus.m_getCameraInfoStatus.width,
521 &serverStatus.m_getCameraInfoStatus.height,
522 serverStatus.m_getCameraInfoStatus.viewMatrix,
523 serverStatus.m_getCameraInfoStatus.projectionMatrix,
524 serverStatus.m_getCameraInfoStatus.camUp,
525 serverStatus.m_getCameraInfoStatus.camForward,
526 serverStatus.m_getCameraInfoStatus.hor,
527 serverStatus.m_getCameraInfoStatus.vert,
528 &serverStatus.m_getCameraInfoStatus.yaw,
529 &serverStatus.m_getCameraInfoStatus.pitch,
530 &serverStatus.m_getCameraInfoStatus.camDist,
531 serverStatus.m_getCameraInfoStatus.camTarget);
532 serverStatus.m_type = GFX_CMD_GET_CAMERA_INFO_COMPLETED;
533 #endif
534 if (gVerboseNetworkMessagesServer)
535 printf("GFX_CMD_GET_CAMERA_INFO\n");
536 break;
537 }
538
539 case GFX_CMD_INVALID:
540 case GFX_CMD_MAX_CLIENT_COMMANDS:
541 default:
542 {
543 printf("UNKNOWN COMMAND!\n");
544 btAssert(0);
545 hasStatus = false;
546 }
547 }
548
549
550 double startTimeSeconds = clock.getTimeInSeconds();
551 double curTimeSeconds = clock.getTimeInSeconds();
552
553 if (gVerboseNetworkMessagesServer)
554 {
555 //printf("buffer.size = %d\n", buffer.size());
556 printf("serverStatus.m_numDataStreamBytes = %d\n", args->m_serverStatus.m_numDataStreamBytes);
557 }
558 if (hasStatus)
559 {
560 submitStatus(pClient, args->m_serverStatus, buffer);
561 }
562
563 bytesReceived.clear();
564 }
565 else
566 {
567 //likely an incomplete packet, let's append more bytes
568 //printf("received packet with unknown contents\n");
569 }
570 }
571 }
572 if (!receivedData)
573 {
574 //printf("Didn't receive data.\n");
575 }
576 }
577
578 printf("Disconnecting client.\n");
579 pClient->Close();
580 delete pClient;
581 }
582 }
583
584 #endif //BT_ENABLE_CLSOCKET
585
586
587 ///////////////////////////////
588 args->m_cs->lock();
589 cachedSharedParam = args->m_cs->getSharedParam(0);
590 args->m_cs->unlock();
591
592 } while (cachedSharedParam != eTCPRequestTerminate);
593 #ifdef BT_ENABLE_CLSOCKET
594 socket.Close();
595 socket.Shutdown(CSimpleSocket::Both);
596 #endif
597 }
598 else
599 {
600 args->m_cs->lock();
601 args->m_cs->setSharedParam(0, eTCPInitializationFailed);
602 args->m_cs->unlock();
603 }
604
605 printf("TCPThreadFunc thread exit\n");
606 //do nothing
607 }
608
TCPlsMemoryFunc()609 void* TCPlsMemoryFunc()
610 {
611 //don't create local store memory, just return 0
612 return new TCPThreadLocalStorage;
613 }
614
TCPlsMemoryReleaseFunc(void * ptr)615 void TCPlsMemoryReleaseFunc(void* ptr)
616 {
617 TCPThreadLocalStorage* p = (TCPThreadLocalStorage*)ptr;
618 delete p;
619 }
620
621
622 #ifndef _WIN32
623 #include "../MultiThreading/b3PosixThreadSupport.h"
624
createTCPThreadSupport(int numThreads)625 b3ThreadSupportInterface* createTCPThreadSupport(int numThreads)
626 {
627 b3PosixThreadSupport::ThreadConstructionInfo constructionInfo("TCPThreads",
628 TCPThreadFunc,
629 TCPlsMemoryFunc,
630 TCPlsMemoryReleaseFunc,
631 numThreads);
632 b3ThreadSupportInterface* threadSupport = new b3PosixThreadSupport(constructionInfo);
633
634 return threadSupport;
635 }
636
637 #elif defined(_WIN32)
638 #include "../MultiThreading/b3Win32ThreadSupport.h"
639
createTCPThreadSupport(int numThreads)640 b3ThreadSupportInterface* createTCPThreadSupport(int numThreads)
641 {
642 b3Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("TCPThreads", TCPThreadFunc, TCPlsMemoryFunc, TCPlsMemoryReleaseFunc, numThreads);
643 b3Win32ThreadSupport* threadSupport = new b3Win32ThreadSupport(threadConstructionInfo);
644 return threadSupport;
645 }
646 #endif
647
648
649 class GraphicsServerExample : public CommonExampleInterface
650 {
651 CommonGraphicsApp* m_app;
652 GUIHelperInterface* m_guiHelper;
653
654 bool m_verboseOutput;
655
656 float m_x;
657 float m_y;
658 float m_z;
659
660 b3ThreadSupportInterface* m_threadSupport;
661 TCPArgs m_args;
662
663 public:
GraphicsServerExample(GUIHelperInterface * guiHelper)664 GraphicsServerExample(GUIHelperInterface* guiHelper)
665 : m_guiHelper(guiHelper),
666 m_x(0),
667 m_y(0),
668 m_z(0)
669 {
670 m_verboseOutput = true;
671
672 m_app = guiHelper->getAppInterface();
673 m_app->setUpAxis(2);
674
675 m_threadSupport = createTCPThreadSupport(1);
676 m_args.m_cs = m_threadSupport->createCriticalSection();
677 m_args.m_cs->setSharedParam(0, eTCPIsUnInitialized);
678 m_threadSupport->runTask(B3_THREAD_SCHEDULE_TASK, (void*)&this->m_args, 0);
679
680 bool isUninitialized = true;
681
682 while (isUninitialized)
683 {
684 m_args.m_cs->lock();
685 isUninitialized = (m_args.m_cs->getSharedParam(0) == eTCPIsUnInitialized);
686 m_args.m_cs->unlock();
687 #ifdef _WIN32
688 b3Clock::usleep(1000);
689 #endif
690 }
691
692 }
~GraphicsServerExample()693 virtual ~GraphicsServerExample()
694 {
695
696 m_args.m_cs->setSharedParam(0, eTCPRequestTerminate);
697
698 int numActiveThreads = 1;
699 while (numActiveThreads)
700 {
701 int arg0, arg1;
702 if (m_threadSupport->isTaskCompleted(&arg0, &arg1, 0))
703 {
704 numActiveThreads--;
705 printf("numActiveThreads = %d\n", numActiveThreads);
706 }
707 else
708 {
709 b3Clock::usleep(0);
710 }
711 };
712
713 m_threadSupport->deleteCriticalSection(m_args.m_cs);
714
715 delete m_threadSupport;
716 m_threadSupport = 0;
717
718 }
719
initPhysics()720 virtual void initPhysics()
721 {
722 }
exitPhysics()723 virtual void exitPhysics()
724 {
725 }
726
submitServerStatus(GraphicsSharedMemoryStatus & status,int blockIndex)727 void submitServerStatus(GraphicsSharedMemoryStatus& status, int blockIndex)
728 {
729 }
730
processCommand(const struct GraphicsSharedMemoryCommand & clientCmd,struct GraphicsSharedMemoryStatus & serverStatusOut)731 bool processCommand(const struct GraphicsSharedMemoryCommand& clientCmd, struct GraphicsSharedMemoryStatus& serverStatusOut)
732 {
733 //printf("processed command of type:%d\n", clientCmd.m_type);
734 B3_PROFILE("processCommand");
735 switch (clientCmd.m_type)
736 {
737 case GFX_CMD_0:
738 {
739 //either Y or Z can be up axis
740 int upAxis = (clientCmd.m_upAxisYCommand.m_enableUpAxisY) ? 1 : 2;
741 m_guiHelper->setUpAxis(upAxis);
742 serverStatusOut.m_type = GFX_CMD_CLIENT_COMMAND_COMPLETED;
743 m_args.processCommand();
744 break;
745 }
746 case GFX_CMD_SET_VISUALIZER_FLAG:
747 {
748 if ((clientCmd.m_visualizerFlagCommand.m_visualizerFlag != COV_ENABLE_RENDERING) &&
749 (clientCmd.m_visualizerFlagCommand.m_visualizerFlag != COV_ENABLE_SINGLE_STEP_RENDERING))
750 {
751 //printf("clientCmd.m_visualizerFlag.m_visualizerFlag: %d, clientCmd.m_visualizerFlag.m_enable %d\n",
752 // clientCmd.m_visualizerFlagCommand.m_visualizerFlag, clientCmd.m_visualizerFlagCommand.m_enable);
753
754 this->m_guiHelper->setVisualizerFlag(clientCmd.m_visualizerFlagCommand.m_visualizerFlag, clientCmd.m_visualizerFlagCommand.m_enable);
755 }
756 m_args.processCommand();
757 break;
758
759 }
760
761 case GFX_CMD_UPLOAD_DATA:
762 {
763 #if 0
764 //printf("uploadData command: curSize=%d, offset=%d, slot=%d", clientCmd.m_uploadDataCommand.m_numBytes, clientCmd.m_uploadDataCommand.m_dataOffset, clientCmd.m_uploadDataCommand.m_dataSlot);
765 int dataSlot = clientCmd.m_uploadDataCommand.m_dataSlot;
766 int dataOffset = clientCmd.m_uploadDataCommand.m_dataOffset;
767 m_dataSlots.resize(dataSlot + 1);
768 btAssert(m_dataSlots[dataSlot].size() >= dataOffset);
769 m_dataSlots[dataSlot].resize(clientCmd.m_uploadDataCommand.m_numBytes + clientCmd.m_uploadDataCommand.m_dataOffset);
770 for (int i = 0; i < clientCmd.m_uploadDataCommand.m_numBytes; i++)
771 {
772 m_dataSlots[dataSlot][dataOffset + i] = bufferServerToClient[i];
773 }
774 #endif
775 break;
776 }
777 case GFX_CMD_REGISTER_TEXTURE:
778 {
779
780 int dataSlot = 0;
781 int sizeData = m_args.m_dataSlots[dataSlot].size();
782 btAssert(sizeData > 0);
783 serverStatusOut.m_type = GFX_CMD_REGISTER_TEXTURE_FAILED;
784 if (sizeData)
785 {
786 unsigned char* texels = &m_args.m_dataSlots[dataSlot][0];
787 int textureId = this->m_guiHelper->registerTexture(texels, clientCmd.m_registerTextureCommand.m_width, clientCmd.m_registerTextureCommand.m_height);
788 serverStatusOut.m_type = GFX_CMD_REGISTER_TEXTURE_COMPLETED;
789 serverStatusOut.m_registerTextureStatus.m_textureId = textureId;
790 }
791
792 m_args.processCommand();
793 break;
794 }
795
796 case GFX_CMD_REGISTER_GRAPHICS_SHAPE:
797 {
798 int verticesSlot = 0;
799 int indicesSlot = 1;
800 serverStatusOut.m_type = GFX_CMD_REGISTER_GRAPHICS_SHAPE_FAILED;
801 const float* vertices = (const float*)&m_args.m_dataSlots[verticesSlot][0];
802 const int* indices = (const int*)&m_args.m_dataSlots[indicesSlot][0];
803 int numVertices = clientCmd.m_registerGraphicsShapeCommand.m_numVertices;
804 int numIndices = clientCmd.m_registerGraphicsShapeCommand.m_numIndices;
805 int primitiveType = clientCmd.m_registerGraphicsShapeCommand.m_primitiveType;
806 int textureId = clientCmd.m_registerGraphicsShapeCommand.m_textureId;
807 int shapeId = this->m_guiHelper->registerGraphicsShape(vertices, numVertices, indices, numIndices, primitiveType, textureId);
808 serverStatusOut.m_registerGraphicsShapeStatus.m_shapeId = shapeId;
809 serverStatusOut.m_type = GFX_CMD_REGISTER_GRAPHICS_SHAPE_COMPLETED;
810 m_args.processCommand();
811 break;
812 }
813
814 case GFX_CMD_REGISTER_GRAPHICS_INSTANCE:
815 {
816 int graphicsInstanceId = m_guiHelper->registerGraphicsInstance(clientCmd.m_registerGraphicsInstanceCommand.m_shapeIndex,
817 clientCmd.m_registerGraphicsInstanceCommand.m_position,
818 clientCmd.m_registerGraphicsInstanceCommand.m_quaternion,
819 clientCmd.m_registerGraphicsInstanceCommand.m_color,
820 clientCmd.m_registerGraphicsInstanceCommand.m_scaling);
821 serverStatusOut.m_registerGraphicsInstanceStatus.m_graphicsInstanceId = graphicsInstanceId;
822 serverStatusOut.m_type = GFX_CMD_REGISTER_GRAPHICS_INSTANCE_COMPLETED;
823 m_args.processCommand();
824 break;
825 }
826 case GFX_CMD_SYNCHRONIZE_TRANSFORMS:
827 {
828 GUISyncPosition* positions = (GUISyncPosition*)&m_args.m_dataSlots[0][0];
829 for (int i = 0; i < clientCmd.m_syncTransformsCommand.m_numPositions; i++)
830 {
831 m_app->m_renderer->writeSingleInstanceTransformToCPU(positions[i].m_pos, positions[i].m_orn, positions[i].m_graphicsInstanceId);
832 }
833 m_args.processCommand();
834 break;
835 }
836 case GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES:
837 {
838 m_guiHelper->removeAllGraphicsInstances();
839 m_args.processCommand();
840 break;
841 }
842 case GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE:
843 {
844 m_app->m_renderer->removeGraphicsInstance(clientCmd.m_removeGraphicsInstanceCommand.m_graphicsUid);
845 m_args.processCommand();
846 break;
847 }
848 case GFX_CMD_CHANGE_RGBA_COLOR:
849 {
850 m_guiHelper->changeRGBAColor(clientCmd.m_changeRGBAColorCommand.m_graphicsUid, clientCmd.m_changeRGBAColorCommand.m_rgbaColor);
851 m_args.processCommand();
852 break;
853 }
854
855 case GFX_CMD_CHANGE_SCALING:
856 {
857 m_guiHelper->changeScaling(clientCmd.m_changeScalingCommand.m_graphicsUid, clientCmd.m_changeScalingCommand.m_scaling);
858 m_args.processCommand();
859 break;
860 }
861
862 case GFX_CMD_GET_CAMERA_INFO:
863 {
864 serverStatusOut.m_type = GFX_CMD_GET_CAMERA_INFO_FAILED;
865
866 if (m_guiHelper->getCameraInfo(
867 &serverStatusOut.m_getCameraInfoStatus.width,
868 &serverStatusOut.m_getCameraInfoStatus.height,
869 serverStatusOut.m_getCameraInfoStatus.viewMatrix,
870 serverStatusOut.m_getCameraInfoStatus.projectionMatrix,
871 serverStatusOut.m_getCameraInfoStatus.camUp,
872 serverStatusOut.m_getCameraInfoStatus.camForward,
873 serverStatusOut.m_getCameraInfoStatus.hor,
874 serverStatusOut.m_getCameraInfoStatus.vert,
875 &serverStatusOut.m_getCameraInfoStatus.yaw,
876 &serverStatusOut.m_getCameraInfoStatus.pitch,
877 &serverStatusOut.m_getCameraInfoStatus.camDist,
878 serverStatusOut.m_getCameraInfoStatus.camTarget))
879 {
880 serverStatusOut.m_type = GFX_CMD_GET_CAMERA_INFO_COMPLETED;
881 }
882 m_args.processCommand();
883
884 break;
885 }
886 default:
887 {
888 printf("unsupported command:%d\n", clientCmd.m_type);
889 }
890 }
891 return true;
892 }
893
processClientCommands()894 void processClientCommands()
895 {
896 int timeStamp = 0;
897 bool hasStatus = false;
898 if (m_args.isCommandOutstanding())
899 {
900 processCommand(*m_args.m_cmdPtr, m_args.m_serverStatus);
901 }
902 //serverStatusOut.m_type = GFX_CMD_CLIENT_COMMAND_FAILED;
903 //bool hasStatus = processCommand(clientCmd, serverStatusOut);
904 if (hasStatus)
905 {
906 //submitServerStatus(serverStatusOut);
907 }
908 }
909
stepSimulation(float deltaTime)910 virtual void stepSimulation(float deltaTime)
911 {
912 B3_PROFILE("stepSimulation");
913 processClientCommands();
914 m_x += 0.01f;
915 m_y += 0.01f;
916 m_z += 0.01f;
917 }
918
919
renderScene()920 virtual void renderScene()
921 {
922 B3_PROFILE("renderScene");
923 {
924
925 B3_PROFILE("writeTransforms");
926 m_app->m_renderer->writeTransforms();
927 }
928 {
929 B3_PROFILE("m_renderer->renderScene");
930 m_app->m_renderer->renderScene();
931 }
932
933 }
934
935
936
physicsDebugDraw(int debugDrawFlags)937 virtual void physicsDebugDraw(int debugDrawFlags)
938 {
939
940 }
941
mouseMoveCallback(float x,float y)942 virtual bool mouseMoveCallback(float x, float y)
943 {
944 return false;
945 }
mouseButtonCallback(int button,int state,float x,float y)946 virtual bool mouseButtonCallback(int button, int state, float x, float y)
947 {
948 return false;
949 }
keyboardCallback(int key,int state)950 virtual bool keyboardCallback(int key, int state)
951 {
952 return false;
953 }
954
resetCamera()955 virtual void resetCamera()
956 {
957 float dist = 3.5;
958 float pitch = -32;
959 float yaw = 136;
960 float targetPos[3] = {0, 0, 0};
961 if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
962 {
963 m_app->m_renderer->getActiveCamera()->setCameraDistance(dist);
964 m_app->m_renderer->getActiveCamera()->setCameraPitch(pitch);
965 m_app->m_renderer->getActiveCamera()->setCameraYaw(yaw);
966 m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0], targetPos[1], targetPos[2]);
967 }
968 }
969
970
971 };
972
973
974
975
976
977
978
GraphicsServerCreateFuncBullet(struct CommonExampleOptions & options)979 CommonExampleInterface* GraphicsServerCreateFuncBullet(struct CommonExampleOptions& options)
980 {
981 return new GraphicsServerExample(options.m_guiHelper);
982 }
983