b3PluginManager.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. #include "b3PluginManager.h"
  2. #include "Bullet3Common/b3HashMap.h"
  3. #include "Bullet3Common/b3ResizablePool.h"
  4. #include "PhysicsClientC_API.h"
  5. #include "PhysicsDirect.h"
  6. #include "plugins/b3PluginContext.h"
  7. #include "../Utils/b3BulletDefaultFileIO.h"
  8. #include <string.h>
  9. #ifdef _WIN32
  10. #define WIN32_LEAN_AND_MEAN
  11. #define VC_EXTRALEAN
  12. #include <windows.h>
  13. typedef HMODULE B3_DYNLIB_HANDLE;
  14. #define B3_DYNLIB_OPEN LoadLibraryA
  15. #define B3_DYNLIB_CLOSE FreeLibrary
  16. #define B3_DYNLIB_IMPORT GetProcAddress
  17. #else
  18. #include <dlfcn.h>
  19. typedef void* B3_DYNLIB_HANDLE;
  20. #ifdef B3_USE_DLMOPEN
  21. #define B3_DYNLIB_OPEN(path) dlmopen(LM_ID_NEWLM, path, RTLD_LAZY)
  22. #else
  23. #define B3_DYNLIB_OPEN(path) dlopen(path, RTLD_NOW | RTLD_GLOBAL)
  24. #endif
  25. #define B3_DYNLIB_CLOSE dlclose
  26. #define B3_DYNLIB_IMPORT dlsym
  27. #endif
  28. struct b3Plugin
  29. {
  30. B3_DYNLIB_HANDLE m_pluginHandle;
  31. bool m_ownsPluginHandle;
  32. bool m_isInitialized;
  33. std::string m_pluginPath;
  34. std::string m_pluginPostFix;
  35. int m_pluginUniqueId;
  36. PFN_INIT m_initFunc;
  37. PFN_EXIT m_exitFunc;
  38. PFN_EXECUTE m_executeCommandFunc;
  39. PFN_TICK m_preTickFunc;
  40. PFN_TICK m_postTickFunc;
  41. PFN_TICK m_processNotificationsFunc;
  42. PFN_TICK m_processClientCommandsFunc;
  43. PFN_GET_RENDER_INTERFACE m_getRendererFunc;
  44. PFN_GET_COLLISION_INTERFACE m_getCollisionFunc;
  45. PFN_GET_FILEIO_INTERFACE m_getFileIOFunc;
  46. void* m_userPointer;
  47. b3UserDataValue* m_returnData;
  48. b3Plugin()
  49. : m_pluginHandle(0),
  50. m_ownsPluginHandle(false),
  51. m_isInitialized(false),
  52. m_pluginUniqueId(-1),
  53. m_initFunc(0),
  54. m_exitFunc(0),
  55. m_executeCommandFunc(0),
  56. m_preTickFunc(0),
  57. m_postTickFunc(0),
  58. m_processNotificationsFunc(0),
  59. m_processClientCommandsFunc(0),
  60. m_getRendererFunc(0),
  61. m_getCollisionFunc(0),
  62. m_getFileIOFunc(0),
  63. m_userPointer(0),
  64. m_returnData(0)
  65. {
  66. }
  67. void clear()
  68. {
  69. if (m_ownsPluginHandle)
  70. {
  71. B3_DYNLIB_CLOSE(m_pluginHandle);
  72. }
  73. m_pluginHandle = 0;
  74. m_initFunc = 0;
  75. m_exitFunc = 0;
  76. m_executeCommandFunc = 0;
  77. m_preTickFunc = 0;
  78. m_postTickFunc = 0;
  79. m_processNotificationsFunc = 0;
  80. m_processClientCommandsFunc = 0;
  81. m_getRendererFunc = 0;
  82. m_getCollisionFunc = 0;
  83. m_getFileIOFunc = 0;
  84. m_userPointer = 0;
  85. m_returnData = 0;
  86. m_isInitialized = false;
  87. }
  88. const char* GetMapKey() const
  89. {
  90. return GetMapKey(m_pluginPath.c_str(), m_pluginPostFix.c_str());
  91. }
  92. static const char* GetMapKey(const char* path, const char* postFix)
  93. {
  94. if (path != 0 && strlen(path) > 0)
  95. {
  96. return path;
  97. }
  98. else if (postFix != 0 && strlen(postFix) > 0)
  99. {
  100. return postFix;
  101. }
  102. return "";
  103. }
  104. };
  105. typedef b3PoolBodyHandle<b3Plugin> b3PluginHandle;
  106. struct b3PluginManagerInternalData
  107. {
  108. b3ResizablePool<b3PluginHandle> m_plugins;
  109. b3HashMap<b3HashString, int> m_pluginMap;
  110. PhysicsDirect* m_physicsDirect;
  111. PhysicsCommandProcessorInterface* m_rpcCommandProcessorInterface;
  112. b3AlignedObjectArray<b3KeyboardEvent> m_keyEvents;
  113. b3AlignedObjectArray<b3VRControllerEvent> m_vrEvents;
  114. b3AlignedObjectArray<b3MouseEvent> m_mouseEvents;
  115. b3AlignedObjectArray<b3Notification> m_notifications[2];
  116. int m_activeNotificationsBufferIndex;
  117. int m_activeRendererPluginUid;
  118. int m_activeCollisionPluginUid;
  119. int m_numNotificationPlugins;
  120. int m_activeFileIOPluginUid;
  121. b3BulletDefaultFileIO m_defaultFileIO;
  122. b3PluginManagerInternalData()
  123. : m_physicsDirect(0), m_rpcCommandProcessorInterface(0), m_activeNotificationsBufferIndex(0), m_activeRendererPluginUid(-1), m_activeCollisionPluginUid(-1), m_numNotificationPlugins(0), m_activeFileIOPluginUid(-1)
  124. {
  125. }
  126. };
  127. b3PluginManager::b3PluginManager(class PhysicsCommandProcessorInterface* physSdk)
  128. {
  129. m_data = new b3PluginManagerInternalData;
  130. m_data->m_rpcCommandProcessorInterface = physSdk;
  131. m_data->m_physicsDirect = new PhysicsDirect(physSdk, false);
  132. }
  133. b3PluginManager::~b3PluginManager()
  134. {
  135. while (m_data->m_pluginMap.size())
  136. {
  137. int* pluginUidPtr = m_data->m_pluginMap.getAtIndex(0);
  138. if (pluginUidPtr)
  139. {
  140. int pluginUid = *pluginUidPtr;
  141. unloadPlugin(*pluginUidPtr);
  142. }
  143. }
  144. delete m_data->m_physicsDirect;
  145. m_data->m_pluginMap.clear();
  146. m_data->m_plugins.exitHandles();
  147. delete m_data;
  148. }
  149. void b3PluginManager::addEvents(const struct b3VRControllerEvent* vrControllerEvents, int numVRControllerEvents, const struct b3KeyboardEvent* keyEvents, int numKeyEvents, const struct b3MouseEvent* mouseEvents, int numMouseEvents)
  150. {
  151. for (int i = 0; i < numKeyEvents; i++)
  152. {
  153. m_data->m_keyEvents.push_back(keyEvents[i]);
  154. }
  155. for (int i = 0; i < numVRControllerEvents; i++)
  156. {
  157. m_data->m_vrEvents.push_back(vrControllerEvents[i]);
  158. }
  159. for (int i = 0; i < numMouseEvents; i++)
  160. {
  161. m_data->m_mouseEvents.push_back(mouseEvents[i]);
  162. }
  163. }
  164. void b3PluginManager::clearEvents()
  165. {
  166. m_data->m_keyEvents.resize(0);
  167. m_data->m_vrEvents.resize(0);
  168. m_data->m_mouseEvents.resize(0);
  169. }
  170. void b3PluginManager::addNotification(const struct b3Notification& notification)
  171. {
  172. if (m_data->m_numNotificationPlugins > 0)
  173. {
  174. m_data->m_notifications[m_data->m_activeNotificationsBufferIndex].push_back(notification);
  175. }
  176. }
  177. int b3PluginManager::loadPlugin(const char* pluginPath, const char* postFixStr)
  178. {
  179. int pluginUniqueId = -1;
  180. int* pluginUidPtr = m_data->m_pluginMap.find(b3Plugin::GetMapKey(pluginPath, postFixStr));
  181. if (pluginUidPtr)
  182. {
  183. //already loaded
  184. pluginUniqueId = *pluginUidPtr;
  185. b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
  186. if (!plugin->m_isInitialized)
  187. {
  188. b3PluginContext context = {0};
  189. context.m_userPointer = 0;
  190. context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
  191. context.m_rpcCommandProcessorInterface = m_data->m_rpcCommandProcessorInterface;
  192. int result = plugin->m_initFunc(&context);
  193. plugin->m_isInitialized = true;
  194. plugin->m_userPointer = context.m_userPointer;
  195. }
  196. }
  197. else
  198. {
  199. pluginUniqueId = m_data->m_plugins.allocHandle();
  200. b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
  201. plugin->m_pluginUniqueId = pluginUniqueId;
  202. B3_DYNLIB_HANDLE pluginHandle = B3_DYNLIB_OPEN(pluginPath);
  203. bool ok = false;
  204. if (pluginHandle)
  205. {
  206. std::string postFix = postFixStr;
  207. std::string initStr = std::string("initPlugin") + postFix;
  208. std::string exitStr = std::string("exitPlugin") + postFix;
  209. std::string executePluginCommandStr = std::string("executePluginCommand") + postFix;
  210. std::string preTickPluginCallbackStr = std::string("preTickPluginCallback") + postFix;
  211. std::string postTickPluginCallback = std::string("postTickPluginCallback") + postFix;
  212. std::string processNotificationsStr = std::string("processNotifications") + postFix;
  213. std::string processClientCommandsStr = std::string("processClientCommands") + postFix;
  214. std::string getRendererStr = std::string("getRenderInterface") + postFix;
  215. std::string getCollisionStr = std::string("getCollisionInterface") + postFix;
  216. std::string getFileIOStr = std::string("getFileIOInterface") + postFix;
  217. plugin->m_initFunc = (PFN_INIT)B3_DYNLIB_IMPORT(pluginHandle, initStr.c_str());
  218. plugin->m_exitFunc = (PFN_EXIT)B3_DYNLIB_IMPORT(pluginHandle, exitStr.c_str());
  219. plugin->m_executeCommandFunc = (PFN_EXECUTE)B3_DYNLIB_IMPORT(pluginHandle, executePluginCommandStr.c_str());
  220. plugin->m_preTickFunc = (PFN_TICK)B3_DYNLIB_IMPORT(pluginHandle, preTickPluginCallbackStr.c_str());
  221. plugin->m_postTickFunc = (PFN_TICK)B3_DYNLIB_IMPORT(pluginHandle, postTickPluginCallback.c_str());
  222. plugin->m_processNotificationsFunc = (PFN_TICK)B3_DYNLIB_IMPORT(pluginHandle, processNotificationsStr.c_str());
  223. if (plugin->m_processNotificationsFunc)
  224. {
  225. m_data->m_numNotificationPlugins++;
  226. }
  227. plugin->m_processClientCommandsFunc = (PFN_TICK)B3_DYNLIB_IMPORT(pluginHandle, processClientCommandsStr.c_str());
  228. plugin->m_getRendererFunc = (PFN_GET_RENDER_INTERFACE)B3_DYNLIB_IMPORT(pluginHandle, getRendererStr.c_str());
  229. plugin->m_getCollisionFunc = (PFN_GET_COLLISION_INTERFACE)B3_DYNLIB_IMPORT(pluginHandle, getCollisionStr.c_str());
  230. plugin->m_getFileIOFunc = (PFN_GET_FILEIO_INTERFACE)B3_DYNLIB_IMPORT(pluginHandle, getFileIOStr.c_str());
  231. if (plugin->m_initFunc && plugin->m_exitFunc && plugin->m_executeCommandFunc)
  232. {
  233. b3PluginContext context;
  234. context.m_userPointer = plugin->m_userPointer;
  235. context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
  236. context.m_rpcCommandProcessorInterface = m_data->m_rpcCommandProcessorInterface;
  237. int version = plugin->m_initFunc(&context);
  238. plugin->m_isInitialized = true;
  239. //keep the user pointer persistent
  240. plugin->m_userPointer = context.m_userPointer;
  241. if (version == SHARED_MEMORY_MAGIC_NUMBER)
  242. {
  243. ok = true;
  244. plugin->m_ownsPluginHandle = true;
  245. plugin->m_pluginHandle = pluginHandle;
  246. plugin->m_pluginPath = pluginPath;
  247. plugin->m_pluginPostFix = postFixStr;
  248. m_data->m_pluginMap.insert(plugin->GetMapKey(), pluginUniqueId);
  249. }
  250. else
  251. {
  252. int expect = SHARED_MEMORY_MAGIC_NUMBER;
  253. b3Warning("Warning: plugin is wrong version: expected %d, got %d\n", expect, version);
  254. }
  255. }
  256. else
  257. {
  258. b3Warning("Loaded plugin but couldn't bind functions");
  259. }
  260. if (!ok)
  261. {
  262. B3_DYNLIB_CLOSE(pluginHandle);
  263. }
  264. }
  265. else
  266. {
  267. b3Warning("Warning: couldn't load plugin %s\n", pluginPath);
  268. #ifdef _WIN32
  269. #else
  270. b3Warning("Error: %s\n", dlerror());
  271. #endif
  272. }
  273. if (!ok)
  274. {
  275. m_data->m_plugins.freeHandle(pluginUniqueId);
  276. pluginUniqueId = -1;
  277. }
  278. }
  279. //for now, automatically select the loaded plugin as active renderer.
  280. if (pluginUniqueId >= 0)
  281. {
  282. b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
  283. if (plugin && plugin->m_getRendererFunc)
  284. {
  285. selectPluginRenderer(pluginUniqueId);
  286. }
  287. }
  288. //for now, automatically select the loaded plugin as active collision plugin.
  289. if (pluginUniqueId >= 0)
  290. {
  291. b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
  292. if (plugin && plugin->m_getCollisionFunc)
  293. {
  294. selectCollisionPlugin(pluginUniqueId);
  295. }
  296. }
  297. //for now, automatically select the loaded plugin as active fileIO plugin.
  298. if (pluginUniqueId >= 0)
  299. {
  300. b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
  301. if (plugin && plugin->m_getFileIOFunc)
  302. {
  303. selectFileIOPlugin(pluginUniqueId);
  304. }
  305. }
  306. return pluginUniqueId;
  307. }
  308. void b3PluginManager::unloadPlugin(int pluginUniqueId)
  309. {
  310. b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
  311. if (plugin)
  312. {
  313. if (plugin->m_processNotificationsFunc)
  314. {
  315. m_data->m_numNotificationPlugins--;
  316. }
  317. b3PluginContext context = {0};
  318. context.m_userPointer = plugin->m_userPointer;
  319. context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
  320. if (plugin->m_isInitialized)
  321. {
  322. plugin->m_exitFunc(&context);
  323. plugin->m_userPointer = 0;
  324. plugin->m_returnData = 0;
  325. plugin->m_isInitialized = false;
  326. }
  327. m_data->m_pluginMap.remove(plugin->GetMapKey());
  328. m_data->m_plugins.freeHandle(pluginUniqueId);
  329. }
  330. }
  331. void b3PluginManager::tickPlugins(double timeStep, b3PluginManagerTickMode tickMode)
  332. {
  333. for (int i = 0; i < m_data->m_pluginMap.size(); i++)
  334. {
  335. int* pluginUidPtr = m_data->m_pluginMap.getAtIndex(i);
  336. b3PluginHandle* plugin = 0;
  337. if (pluginUidPtr)
  338. {
  339. int pluginUid = *pluginUidPtr;
  340. plugin = m_data->m_plugins.getHandle(pluginUid);
  341. }
  342. else
  343. {
  344. continue;
  345. }
  346. PFN_TICK tick = 0;
  347. switch (tickMode)
  348. {
  349. case B3_PRE_TICK_MODE:
  350. {
  351. tick = plugin->m_preTickFunc;
  352. break;
  353. }
  354. case B3_POST_TICK_MODE:
  355. {
  356. tick = plugin->m_postTickFunc;
  357. break;
  358. }
  359. case B3_PROCESS_CLIENT_COMMANDS_TICK:
  360. {
  361. tick = plugin->m_processClientCommandsFunc;
  362. break;
  363. }
  364. default:
  365. {
  366. }
  367. }
  368. if (tick)
  369. {
  370. b3PluginContext context = {0};
  371. context.m_userPointer = plugin->m_userPointer;
  372. context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
  373. context.m_numMouseEvents = m_data->m_mouseEvents.size();
  374. context.m_mouseEvents = m_data->m_mouseEvents.size() ? &m_data->m_mouseEvents[0] : 0;
  375. context.m_numKeyEvents = m_data->m_keyEvents.size();
  376. context.m_keyEvents = m_data->m_keyEvents.size() ? &m_data->m_keyEvents[0] : 0;
  377. context.m_numVRControllerEvents = m_data->m_vrEvents.size();
  378. context.m_vrControllerEvents = m_data->m_vrEvents.size() ? &m_data->m_vrEvents[0] : 0;
  379. if (tickMode == B3_PROCESS_CLIENT_COMMANDS_TICK)
  380. {
  381. context.m_rpcCommandProcessorInterface = m_data->m_rpcCommandProcessorInterface;
  382. }
  383. int result = tick(&context);
  384. plugin->m_userPointer = context.m_userPointer;
  385. }
  386. }
  387. }
  388. void b3PluginManager::reportNotifications()
  389. {
  390. b3AlignedObjectArray<b3Notification>& notifications = m_data->m_notifications[m_data->m_activeNotificationsBufferIndex];
  391. if (notifications.size() == 0)
  392. {
  393. return;
  394. }
  395. // Swap notification buffers.
  396. m_data->m_activeNotificationsBufferIndex = 1 - m_data->m_activeNotificationsBufferIndex;
  397. for (int i = 0; i < m_data->m_pluginMap.size(); i++)
  398. {
  399. int* pluginUidPtr = m_data->m_pluginMap.getAtIndex(i);
  400. b3PluginHandle* plugin = 0;
  401. if (pluginUidPtr)
  402. {
  403. int pluginUid = *pluginUidPtr;
  404. plugin = m_data->m_plugins.getHandle(pluginUid);
  405. }
  406. else
  407. {
  408. continue;
  409. }
  410. if (plugin->m_processNotificationsFunc)
  411. {
  412. b3PluginContext context = {0};
  413. context.m_userPointer = plugin->m_userPointer;
  414. context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
  415. context.m_numNotifications = notifications.size();
  416. context.m_notifications = notifications.size() ? &notifications[0] : 0;
  417. plugin->m_processNotificationsFunc(&context);
  418. }
  419. }
  420. notifications.resize(0);
  421. }
  422. int b3PluginManager::executePluginCommand(int pluginUniqueId, const b3PluginArguments* arguments)
  423. {
  424. int result = -1;
  425. b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
  426. if (plugin)
  427. {
  428. b3PluginContext context = {0};
  429. context.m_userPointer = plugin->m_userPointer;
  430. context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
  431. context.m_rpcCommandProcessorInterface = m_data->m_rpcCommandProcessorInterface;
  432. result = plugin->m_executeCommandFunc(&context, arguments);
  433. plugin->m_userPointer = context.m_userPointer;
  434. plugin->m_returnData = context.m_returnData;
  435. }
  436. return result;
  437. }
  438. int b3PluginManager::registerStaticLinkedPlugin(const char* pluginPath, b3PluginFunctions& functions, bool initPlugin)
  439. {
  440. b3Plugin orgPlugin;
  441. int pluginUniqueId = m_data->m_plugins.allocHandle();
  442. b3PluginHandle* pluginHandle = m_data->m_plugins.getHandle(pluginUniqueId);
  443. pluginHandle->m_pluginHandle = 0;
  444. pluginHandle->m_ownsPluginHandle = false;
  445. pluginHandle->m_pluginUniqueId = pluginUniqueId;
  446. pluginHandle->m_executeCommandFunc = functions.m_executeCommandFunc;
  447. pluginHandle->m_exitFunc = functions.m_exitFunc;
  448. pluginHandle->m_initFunc = functions.m_initFunc;
  449. pluginHandle->m_preTickFunc = functions.m_preTickFunc;
  450. pluginHandle->m_postTickFunc = functions.m_postTickFunc;
  451. pluginHandle->m_getRendererFunc = functions.m_getRendererFunc;
  452. pluginHandle->m_getCollisionFunc = functions.m_getCollisionFunc;
  453. pluginHandle->m_processClientCommandsFunc = functions.m_processClientCommandsFunc;
  454. pluginHandle->m_getFileIOFunc = functions.m_fileIoFunc;
  455. pluginHandle->m_pluginHandle = 0;
  456. pluginHandle->m_pluginPath = pluginPath;
  457. pluginHandle->m_pluginPostFix = "";
  458. pluginHandle->m_userPointer = 0;
  459. pluginHandle->m_returnData = 0;
  460. if (pluginHandle->m_processNotificationsFunc)
  461. {
  462. m_data->m_numNotificationPlugins++;
  463. }
  464. m_data->m_pluginMap.insert(pluginHandle->GetMapKey(), pluginUniqueId);
  465. if (initPlugin)
  466. {
  467. b3PluginContext context = {0};
  468. context.m_userPointer = 0;
  469. context.m_returnData = 0;
  470. context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
  471. context.m_rpcCommandProcessorInterface = m_data->m_rpcCommandProcessorInterface;
  472. int result = pluginHandle->m_initFunc(&context);
  473. pluginHandle->m_isInitialized = true;
  474. pluginHandle->m_userPointer = context.m_userPointer;
  475. pluginHandle->m_returnData = 0;
  476. }
  477. return pluginUniqueId;
  478. }
  479. void b3PluginManager::selectPluginRenderer(int pluginUniqueId)
  480. {
  481. m_data->m_activeRendererPluginUid = pluginUniqueId;
  482. }
  483. UrdfRenderingInterface* b3PluginManager::getRenderInterface()
  484. {
  485. UrdfRenderingInterface* renderer = 0;
  486. if (m_data->m_activeRendererPluginUid >= 0)
  487. {
  488. b3PluginHandle* plugin = m_data->m_plugins.getHandle(m_data->m_activeRendererPluginUid);
  489. if (plugin && plugin->m_getRendererFunc)
  490. {
  491. b3PluginContext context = {0};
  492. context.m_userPointer = plugin->m_userPointer;
  493. context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
  494. renderer = plugin->m_getRendererFunc(&context);
  495. }
  496. }
  497. return renderer;
  498. }
  499. void b3PluginManager::selectFileIOPlugin(int pluginUniqueId)
  500. {
  501. m_data->m_activeFileIOPluginUid = pluginUniqueId;
  502. }
  503. struct CommonFileIOInterface* b3PluginManager::getFileIOInterface()
  504. {
  505. CommonFileIOInterface* fileIOInterface = 0;
  506. if (m_data->m_activeFileIOPluginUid >= 0)
  507. {
  508. b3PluginHandle* plugin = m_data->m_plugins.getHandle(m_data->m_activeFileIOPluginUid);
  509. if (plugin && plugin->m_getFileIOFunc)
  510. {
  511. b3PluginContext context = {0};
  512. context.m_userPointer = plugin->m_userPointer;
  513. context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
  514. fileIOInterface = plugin->m_getFileIOFunc(&context);
  515. }
  516. }
  517. if (fileIOInterface==0)
  518. {
  519. return &m_data->m_defaultFileIO;
  520. }
  521. return fileIOInterface;
  522. }
  523. void b3PluginManager::selectCollisionPlugin(int pluginUniqueId)
  524. {
  525. m_data->m_activeCollisionPluginUid = pluginUniqueId;
  526. }
  527. struct b3PluginCollisionInterface* b3PluginManager::getCollisionInterface()
  528. {
  529. b3PluginCollisionInterface* collisionInterface = 0;
  530. if (m_data->m_activeCollisionPluginUid >= 0)
  531. {
  532. b3PluginHandle* plugin = m_data->m_plugins.getHandle(m_data->m_activeCollisionPluginUid);
  533. if (plugin && plugin->m_getCollisionFunc)
  534. {
  535. b3PluginContext context = {0};
  536. context.m_userPointer = plugin->m_userPointer;
  537. context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
  538. collisionInterface = plugin->m_getCollisionFunc(&context);
  539. }
  540. }
  541. return collisionInterface;
  542. }
  543. const struct b3UserDataValue* b3PluginManager::getReturnData(int pluginUniqueId)
  544. {
  545. b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
  546. if (plugin)
  547. {
  548. return plugin->m_returnData;
  549. }
  550. return 0;
  551. }