PhysicsDirect.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. #include "PhysicsDirect.h"
  2. #include "PhysicsClientSharedMemory.h"
  3. #include "../CommonInterfaces/CommonGUIHelperInterface.h"
  4. #include "SharedMemoryCommands.h"
  5. #include "PhysicsServerCommandProcessor.h"
  6. #include "LinearMath/btHashMap.h"
  7. #include "LinearMath/btAlignedObjectArray.h"
  8. #include "../../Extras/Serialize/BulletFileLoader/btBulletFile.h"
  9. #include "../../Extras/Serialize/BulletFileLoader/autogenerated/bullet.h"
  10. #include "BodyJointInfoUtility.h"
  11. #include <string>
  12. struct BodyJointInfoCache2
  13. {
  14. std::string m_baseName;
  15. btAlignedObjectArray<b3JointInfo> m_jointInfo;
  16. };
  17. struct PhysicsDirectInternalData
  18. {
  19. DummyGUIHelper m_noGfx;
  20. SharedMemoryCommand m_command;
  21. SharedMemoryStatus m_serverStatus;
  22. bool m_hasStatus;
  23. bool m_verboseOutput;
  24. btAlignedObjectArray<TmpFloat3> m_debugLinesFrom;
  25. btAlignedObjectArray<TmpFloat3> m_debugLinesTo;
  26. btAlignedObjectArray<TmpFloat3> m_debugLinesColor;
  27. btHashMap<btHashInt,BodyJointInfoCache2*> m_bodyJointMap;
  28. char m_bulletStreamDataServerToClient[SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE];
  29. int m_cachedCameraPixelsWidth;
  30. int m_cachedCameraPixelsHeight;
  31. btAlignedObjectArray<unsigned char> m_cachedCameraPixelsRGBA;
  32. btAlignedObjectArray<float> m_cachedCameraDepthBuffer;
  33. btAlignedObjectArray<int> m_cachedSegmentationMask;
  34. btAlignedObjectArray<b3ContactPointData> m_cachedContactPoints;
  35. PhysicsServerCommandProcessor* m_commandProcessor;
  36. PhysicsDirectInternalData()
  37. :m_hasStatus(false),
  38. m_verboseOutput(false)
  39. {
  40. }
  41. };
  42. PhysicsDirect::PhysicsDirect()
  43. {
  44. m_data = new PhysicsDirectInternalData;
  45. m_data->m_commandProcessor = new PhysicsServerCommandProcessor;
  46. }
  47. PhysicsDirect::~PhysicsDirect()
  48. {
  49. delete m_data->m_commandProcessor;
  50. delete m_data;
  51. }
  52. // return true if connection succesfull, can also check 'isConnected'
  53. bool PhysicsDirect::connect()
  54. {
  55. m_data->m_commandProcessor->setGuiHelper(&m_data->m_noGfx);
  56. return true;
  57. }
  58. // return true if connection succesfull, can also check 'isConnected'
  59. bool PhysicsDirect::connect(struct GUIHelperInterface* guiHelper)
  60. {
  61. m_data->m_commandProcessor->setGuiHelper(guiHelper);
  62. return true;
  63. }
  64. void PhysicsDirect::renderScene()
  65. {
  66. m_data->m_commandProcessor->renderScene();
  67. }
  68. void PhysicsDirect::debugDraw(int debugDrawMode)
  69. {
  70. m_data->m_commandProcessor->physicsDebugDraw(debugDrawMode);
  71. }
  72. ////todo: rename to 'disconnect'
  73. void PhysicsDirect::disconnectSharedMemory()
  74. {
  75. m_data->m_commandProcessor->setGuiHelper(0);
  76. }
  77. bool PhysicsDirect::isConnected() const
  78. {
  79. return true;
  80. }
  81. // return non-null if there is a status, nullptr otherwise
  82. const SharedMemoryStatus* PhysicsDirect::processServerStatus()
  83. {
  84. SharedMemoryStatus* stat = 0;
  85. if (m_data->m_hasStatus)
  86. {
  87. stat = &m_data->m_serverStatus;
  88. m_data->m_hasStatus = false;
  89. }
  90. return stat;
  91. }
  92. SharedMemoryCommand* PhysicsDirect::getAvailableSharedMemoryCommand()
  93. {
  94. return &m_data->m_command;
  95. }
  96. bool PhysicsDirect::canSubmitCommand() const
  97. {
  98. return true;
  99. }
  100. bool PhysicsDirect::processDebugLines(const struct SharedMemoryCommand& orgCommand)
  101. {
  102. SharedMemoryCommand command = orgCommand;
  103. const SharedMemoryStatus& serverCmd = m_data->m_serverStatus;
  104. do
  105. {
  106. bool hasStatus = m_data->m_commandProcessor->processCommand(command,m_data->m_serverStatus,&m_data->m_bulletStreamDataServerToClient[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
  107. m_data->m_hasStatus = hasStatus;
  108. if (hasStatus)
  109. {
  110. btAssert(m_data->m_serverStatus.m_type == CMD_DEBUG_LINES_COMPLETED);
  111. if (m_data->m_verboseOutput)
  112. {
  113. b3Printf("Success receiving %d debug lines",
  114. serverCmd.m_sendDebugLinesArgs.m_numDebugLines);
  115. }
  116. int numLines = serverCmd.m_sendDebugLinesArgs.m_numDebugLines;
  117. float* linesFrom =
  118. (float*)&m_data->m_bulletStreamDataServerToClient[0];
  119. float* linesTo =
  120. (float*)(&m_data->m_bulletStreamDataServerToClient[0] +
  121. numLines * 3 * sizeof(float));
  122. float* linesColor =
  123. (float*)(&m_data->m_bulletStreamDataServerToClient[0] +
  124. 2 * numLines * 3 * sizeof(float));
  125. m_data->m_debugLinesFrom.resize(serverCmd.m_sendDebugLinesArgs.m_startingLineIndex +
  126. numLines);
  127. m_data->m_debugLinesTo.resize(serverCmd.m_sendDebugLinesArgs.m_startingLineIndex +
  128. numLines);
  129. m_data->m_debugLinesColor.resize(
  130. serverCmd.m_sendDebugLinesArgs.m_startingLineIndex + numLines);
  131. for (int i = 0; i < numLines; i++)
  132. {
  133. TmpFloat3 from = CreateTmpFloat3(linesFrom[i * 3], linesFrom[i * 3 + 1],
  134. linesFrom[i * 3 + 2]);
  135. TmpFloat3 to =
  136. CreateTmpFloat3(linesTo[i * 3], linesTo[i * 3 + 1], linesTo[i * 3 + 2]);
  137. TmpFloat3 color = CreateTmpFloat3(linesColor[i * 3], linesColor[i * 3 + 1],
  138. linesColor[i * 3 + 2]);
  139. m_data
  140. ->m_debugLinesFrom[serverCmd.m_sendDebugLinesArgs.m_startingLineIndex + i] =
  141. from;
  142. m_data->m_debugLinesTo[serverCmd.m_sendDebugLinesArgs.m_startingLineIndex + i] =
  143. to;
  144. m_data->m_debugLinesColor[serverCmd.m_sendDebugLinesArgs.m_startingLineIndex +
  145. i] = color;
  146. }
  147. if (serverCmd.m_sendDebugLinesArgs.m_numRemainingDebugLines > 0)
  148. {
  149. command.m_type = CMD_REQUEST_DEBUG_LINES;
  150. command.m_requestDebugLinesArguments.m_startingLineIndex =
  151. serverCmd.m_sendDebugLinesArgs.m_numDebugLines +
  152. serverCmd.m_sendDebugLinesArgs.m_startingLineIndex;
  153. }
  154. }
  155. } while (serverCmd.m_sendDebugLinesArgs.m_numRemainingDebugLines > 0);
  156. return m_data->m_hasStatus;
  157. }
  158. bool PhysicsDirect::processContactPointData(const struct SharedMemoryCommand& orgCommand)
  159. {
  160. SharedMemoryCommand command = orgCommand;
  161. const SharedMemoryStatus& serverCmd = m_data->m_serverStatus;
  162. do
  163. {
  164. bool hasStatus = m_data->m_commandProcessor->processCommand(command,m_data->m_serverStatus,&m_data->m_bulletStreamDataServerToClient[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
  165. m_data->m_hasStatus = hasStatus;
  166. if (hasStatus)
  167. {
  168. if (m_data->m_verboseOutput)
  169. {
  170. b3Printf("Contact Point Information Request OK\n");
  171. }
  172. int startContactIndex = serverCmd.m_sendContactPointArgs.m_startingContactPointIndex;
  173. int numContactsCopied = serverCmd.m_sendContactPointArgs.m_numContactPointsCopied;
  174. m_data->m_cachedContactPoints.resize(startContactIndex+numContactsCopied);
  175. b3ContactPointData* contactData = (b3ContactPointData*)&m_data->m_bulletStreamDataServerToClient[0];
  176. for (int i=0;i<numContactsCopied;i++)
  177. {
  178. m_data->m_cachedContactPoints[startContactIndex+i] = contactData[i];
  179. }
  180. if (serverCmd.m_sendContactPointArgs.m_numRemainingContactPoints>0 && serverCmd.m_sendContactPointArgs.m_numContactPointsCopied)
  181. {
  182. command.m_type = CMD_REQUEST_CONTACT_POINT_INFORMATION;
  183. command.m_requestContactPointArguments.m_startingContactPointIndex = serverCmd.m_sendContactPointArgs.m_startingContactPointIndex+serverCmd.m_sendContactPointArgs.m_numContactPointsCopied;
  184. command.m_requestContactPointArguments.m_objectAIndexFilter = -1;
  185. command.m_requestContactPointArguments.m_objectBIndexFilter = -1;
  186. }
  187. }
  188. } while (serverCmd.m_sendContactPointArgs.m_numRemainingContactPoints > 0 && serverCmd.m_sendContactPointArgs.m_numContactPointsCopied);
  189. return m_data->m_hasStatus;
  190. }
  191. bool PhysicsDirect::processCamera(const struct SharedMemoryCommand& orgCommand)
  192. {
  193. SharedMemoryCommand command = orgCommand;
  194. const SharedMemoryStatus& serverCmd = m_data->m_serverStatus;
  195. do
  196. {
  197. bool hasStatus = m_data->m_commandProcessor->processCommand(command,m_data->m_serverStatus,&m_data->m_bulletStreamDataServerToClient[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
  198. m_data->m_hasStatus = hasStatus;
  199. if (hasStatus)
  200. {
  201. btAssert(m_data->m_serverStatus.m_type == CMD_CAMERA_IMAGE_COMPLETED);
  202. if (m_data->m_verboseOutput)
  203. {
  204. b3Printf("Camera image OK\n");
  205. }
  206. int numBytesPerPixel = 4;//RGBA
  207. int numTotalPixels = serverCmd.m_sendPixelDataArguments.m_startingPixelIndex+
  208. serverCmd.m_sendPixelDataArguments.m_numPixelsCopied+
  209. serverCmd.m_sendPixelDataArguments.m_numRemainingPixels;
  210. m_data->m_cachedCameraPixelsWidth = 0;
  211. m_data->m_cachedCameraPixelsHeight = 0;
  212. int numPixels = serverCmd.m_sendPixelDataArguments.m_imageWidth*serverCmd.m_sendPixelDataArguments.m_imageHeight;
  213. m_data->m_cachedCameraPixelsRGBA.reserve(numPixels*numBytesPerPixel);
  214. m_data->m_cachedCameraDepthBuffer.resize(numTotalPixels);
  215. m_data->m_cachedSegmentationMask.resize(numTotalPixels);
  216. m_data->m_cachedCameraPixelsRGBA.resize(numTotalPixels*numBytesPerPixel);
  217. unsigned char* rgbaPixelsReceived =
  218. (unsigned char*)&m_data->m_bulletStreamDataServerToClient[0];
  219. float* depthBuffer = (float*)&(m_data->m_bulletStreamDataServerToClient[serverCmd.m_sendPixelDataArguments.m_numPixelsCopied*4]);
  220. int* segmentationMaskBuffer = (int*)&(m_data->m_bulletStreamDataServerToClient[serverCmd.m_sendPixelDataArguments.m_numPixelsCopied*8]);
  221. // printf("pixel = %d\n", rgbaPixelsReceived[0]);
  222. for (int i=0;i<serverCmd.m_sendPixelDataArguments.m_numPixelsCopied;i++)
  223. {
  224. m_data->m_cachedCameraDepthBuffer[i + serverCmd.m_sendPixelDataArguments.m_startingPixelIndex] = depthBuffer[i];
  225. }
  226. for (int i=0;i<serverCmd.m_sendPixelDataArguments.m_numPixelsCopied;i++)
  227. {
  228. m_data->m_cachedSegmentationMask[i + serverCmd.m_sendPixelDataArguments.m_startingPixelIndex] = segmentationMaskBuffer[i];
  229. }
  230. for (int i=0;i<serverCmd.m_sendPixelDataArguments.m_numPixelsCopied*numBytesPerPixel;i++)
  231. {
  232. m_data->m_cachedCameraPixelsRGBA[i + serverCmd.m_sendPixelDataArguments.m_startingPixelIndex*numBytesPerPixel]
  233. = rgbaPixelsReceived[i];
  234. }
  235. if (serverCmd.m_sendPixelDataArguments.m_numRemainingPixels > 0 && serverCmd.m_sendPixelDataArguments.m_numPixelsCopied)
  236. {
  237. // continue requesting remaining pixels
  238. command.m_type = CMD_REQUEST_CAMERA_IMAGE_DATA;
  239. command.m_requestPixelDataArguments.m_startPixelIndex =
  240. serverCmd.m_sendPixelDataArguments.m_startingPixelIndex +
  241. serverCmd.m_sendPixelDataArguments.m_numPixelsCopied;
  242. } else
  243. {
  244. m_data->m_cachedCameraPixelsWidth = serverCmd.m_sendPixelDataArguments.m_imageWidth;
  245. m_data->m_cachedCameraPixelsHeight = serverCmd.m_sendPixelDataArguments.m_imageHeight;
  246. }
  247. }
  248. } while (serverCmd.m_sendPixelDataArguments.m_numRemainingPixels > 0 && serverCmd.m_sendPixelDataArguments.m_numPixelsCopied);
  249. return m_data->m_hasStatus;
  250. }
  251. void PhysicsDirect::processBodyJointInfo(int bodyUniqueId, const SharedMemoryStatus& serverCmd)
  252. {
  253. bParse::btBulletFile bf(
  254. &m_data->m_bulletStreamDataServerToClient[0],
  255. serverCmd.m_dataStreamArguments.m_streamChunkLength);
  256. bf.setFileDNAisMemoryDNA();
  257. bf.parse(false);
  258. BodyJointInfoCache2* bodyJoints = new BodyJointInfoCache2;
  259. m_data->m_bodyJointMap.insert(bodyUniqueId,bodyJoints);
  260. for (int i = 0; i < bf.m_multiBodies.size(); i++)
  261. {
  262. int flag = bf.getFlags();
  263. if ((flag & bParse::FD_DOUBLE_PRECISION) != 0)
  264. {
  265. Bullet::btMultiBodyDoubleData* mb =
  266. (Bullet::btMultiBodyDoubleData*)bf.m_multiBodies[i];
  267. bodyJoints->m_baseName = mb->m_baseName;
  268. addJointInfoFromMultiBodyData(mb,bodyJoints, m_data->m_verboseOutput);
  269. } else
  270. {
  271. Bullet::btMultiBodyFloatData* mb =
  272. (Bullet::btMultiBodyFloatData*)bf.m_multiBodies[i];
  273. bodyJoints->m_baseName = mb->m_baseName;
  274. addJointInfoFromMultiBodyData(mb,bodyJoints, m_data->m_verboseOutput);
  275. }
  276. }
  277. if (bf.ok()) {
  278. if (m_data->m_verboseOutput)
  279. {
  280. b3Printf("Received robot description ok!\n");
  281. }
  282. } else
  283. {
  284. b3Warning("Robot description not received");
  285. }
  286. }
  287. bool PhysicsDirect::submitClientCommand(const struct SharedMemoryCommand& command)
  288. {
  289. if (command.m_type==CMD_REQUEST_DEBUG_LINES)
  290. {
  291. return processDebugLines(command);
  292. }
  293. if (command.m_type==CMD_REQUEST_CAMERA_IMAGE_DATA)
  294. {
  295. return processCamera(command);
  296. }
  297. if (command.m_type == CMD_REQUEST_CONTACT_POINT_INFORMATION)
  298. {
  299. return processContactPointData(command);
  300. }
  301. bool hasStatus = m_data->m_commandProcessor->processCommand(command,m_data->m_serverStatus,&m_data->m_bulletStreamDataServerToClient[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
  302. m_data->m_hasStatus = hasStatus;
  303. if (hasStatus)
  304. {
  305. const SharedMemoryStatus& serverCmd = m_data->m_serverStatus;
  306. switch (m_data->m_serverStatus.m_type)
  307. {
  308. case CMD_RESET_SIMULATION_COMPLETED:
  309. {
  310. m_data->m_debugLinesFrom.clear();
  311. m_data->m_debugLinesTo.clear();
  312. m_data->m_debugLinesColor.clear();
  313. for (int i=0;i<m_data->m_bodyJointMap.size();i++)
  314. {
  315. BodyJointInfoCache2** bodyJointsPtr = m_data->m_bodyJointMap.getAtIndex(i);
  316. if (bodyJointsPtr && *bodyJointsPtr)
  317. {
  318. BodyJointInfoCache2* bodyJoints = *bodyJointsPtr;
  319. for (int j=0;j<bodyJoints->m_jointInfo.size();j++) {
  320. if (bodyJoints->m_jointInfo[j].m_jointName)
  321. {
  322. free(bodyJoints->m_jointInfo[j].m_jointName);
  323. }
  324. if (bodyJoints->m_jointInfo[j].m_linkName)
  325. {
  326. free(bodyJoints->m_jointInfo[j].m_linkName);
  327. }
  328. }
  329. delete (*bodyJointsPtr);
  330. }
  331. }
  332. m_data->m_bodyJointMap.clear();
  333. break;
  334. }
  335. case CMD_SDF_LOADING_COMPLETED:
  336. {
  337. //we'll stream further info from the physics server
  338. //so serverCmd will be invalid, make a copy
  339. int numBodies = serverCmd.m_sdfLoadedArgs.m_numBodies;
  340. for (int i=0;i<numBodies;i++)
  341. {
  342. int bodyUniqueId = serverCmd.m_sdfLoadedArgs.m_bodyUniqueIds[i];
  343. SharedMemoryCommand infoRequestCommand;
  344. infoRequestCommand.m_type = CMD_REQUEST_BODY_INFO;
  345. infoRequestCommand.m_sdfRequestInfoArgs.m_bodyUniqueId = bodyUniqueId;
  346. SharedMemoryStatus infoStatus;
  347. bool hasStatus = m_data->m_commandProcessor->processCommand(infoRequestCommand,infoStatus,&m_data->m_bulletStreamDataServerToClient[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
  348. if (hasStatus)
  349. {
  350. processBodyJointInfo(bodyUniqueId, infoStatus);
  351. }
  352. }
  353. break;
  354. }
  355. case CMD_URDF_LOADING_COMPLETED:
  356. {
  357. if (serverCmd.m_dataStreamArguments.m_streamChunkLength > 0)
  358. {
  359. int bodyIndex = serverCmd.m_dataStreamArguments.m_bodyUniqueId;
  360. processBodyJointInfo(bodyIndex,serverCmd);
  361. }
  362. break;
  363. }
  364. default:
  365. {
  366. // b3Error("Unknown server status type");
  367. }
  368. };
  369. }
  370. return hasStatus;
  371. }
  372. int PhysicsDirect::getNumBodies() const
  373. {
  374. return m_data->m_bodyJointMap.size();
  375. }
  376. int PhysicsDirect::getBodyUniqueId(int serialIndex) const
  377. {
  378. if ((serialIndex >= 0) && (serialIndex < getNumBodies()))
  379. {
  380. return m_data->m_bodyJointMap.getKeyAtIndex(serialIndex).getUid1();
  381. }
  382. return -1;
  383. }
  384. bool PhysicsDirect::getBodyInfo(int bodyUniqueId, struct b3BodyInfo& info) const
  385. {
  386. BodyJointInfoCache2** bodyJointsPtr = m_data->m_bodyJointMap[bodyUniqueId];
  387. if (bodyJointsPtr && *bodyJointsPtr)
  388. {
  389. BodyJointInfoCache2* bodyJoints = *bodyJointsPtr;
  390. info.m_baseName = bodyJoints->m_baseName.c_str();
  391. return true;
  392. }
  393. return false;
  394. }
  395. int PhysicsDirect::getNumJoints(int bodyIndex) const
  396. {
  397. BodyJointInfoCache2** bodyJointsPtr = m_data->m_bodyJointMap[bodyIndex];
  398. if (bodyJointsPtr && *bodyJointsPtr)
  399. {
  400. BodyJointInfoCache2* bodyJoints = *bodyJointsPtr;
  401. return bodyJoints->m_jointInfo.size();
  402. }
  403. btAssert(0);
  404. return 0;
  405. }
  406. bool PhysicsDirect::getJointInfo(int bodyIndex, int jointIndex, struct b3JointInfo& info) const
  407. {
  408. BodyJointInfoCache2** bodyJointsPtr = m_data->m_bodyJointMap[bodyIndex];
  409. if (bodyJointsPtr && *bodyJointsPtr)
  410. {
  411. BodyJointInfoCache2* bodyJoints = *bodyJointsPtr;
  412. if (jointIndex < bodyJoints->m_jointInfo.size())
  413. {
  414. info = bodyJoints->m_jointInfo[jointIndex];
  415. return true;
  416. }
  417. }
  418. return false;
  419. }
  420. ///todo: move this out of the
  421. void PhysicsDirect::setSharedMemoryKey(int key)
  422. {
  423. //m_data->m_physicsServer->setSharedMemoryKey(key);
  424. //m_data->m_physicsClient->setSharedMemoryKey(key);
  425. }
  426. void PhysicsDirect::uploadBulletFileToSharedMemory(const char* data, int len)
  427. {
  428. //m_data->m_physicsClient->uploadBulletFileToSharedMemory(data,len);
  429. }
  430. int PhysicsDirect::getNumDebugLines() const
  431. {
  432. return m_data->m_debugLinesFrom.size();
  433. }
  434. const float* PhysicsDirect::getDebugLinesFrom() const
  435. {
  436. if (getNumDebugLines())
  437. {
  438. return &m_data->m_debugLinesFrom[0].m_x;
  439. }
  440. return 0;
  441. }
  442. const float* PhysicsDirect::getDebugLinesTo() const
  443. {
  444. if (getNumDebugLines())
  445. {
  446. return &m_data->m_debugLinesTo[0].m_x;
  447. }
  448. return 0;
  449. }
  450. const float* PhysicsDirect::getDebugLinesColor() const
  451. {
  452. if (getNumDebugLines())
  453. {
  454. return &m_data->m_debugLinesColor[0].m_x;
  455. }
  456. return 0;
  457. }
  458. void PhysicsDirect::getCachedCameraImage(b3CameraImageData* cameraData)
  459. {
  460. if (cameraData)
  461. {
  462. cameraData->m_pixelWidth = m_data->m_cachedCameraPixelsWidth;
  463. cameraData->m_pixelHeight = m_data->m_cachedCameraPixelsHeight;
  464. cameraData->m_depthValues = m_data->m_cachedCameraDepthBuffer.size() ? &m_data->m_cachedCameraDepthBuffer[0] : 0;
  465. cameraData->m_rgbColorData = m_data->m_cachedCameraPixelsRGBA.size() ? &m_data->m_cachedCameraPixelsRGBA[0] : 0;
  466. cameraData->m_segmentationMaskValues = m_data->m_cachedSegmentationMask.size()? &m_data->m_cachedSegmentationMask[0] : 0;
  467. }
  468. }
  469. void PhysicsDirect::getCachedContactPointInformation(struct b3ContactInformation* contactPointData)
  470. {
  471. contactPointData->m_numContactPoints = m_data->m_cachedContactPoints.size();
  472. contactPointData->m_contactPointData = contactPointData->m_numContactPoints? &m_data->m_cachedContactPoints[0] : 0;
  473. }