GraphicsServerExample.cpp 27 KB

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