PyBullet.addUserData / getUserData / removeUserData / getUserDataId / getNumUserData / getUserDataInfo
See examples/pybullet/examples/userData.py how to use it. TODO: add to PyBullet Quickstart Guide. Thanks to Tigran Gasparian for the contribution!
This commit is contained in:
@@ -11,16 +11,34 @@
|
||||
#include "../../Extras/Serialize/BulletFileLoader/autogenerated/bullet.h"
|
||||
#include "SharedMemoryBlock.h"
|
||||
#include "BodyJointInfoUtility.h"
|
||||
#include "SharedMemoryUserData.h"
|
||||
|
||||
|
||||
|
||||
struct UserDataCache
|
||||
{
|
||||
btHashMap<btHashInt, SharedMemoryUserData> m_userDataMap;
|
||||
btHashMap<btHashString, int> m_keyToUserDataIdMap;
|
||||
|
||||
UserDataCache()
|
||||
{
|
||||
}
|
||||
~UserDataCache()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct BodyJointInfoCache
|
||||
{
|
||||
std::string m_baseName;
|
||||
b3AlignedObjectArray<b3JointInfo> m_jointInfo;
|
||||
std::string m_bodyName;
|
||||
// Joint index -> user data.
|
||||
btHashMap<btHashInt, UserDataCache> m_jointToUserDataMap;
|
||||
|
||||
~BodyJointInfoCache()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct PhysicsClientSharedMemoryInternalData {
|
||||
@@ -28,32 +46,34 @@ struct PhysicsClientSharedMemoryInternalData {
|
||||
bool m_ownsSharedMemory;
|
||||
SharedMemoryBlock* m_testBlock1;
|
||||
|
||||
b3HashMap<b3HashInt,BodyJointInfoCache*> m_bodyJointMap;
|
||||
b3HashMap<b3HashInt,b3UserConstraint> m_userConstraintInfoMap;
|
||||
btHashMap<btHashInt,BodyJointInfoCache*> m_bodyJointMap;
|
||||
btHashMap<btHashInt,b3UserConstraint> m_userConstraintInfoMap;
|
||||
|
||||
b3AlignedObjectArray<TmpFloat3> m_debugLinesFrom;
|
||||
b3AlignedObjectArray<TmpFloat3> m_debugLinesTo;
|
||||
b3AlignedObjectArray<TmpFloat3> m_debugLinesColor;
|
||||
btAlignedObjectArray<TmpFloat3> m_debugLinesFrom;
|
||||
btAlignedObjectArray<TmpFloat3> m_debugLinesTo;
|
||||
btAlignedObjectArray<TmpFloat3> m_debugLinesColor;
|
||||
|
||||
int m_cachedCameraPixelsWidth;
|
||||
int m_cachedCameraPixelsHeight;
|
||||
b3AlignedObjectArray<unsigned char> m_cachedCameraPixelsRGBA;
|
||||
b3AlignedObjectArray<float> m_cachedCameraDepthBuffer;
|
||||
b3AlignedObjectArray<int> m_cachedSegmentationMaskBuffer;
|
||||
btAlignedObjectArray<unsigned char> m_cachedCameraPixelsRGBA;
|
||||
btAlignedObjectArray<float> m_cachedCameraDepthBuffer;
|
||||
btAlignedObjectArray<int> m_cachedSegmentationMaskBuffer;
|
||||
|
||||
b3AlignedObjectArray<b3ContactPointData> m_cachedContactPoints;
|
||||
b3AlignedObjectArray<b3OverlappingObject> m_cachedOverlappingObjects;
|
||||
b3AlignedObjectArray<b3VisualShapeData> m_cachedVisualShapes;
|
||||
b3AlignedObjectArray<b3CollisionShapeData> m_cachedCollisionShapes;
|
||||
btAlignedObjectArray<b3ContactPointData> m_cachedContactPoints;
|
||||
btAlignedObjectArray<b3OverlappingObject> m_cachedOverlappingObjects;
|
||||
btAlignedObjectArray<b3VisualShapeData> m_cachedVisualShapes;
|
||||
btAlignedObjectArray<b3CollisionShapeData> m_cachedCollisionShapes;
|
||||
|
||||
b3AlignedObjectArray<b3VRControllerEvent> m_cachedVREvents;
|
||||
b3AlignedObjectArray<b3KeyboardEvent> m_cachedKeyboardEvents;
|
||||
b3AlignedObjectArray<b3MouseEvent> m_cachedMouseEvents;
|
||||
b3AlignedObjectArray<double> m_cachedMassMatrix;
|
||||
b3AlignedObjectArray<b3RayHitInfo> m_raycastHits;
|
||||
btAlignedObjectArray<b3VRControllerEvent> m_cachedVREvents;
|
||||
btAlignedObjectArray<b3KeyboardEvent> m_cachedKeyboardEvents;
|
||||
btAlignedObjectArray<b3MouseEvent> m_cachedMouseEvents;
|
||||
btAlignedObjectArray<double> m_cachedMassMatrix;
|
||||
btAlignedObjectArray<b3RayHitInfo> m_raycastHits;
|
||||
|
||||
b3AlignedObjectArray<int> m_bodyIdsRequestInfo;
|
||||
b3AlignedObjectArray<int> m_constraintIdsRequestInfo;
|
||||
btAlignedObjectArray<int> m_bodyIdsRequestInfo;
|
||||
btAlignedObjectArray<int> m_constraintIdsRequestInfo;
|
||||
|
||||
btAlignedObjectArray<b3UserDataGlobalIdentifier> m_userDataIdsRequestInfo;
|
||||
|
||||
SharedMemoryStatus m_tempBackupServerStatus;
|
||||
|
||||
@@ -1285,6 +1305,33 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
|
||||
{
|
||||
break;
|
||||
}
|
||||
case CMD_SYNC_USER_DATA_FAILED:
|
||||
{
|
||||
b3Warning("Synchronizing user data failed.");
|
||||
break;
|
||||
}
|
||||
case CMD_REQUEST_USER_DATA_FAILED:
|
||||
{
|
||||
b3Warning("Requesting user data failed");
|
||||
break;
|
||||
}
|
||||
case CMD_ADD_USER_DATA_FAILED:
|
||||
{
|
||||
b3Warning("Adding user data failed (do the specified body and link exist?)");
|
||||
break;
|
||||
}
|
||||
case CMD_REMOVE_USER_DATA_FAILED:
|
||||
{
|
||||
b3Warning("Removing user data failed");
|
||||
break;
|
||||
}
|
||||
case CMD_REQUEST_USER_DATA_COMPLETED:
|
||||
case CMD_SYNC_USER_DATA_COMPLETED:
|
||||
case CMD_REMOVE_USER_DATA_COMPLETED:
|
||||
case CMD_ADD_USER_DATA_COMPLETED:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
b3Error("Unknown server status %d\n", serverCmd.m_type);
|
||||
btAssert(0);
|
||||
@@ -1336,6 +1383,94 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
|
||||
}
|
||||
}
|
||||
|
||||
if (serverCmd.m_type == CMD_SYNC_USER_DATA_COMPLETED) {
|
||||
B3_PROFILE("CMD_SYNC_USER_DATA_COMPLETED");
|
||||
const int numIdentifiers = serverCmd.m_syncUserDataArgs.m_numUserDataIdentifiers;
|
||||
if (numIdentifiers > 0) {
|
||||
m_data->m_tempBackupServerStatus = m_data->m_lastServerStatus;
|
||||
|
||||
const b3UserDataGlobalIdentifier *identifiers = (b3UserDataGlobalIdentifier *)m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor;
|
||||
for (int i=0; i<numIdentifiers; i++) {
|
||||
m_data->m_userDataIdsRequestInfo.push_back(identifiers[i]);
|
||||
}
|
||||
|
||||
// Request individual user data entries.
|
||||
const b3UserDataGlobalIdentifier userDataGlobalId = m_data->m_userDataIdsRequestInfo[m_data->m_userDataIdsRequestInfo.size()-1];
|
||||
m_data->m_userDataIdsRequestInfo.pop_back();
|
||||
|
||||
SharedMemoryCommand& command = m_data->m_testBlock1->m_clientCommands[0];
|
||||
command.m_type = CMD_REQUEST_USER_DATA;
|
||||
command.m_userDataRequestArgs = userDataGlobalId;
|
||||
submitClientCommand(command);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (serverCmd.m_type == CMD_ADD_USER_DATA_COMPLETED || serverCmd.m_type == CMD_REQUEST_USER_DATA_COMPLETED) {
|
||||
B3_PROFILE("CMD_ADD_USER_DATA_COMPLETED");
|
||||
const b3UserDataGlobalIdentifier userDataGlobalId = serverCmd.m_userDataResponseArgs.m_userDataGlobalId;
|
||||
BodyJointInfoCache** bodyJointsPtr = m_data->m_bodyJointMap[userDataGlobalId.m_bodyUniqueId];
|
||||
if (bodyJointsPtr && *bodyJointsPtr) {
|
||||
UserDataCache* userDataCachePtr = (*bodyJointsPtr)->m_jointToUserDataMap[userDataGlobalId.m_linkIndex];
|
||||
if (!userDataCachePtr)
|
||||
{
|
||||
UserDataCache cache;
|
||||
(*bodyJointsPtr)->m_jointToUserDataMap.insert(userDataGlobalId.m_linkIndex, cache);
|
||||
}
|
||||
userDataCachePtr = (*bodyJointsPtr)->m_jointToUserDataMap[userDataGlobalId.m_linkIndex];
|
||||
|
||||
const char *dataStream = m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor;
|
||||
|
||||
SharedMemoryUserData* userDataPtr = (userDataCachePtr)->m_userDataMap[userDataGlobalId.m_userDataId];
|
||||
if (userDataPtr) {
|
||||
// Only replace the value.
|
||||
userDataPtr->replaceValue(dataStream, serverCmd.m_userDataResponseArgs.m_valueLength, serverCmd.m_userDataResponseArgs.m_valueType);
|
||||
}
|
||||
else {
|
||||
// Add a new user data entry.
|
||||
const char *key = serverCmd.m_userDataResponseArgs.m_key;
|
||||
(userDataCachePtr)->m_userDataMap.insert(userDataGlobalId.m_userDataId, SharedMemoryUserData(key));
|
||||
(userDataCachePtr)->m_keyToUserDataIdMap.insert(key, userDataGlobalId.m_userDataId);
|
||||
userDataPtr = (userDataCachePtr)->m_userDataMap[userDataGlobalId.m_userDataId];
|
||||
userDataPtr->replaceValue(dataStream, serverCmd.m_userDataResponseArgs.m_valueLength, serverCmd.m_userDataResponseArgs.m_valueType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (serverCmd.m_type == CMD_REQUEST_USER_DATA_COMPLETED) {
|
||||
|
||||
if (m_data->m_userDataIdsRequestInfo.size() > 0) {
|
||||
// Request individual user data entries.
|
||||
const b3UserDataGlobalIdentifier userDataGlobalId = m_data->m_userDataIdsRequestInfo[m_data->m_userDataIdsRequestInfo.size()-1];
|
||||
m_data->m_userDataIdsRequestInfo.pop_back();
|
||||
|
||||
SharedMemoryCommand& command = m_data->m_testBlock1->m_clientCommands[0];
|
||||
command.m_type = CMD_REQUEST_USER_DATA;
|
||||
command.m_userDataRequestArgs = userDataGlobalId;
|
||||
submitClientCommand(command);
|
||||
return 0;
|
||||
}
|
||||
m_data->m_lastServerStatus = m_data->m_tempBackupServerStatus;
|
||||
}
|
||||
|
||||
if (serverCmd.m_type == CMD_REMOVE_USER_DATA_COMPLETED) {
|
||||
B3_PROFILE("CMD_REMOVE_USER_DATA_COMPLETED");
|
||||
const b3UserDataGlobalIdentifier userDataGlobalId = serverCmd.m_removeUserDataResponseArgs;
|
||||
BodyJointInfoCache** bodyJointsPtr = m_data->m_bodyJointMap[userDataGlobalId.m_bodyUniqueId];
|
||||
if (bodyJointsPtr && *bodyJointsPtr) {
|
||||
UserDataCache* userDataCachePtr = (*bodyJointsPtr)->m_jointToUserDataMap[userDataGlobalId.m_linkIndex];
|
||||
if (userDataCachePtr)
|
||||
{
|
||||
SharedMemoryUserData *userDataPtr = (userDataCachePtr)->m_userDataMap[userDataGlobalId.m_userDataId];
|
||||
if (userDataPtr)
|
||||
{
|
||||
(userDataCachePtr)->m_keyToUserDataIdMap.remove((userDataPtr)->m_key.c_str());
|
||||
(userDataCachePtr)->m_userDataMap.remove(userDataGlobalId.m_userDataId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (serverCmd.m_type == CMD_REMOVE_BODY_COMPLETED)
|
||||
{
|
||||
for (int i=0;i<serverCmd.m_removeObjectArgs.m_numBodies;i++)
|
||||
@@ -1663,3 +1798,73 @@ double PhysicsClientSharedMemory::getTimeOut() const
|
||||
{
|
||||
return m_data->m_timeOutInSeconds;
|
||||
}
|
||||
|
||||
bool PhysicsClientSharedMemory::getCachedUserData(int bodyUniqueId, int linkIndex, int userDataId, struct b3UserDataValue &valueOut) const {
|
||||
BodyJointInfoCache** bodyJointsPtr = m_data->m_bodyJointMap[bodyUniqueId];
|
||||
if (!bodyJointsPtr || !(*bodyJointsPtr)) {
|
||||
return false;
|
||||
}
|
||||
UserDataCache* userDataCachePtr = (*bodyJointsPtr)->m_jointToUserDataMap[linkIndex];
|
||||
if (!userDataCachePtr) {
|
||||
return false;
|
||||
}
|
||||
SharedMemoryUserData *userDataPtr = (userDataCachePtr)->m_userDataMap[userDataId];
|
||||
if (!userDataPtr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
valueOut.m_type = (userDataPtr)->m_type;
|
||||
valueOut.m_length = userDataPtr->m_bytes.size();
|
||||
valueOut.m_data1 = userDataPtr->m_bytes.size()? &userDataPtr->m_bytes[0] : 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int PhysicsClientSharedMemory::getCachedUserDataId(int bodyUniqueId, int linkIndex, const char *key) const {
|
||||
BodyJointInfoCache** bodyJointsPtr = m_data->m_bodyJointMap[bodyUniqueId];
|
||||
if (!bodyJointsPtr || !(*bodyJointsPtr)) {
|
||||
return -1;
|
||||
}
|
||||
UserDataCache* userDataCachePtr = (*bodyJointsPtr)->m_jointToUserDataMap[linkIndex];
|
||||
if (!userDataCachePtr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int *userDataId = (userDataCachePtr)->m_keyToUserDataIdMap[key];
|
||||
if (!userDataId) {
|
||||
return -1;
|
||||
}
|
||||
return *userDataId;
|
||||
}
|
||||
|
||||
int PhysicsClientSharedMemory::getNumUserData(int bodyUniqueId, int linkIndex) const {
|
||||
BodyJointInfoCache** bodyJointsPtr = m_data->m_bodyJointMap[bodyUniqueId];
|
||||
if (!bodyJointsPtr || !(*bodyJointsPtr)) {
|
||||
return 0;
|
||||
}
|
||||
UserDataCache* userDataCachePtr = (*bodyJointsPtr)->m_jointToUserDataMap[linkIndex];
|
||||
if (!userDataCachePtr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (userDataCachePtr)->m_userDataMap.size();
|
||||
}
|
||||
|
||||
void PhysicsClientSharedMemory::getUserDataInfo(int bodyUniqueId, int linkIndex, int userDataIndex, const char **keyOut, int *userDataIdOut) const {
|
||||
BodyJointInfoCache** bodyJointsPtr = m_data->m_bodyJointMap[bodyUniqueId];
|
||||
if (!bodyJointsPtr || !(*bodyJointsPtr))
|
||||
{
|
||||
*keyOut = 0;
|
||||
*userDataIdOut = -1;
|
||||
return;
|
||||
}
|
||||
UserDataCache* userDataCachePtr = (*bodyJointsPtr)->m_jointToUserDataMap[linkIndex];
|
||||
if (!userDataCachePtr || userDataIndex >= (userDataCachePtr)->m_userDataMap.size())
|
||||
{
|
||||
*keyOut = 0;
|
||||
*userDataIdOut = -1;
|
||||
return;
|
||||
}
|
||||
*userDataIdOut = (userDataCachePtr)->m_userDataMap.getKeyAtIndex(userDataIndex).getUid1();
|
||||
SharedMemoryUserData *userDataPtr = (userDataCachePtr)->m_userDataMap.getAtIndex(userDataIndex);
|
||||
*keyOut = (userDataPtr)->m_key.c_str();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user