mirror of
https://github.com/bulletphysics/bullet3
synced 2025-01-18 21:10:05 +00:00
add physics server loopback (both client and server in the same process, using shared memory)
add physics server direct (client and server in the same process, directly processing commands without shared memory transport mechanism)
This commit is contained in:
parent
7d6c2b77f7
commit
03bf78ef49
@ -23,6 +23,17 @@ SET(App_ExampleBrowser_SRCS
|
||||
../SharedMemory/PhysicsClientExample.cpp
|
||||
../SharedMemory/PosixSharedMemory.cpp
|
||||
../SharedMemory/Win32SharedMemory.cpp
|
||||
../SharedMemory/PhysicsServerSharedMemory.cpp
|
||||
../SharedMemory/PhysicsDirect.cpp
|
||||
../SharedMemory/PhysicsDirect.h
|
||||
../SharedMemory/PhysicsDirectC_API.cpp
|
||||
../SharedMemory/PhysicsDirectC_API.h
|
||||
../SharedMemory/PhysicsLoopBack.cpp
|
||||
../SharedMemory/PhysicsLoopBack.h
|
||||
../SharedMemory/PhysicsLoopBackC_Api.cpp
|
||||
../SharedMemory/PhysicsLoopBackC_Api.h
|
||||
../SharedMemory/PhysicsServerCommandProcessor.cpp
|
||||
../SharedMemory/PhysicsServerCommandProcessor.h
|
||||
../BasicDemo/BasicExample.cpp
|
||||
../BasicDemo/BasicExample.h
|
||||
../ForkLift/ForkLiftDemo.cpp
|
||||
|
@ -57,10 +57,21 @@
|
||||
"../SharedMemory/PhysicsServerExample.cpp",
|
||||
"../SharedMemory/PhysicsClientExample.cpp",
|
||||
"../SharedMemory/PhysicsServer.cpp",
|
||||
"../SharedMemory/PhysicsServerSharedMemory.cpp",
|
||||
"../SharedMemory/PhysicsClientSharedMemory.cpp",
|
||||
"../SharedMemory/PhysicsClient.cpp",
|
||||
"../SharedMemory/PosixSharedMemory.cpp",
|
||||
"../SharedMemory/Win32SharedMemory.cpp",
|
||||
"../SharedMemory/PhysicsDirect.cpp",
|
||||
"../SharedMemory/PhysicsDirect.h",
|
||||
"../SharedMemory/PhysicsDirectC_API.cpp",
|
||||
"../SharedMemory/PhysicsDirectC_API.h",
|
||||
"../SharedMemory/PhysicsLoopBack.cpp",
|
||||
"../SharedMemory/PhysicsLoopBack.h",
|
||||
"../SharedMemory/PhysicsLoopBackC_Api.cpp",
|
||||
"../SharedMemory/PhysicsLoopBackC_Api.h",
|
||||
"../SharedMemory/PhysicsServerCommandProcessor.cpp",
|
||||
"../SharedMemory/PhysicsServerCommandProcessor.h",
|
||||
"../MultiThreading/MultiThreadingExample.cpp",
|
||||
"../MultiThreading/b3PosixThreadSupport.cpp",
|
||||
"../MultiThreading/b3Win32ThreadSupport.cpp",
|
||||
|
75
examples/SharedMemory/BodyJointInfoUtility.h
Normal file
75
examples/SharedMemory/BodyJointInfoUtility.h
Normal file
@ -0,0 +1,75 @@
|
||||
#ifndef BODY_JOINT_INFO_UTILITY_H
|
||||
#define BODY_JOINT_INFO_UTILITY_H
|
||||
|
||||
#include "Bullet3Common/b3Logging.h"
|
||||
|
||||
namespace Bullet
|
||||
{
|
||||
class btMultiBodyDoubleData;
|
||||
class btMultiBodyFloatData;
|
||||
};
|
||||
|
||||
inline char* strDup(const char* const str)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _strdup(str);
|
||||
#else
|
||||
return strdup(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T, typename U> void addJointInfoFromMultiBodyData(const T* mb, U* bodyJoints, bool verboseOutput)
|
||||
{
|
||||
if (mb->m_baseName)
|
||||
{
|
||||
if (verboseOutput)
|
||||
{
|
||||
b3Printf("mb->m_baseName = %s\n", mb->m_baseName);
|
||||
}
|
||||
}
|
||||
int qOffset = 7;
|
||||
int uOffset = 6;
|
||||
|
||||
for (int link = 0; link < mb->m_numLinks; link++)
|
||||
{
|
||||
{
|
||||
b3JointInfo info;
|
||||
info.m_flags = 0;
|
||||
info.m_jointIndex = link;
|
||||
info.m_qIndex =
|
||||
(0 < mb->m_links[link].m_posVarCount) ? qOffset : -1;
|
||||
info.m_uIndex =
|
||||
(0 < mb->m_links[link].m_dofCount) ? uOffset : -1;
|
||||
|
||||
if (mb->m_links[link].m_linkName) {
|
||||
if (verboseOutput) {
|
||||
b3Printf("mb->m_links[%d].m_linkName = %s\n", link,
|
||||
mb->m_links[link].m_linkName);
|
||||
}
|
||||
info.m_linkName = strDup(mb->m_links[link].m_linkName);
|
||||
}
|
||||
if (mb->m_links[link].m_jointName) {
|
||||
if (verboseOutput) {
|
||||
b3Printf("mb->m_links[%d].m_jointName = %s\n", link,
|
||||
mb->m_links[link].m_jointName);
|
||||
}
|
||||
info.m_jointName = strDup(mb->m_links[link].m_jointName);
|
||||
}
|
||||
|
||||
info.m_jointType = mb->m_links[link].m_jointType;
|
||||
|
||||
if ((mb->m_links[link].m_jointType == eRevoluteType) ||
|
||||
(mb->m_links[link].m_jointType == ePrismaticType)) {
|
||||
info.m_flags |= JOINT_HAS_MOTORIZED_POWER;
|
||||
}
|
||||
bodyJoints->m_jointInfo.push_back(info);
|
||||
}
|
||||
qOffset += mb->m_links[link].m_posVarCount;
|
||||
uOffset += mb->m_links[link].m_dofCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //BODY_JOINT_INFO_UTILITY_H
|
@ -8,6 +8,8 @@
|
||||
#include "PhysicsClientC_API.h"
|
||||
#include "PhysicsClient.h"
|
||||
//#include "SharedMemoryCommands.h"
|
||||
#include "PhysicsLoopBackC_API.h"
|
||||
#include "PhysicsDirectC_API.h"
|
||||
|
||||
#include "PhysicsClientC_API.h"
|
||||
|
||||
@ -444,7 +446,10 @@ void PhysicsClientExample::initPhysics()
|
||||
m_selectedBody = -1;
|
||||
m_prevSelectedBody = -1;
|
||||
|
||||
m_physicsClientHandle = b3ConnectSharedMemory(m_sharedMemoryKey);
|
||||
//m_physicsClientHandle = b3ConnectSharedMemory(m_sharedMemoryKey);
|
||||
m_physicsClientHandle = b3ConnectPhysicsLoopback(SHARED_MEMORY_KEY);
|
||||
//m_physicsClientHandle = b3ConnectPhysicsDirect();
|
||||
|
||||
if (!b3CanSubmitCommand(m_physicsClientHandle))
|
||||
{
|
||||
b3Warning("Cannot connect to physics client");
|
||||
|
@ -10,26 +10,11 @@
|
||||
#include "../../Extras/Serialize/BulletFileLoader/btBulletFile.h"
|
||||
#include "../../Extras/Serialize/BulletFileLoader/autogenerated/bullet.h"
|
||||
#include "SharedMemoryBlock.h"
|
||||
#include "BodyJointInfoUtility.h"
|
||||
|
||||
|
||||
// copied from btMultiBodyLink.h
|
||||
enum JointType {
|
||||
eRevoluteType = 0,
|
||||
ePrismaticType = 1,
|
||||
};
|
||||
|
||||
struct TmpFloat3 {
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_z;
|
||||
};
|
||||
|
||||
TmpFloat3 CreateTmpFloat3(float x, float y, float z) {
|
||||
TmpFloat3 tmp;
|
||||
tmp.m_x = x;
|
||||
tmp.m_y = y;
|
||||
tmp.m_z = z;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
struct BodyJointInfoCache
|
||||
{
|
||||
@ -72,14 +57,8 @@ struct PhysicsClientSharedMemoryInternalData {
|
||||
bool canSubmitCommand() const;
|
||||
};
|
||||
|
||||
static char* strDup(const char* const str)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _strdup(str);
|
||||
#else
|
||||
return strdup(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
int PhysicsClientSharedMemory::getNumJoints(int bodyIndex) const
|
||||
{
|
||||
@ -184,6 +163,7 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
|
||||
|
||||
EnumSharedMemoryServerStatus s = (EnumSharedMemoryServerStatus)serverCmd.m_type;
|
||||
// consume the command
|
||||
|
||||
switch (serverCmd.m_type) {
|
||||
case CMD_CLIENT_COMMAND_COMPLETED: {
|
||||
if (m_data->m_verboseOutput) {
|
||||
@ -199,7 +179,7 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
|
||||
|
||||
if (serverCmd.m_dataStreamArguments.m_streamChunkLength > 0) {
|
||||
bParse::btBulletFile bf(
|
||||
this->m_data->m_testBlock1->m_bulletStreamDataServerToClient,
|
||||
this->m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor,
|
||||
serverCmd.m_dataStreamArguments.m_streamChunkLength);
|
||||
bf.setFileDNAisMemoryDNA();
|
||||
bf.parse(false);
|
||||
@ -209,98 +189,21 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
|
||||
m_data->m_bodyJointMap.insert(bodyIndex,bodyJoints);
|
||||
|
||||
for (int i = 0; i < bf.m_multiBodies.size(); i++) {
|
||||
int flag = bf.getFlags();
|
||||
int qOffset = 7;
|
||||
int uOffset = 6;
|
||||
|
||||
|
||||
int flag = bf.getFlags();
|
||||
|
||||
if ((flag & bParse::FD_DOUBLE_PRECISION) != 0) {
|
||||
Bullet::btMultiBodyDoubleData* mb =
|
||||
(Bullet::btMultiBodyDoubleData*)bf.m_multiBodies[i];
|
||||
if (mb->m_baseName) {
|
||||
if (m_data->m_verboseOutput) {
|
||||
b3Printf("mb->m_baseName = %s\n", mb->m_baseName);
|
||||
}
|
||||
}
|
||||
|
||||
for (int link = 0; link < mb->m_numLinks; link++) {
|
||||
{
|
||||
b3JointInfo info;
|
||||
info.m_flags = 0;
|
||||
info.m_jointIndex = link;
|
||||
info.m_qIndex =
|
||||
(0 < mb->m_links[link].m_posVarCount) ? qOffset : -1;
|
||||
info.m_uIndex =
|
||||
(0 < mb->m_links[link].m_dofCount) ? uOffset : -1;
|
||||
|
||||
if (mb->m_links[link].m_linkName) {
|
||||
if (m_data->m_verboseOutput) {
|
||||
b3Printf("mb->m_links[%d].m_linkName = %s\n", link,
|
||||
mb->m_links[link].m_linkName);
|
||||
}
|
||||
info.m_linkName = strDup(mb->m_links[link].m_linkName);
|
||||
}
|
||||
if (mb->m_links[link].m_jointName) {
|
||||
if (m_data->m_verboseOutput) {
|
||||
b3Printf("mb->m_links[%d].m_jointName = %s\n", link,
|
||||
mb->m_links[link].m_jointName);
|
||||
}
|
||||
info.m_jointName = strDup(mb->m_links[link].m_jointName);
|
||||
}
|
||||
|
||||
info.m_jointType = mb->m_links[link].m_jointType;
|
||||
|
||||
if ((mb->m_links[link].m_jointType == eRevoluteType) ||
|
||||
(mb->m_links[link].m_jointType == ePrismaticType)) {
|
||||
info.m_flags |= JOINT_HAS_MOTORIZED_POWER;
|
||||
}
|
||||
bodyJoints->m_jointInfo.push_back(info);
|
||||
}
|
||||
qOffset += mb->m_links[link].m_posVarCount;
|
||||
uOffset += mb->m_links[link].m_dofCount;
|
||||
}
|
||||
|
||||
} else {
|
||||
addJointInfoFromMultiBodyData(mb,bodyJoints, m_data->m_verboseOutput);
|
||||
} else
|
||||
{
|
||||
Bullet::btMultiBodyFloatData* mb =
|
||||
(Bullet::btMultiBodyFloatData*)bf.m_multiBodies[i];
|
||||
if (mb->m_baseName) {
|
||||
if (m_data->m_verboseOutput) {
|
||||
b3Printf("mb->m_baseName = %s\n", mb->m_baseName);
|
||||
}
|
||||
}
|
||||
for (int link = 0; link < mb->m_numLinks; link++) {
|
||||
{
|
||||
b3JointInfo info;
|
||||
info.m_flags = 0;
|
||||
info.m_jointIndex = link;
|
||||
info.m_qIndex =
|
||||
(0 < mb->m_links[link].m_posVarCount) ? qOffset : -1;
|
||||
info.m_uIndex =
|
||||
(0 < mb->m_links[link].m_dofCount) ? uOffset : -1;
|
||||
|
||||
if (mb->m_links[link].m_linkName) {
|
||||
if (m_data->m_verboseOutput) {
|
||||
b3Printf("mb->m_links[%d].m_linkName = %s\n", link,
|
||||
mb->m_links[link].m_linkName);
|
||||
}
|
||||
info.m_linkName = strDup(mb->m_links[link].m_linkName);
|
||||
}
|
||||
if (mb->m_links[link].m_jointName) {
|
||||
if (m_data->m_verboseOutput) {
|
||||
b3Printf("mb->m_links[%d].m_jointName = %s\n", link,
|
||||
mb->m_links[link].m_jointName);
|
||||
}
|
||||
info.m_jointName = strDup(mb->m_links[link].m_jointName);
|
||||
}
|
||||
info.m_jointType = mb->m_links[link].m_jointType;
|
||||
if ((mb->m_links[link].m_jointType == eRevoluteType) ||
|
||||
(mb->m_links[link].m_jointType == ePrismaticType)) {
|
||||
info.m_flags |= JOINT_HAS_MOTORIZED_POWER;
|
||||
}
|
||||
bodyJoints->m_jointInfo.push_back(info);
|
||||
}
|
||||
qOffset += mb->m_links[link].m_posVarCount;
|
||||
uOffset += mb->m_links[link].m_dofCount;
|
||||
}
|
||||
addJointInfoFromMultiBodyData(mb,bodyJoints, m_data->m_verboseOutput);
|
||||
}
|
||||
}
|
||||
if (bf.ok()) {
|
||||
@ -406,6 +309,9 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
|
||||
if (m_data->m_verboseOutput) {
|
||||
b3Printf("CMD_RESET_SIMULATION_COMPLETED clean data\n");
|
||||
}
|
||||
m_data->m_debugLinesFrom.clear();
|
||||
m_data->m_debugLinesTo.clear();
|
||||
m_data->m_debugLinesColor.clear();
|
||||
for (int i=0;i<m_data->m_bodyJointMap.size();i++)
|
||||
{
|
||||
BodyJointInfoCache** bodyJointsPtr = m_data->m_bodyJointMap.getAtIndex(i);
|
||||
@ -437,12 +343,12 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
|
||||
|
||||
int numLines = serverCmd.m_sendDebugLinesArgs.m_numDebugLines;
|
||||
float* linesFrom =
|
||||
(float*)&m_data->m_testBlock1->m_bulletStreamDataServerToClient[0];
|
||||
(float*)&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0];
|
||||
float* linesTo =
|
||||
(float*)(&m_data->m_testBlock1->m_bulletStreamDataServerToClient[0] +
|
||||
(float*)(&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0] +
|
||||
numLines * 3 * sizeof(float));
|
||||
float* linesColor =
|
||||
(float*)(&m_data->m_testBlock1->m_bulletStreamDataServerToClient[0] +
|
||||
(float*)(&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0] +
|
||||
2 * numLines * 3 * sizeof(float));
|
||||
|
||||
m_data->m_debugLinesFrom.resize(serverCmd.m_sendDebugLinesArgs.m_startingLineIndex +
|
||||
|
330
examples/SharedMemory/PhysicsDirect.cpp
Normal file
330
examples/SharedMemory/PhysicsDirect.cpp
Normal file
@ -0,0 +1,330 @@
|
||||
#include "PhysicsDirect.h"
|
||||
|
||||
#include "PhysicsClientSharedMemory.h"
|
||||
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
||||
#include "SharedMemoryCommands.h"
|
||||
#include "PhysicsServerCommandProcessor.h"
|
||||
#include "LinearMath/btHashMap.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "../../Extras/Serialize/BulletFileLoader/btBulletFile.h"
|
||||
#include "../../Extras/Serialize/BulletFileLoader/autogenerated/bullet.h"
|
||||
#include "BodyJointInfoUtility.h"
|
||||
|
||||
|
||||
struct BodyJointInfoCache2
|
||||
{
|
||||
btAlignedObjectArray<b3JointInfo> m_jointInfo;
|
||||
};
|
||||
|
||||
struct PhysicsDirectInternalData
|
||||
{
|
||||
DummyGUIHelper m_noGfx;
|
||||
|
||||
SharedMemoryCommand m_command;
|
||||
SharedMemoryStatus m_serverStatus;
|
||||
bool m_hasStatus;
|
||||
bool m_verboseOutput;
|
||||
|
||||
btAlignedObjectArray<TmpFloat3> m_debugLinesFrom;
|
||||
btAlignedObjectArray<TmpFloat3> m_debugLinesTo;
|
||||
btAlignedObjectArray<TmpFloat3> m_debugLinesColor;
|
||||
|
||||
btHashMap<btHashInt,BodyJointInfoCache2*> m_bodyJointMap;
|
||||
|
||||
char m_bulletStreamDataServerToClient[SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE];
|
||||
|
||||
PhysicsServerCommandProcessor* m_commandProcessor;
|
||||
|
||||
PhysicsDirectInternalData()
|
||||
:m_hasStatus(false),
|
||||
m_verboseOutput(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
PhysicsDirect::PhysicsDirect()
|
||||
{
|
||||
m_data = new PhysicsDirectInternalData;
|
||||
m_data->m_commandProcessor = new PhysicsServerCommandProcessor;
|
||||
|
||||
|
||||
}
|
||||
|
||||
PhysicsDirect::~PhysicsDirect()
|
||||
{
|
||||
delete m_data->m_commandProcessor;
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
|
||||
// return true if connection succesfull, can also check 'isConnected'
|
||||
bool PhysicsDirect::connect()
|
||||
{
|
||||
m_data->m_commandProcessor->setGuiHelper(&m_data->m_noGfx);
|
||||
return true;
|
||||
}
|
||||
|
||||
////todo: rename to 'disconnect'
|
||||
void PhysicsDirect::disconnectSharedMemory()
|
||||
{
|
||||
m_data->m_commandProcessor->setGuiHelper(0);
|
||||
}
|
||||
|
||||
bool PhysicsDirect::isConnected() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// return non-null if there is a status, nullptr otherwise
|
||||
const SharedMemoryStatus* PhysicsDirect::processServerStatus()
|
||||
{
|
||||
SharedMemoryStatus* stat = 0;
|
||||
if (m_data->m_hasStatus)
|
||||
{
|
||||
stat = &m_data->m_serverStatus;
|
||||
m_data->m_hasStatus = false;
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
SharedMemoryCommand* PhysicsDirect::getAvailableSharedMemoryCommand()
|
||||
{
|
||||
return &m_data->m_command;
|
||||
}
|
||||
|
||||
bool PhysicsDirect::canSubmitCommand() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsDirect::processDebugLines(const struct SharedMemoryCommand& orgCommand)
|
||||
{
|
||||
SharedMemoryCommand command = orgCommand;
|
||||
|
||||
const SharedMemoryStatus& serverCmd = m_data->m_serverStatus;
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
bool hasStatus = m_data->m_commandProcessor->processCommand(command,m_data->m_serverStatus,&m_data->m_bulletStreamDataServerToClient[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
|
||||
m_data->m_hasStatus = hasStatus;
|
||||
if (hasStatus)
|
||||
{
|
||||
btAssert(m_data->m_serverStatus.m_type == CMD_DEBUG_LINES_COMPLETED);
|
||||
|
||||
if (m_data->m_verboseOutput)
|
||||
{
|
||||
b3Printf("Success receiving %d debug lines",
|
||||
serverCmd.m_sendDebugLinesArgs.m_numDebugLines);
|
||||
}
|
||||
|
||||
int numLines = serverCmd.m_sendDebugLinesArgs.m_numDebugLines;
|
||||
float* linesFrom =
|
||||
(float*)&m_data->m_bulletStreamDataServerToClient[0];
|
||||
float* linesTo =
|
||||
(float*)(&m_data->m_bulletStreamDataServerToClient[0] +
|
||||
numLines * 3 * sizeof(float));
|
||||
float* linesColor =
|
||||
(float*)(&m_data->m_bulletStreamDataServerToClient[0] +
|
||||
2 * numLines * 3 * sizeof(float));
|
||||
|
||||
m_data->m_debugLinesFrom.resize(serverCmd.m_sendDebugLinesArgs.m_startingLineIndex +
|
||||
numLines);
|
||||
m_data->m_debugLinesTo.resize(serverCmd.m_sendDebugLinesArgs.m_startingLineIndex +
|
||||
numLines);
|
||||
m_data->m_debugLinesColor.resize(
|
||||
serverCmd.m_sendDebugLinesArgs.m_startingLineIndex + numLines);
|
||||
|
||||
for (int i = 0; i < numLines; i++)
|
||||
{
|
||||
TmpFloat3 from = CreateTmpFloat3(linesFrom[i * 3], linesFrom[i * 3 + 1],
|
||||
linesFrom[i * 3 + 2]);
|
||||
TmpFloat3 to =
|
||||
CreateTmpFloat3(linesTo[i * 3], linesTo[i * 3 + 1], linesTo[i * 3 + 2]);
|
||||
TmpFloat3 color = CreateTmpFloat3(linesColor[i * 3], linesColor[i * 3 + 1],
|
||||
linesColor[i * 3 + 2]);
|
||||
|
||||
m_data
|
||||
->m_debugLinesFrom[serverCmd.m_sendDebugLinesArgs.m_startingLineIndex + i] =
|
||||
from;
|
||||
m_data->m_debugLinesTo[serverCmd.m_sendDebugLinesArgs.m_startingLineIndex + i] =
|
||||
to;
|
||||
m_data->m_debugLinesColor[serverCmd.m_sendDebugLinesArgs.m_startingLineIndex +
|
||||
i] = color;
|
||||
}
|
||||
|
||||
if (serverCmd.m_sendDebugLinesArgs.m_numRemainingDebugLines > 0)
|
||||
{
|
||||
command.m_type = CMD_REQUEST_DEBUG_LINES;
|
||||
command.m_requestDebugLinesArguments.m_startingLineIndex =
|
||||
serverCmd.m_sendDebugLinesArgs.m_numDebugLines +
|
||||
serverCmd.m_sendDebugLinesArgs.m_startingLineIndex;
|
||||
}
|
||||
}
|
||||
|
||||
} while (serverCmd.m_sendDebugLinesArgs.m_numRemainingDebugLines > 0);
|
||||
|
||||
return m_data->m_hasStatus;
|
||||
}
|
||||
|
||||
bool PhysicsDirect::submitClientCommand(const struct SharedMemoryCommand& command)
|
||||
{
|
||||
if (command.m_type==CMD_REQUEST_DEBUG_LINES)
|
||||
{
|
||||
return processDebugLines(command);
|
||||
}
|
||||
|
||||
bool hasStatus = m_data->m_commandProcessor->processCommand(command,m_data->m_serverStatus,&m_data->m_bulletStreamDataServerToClient[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
|
||||
m_data->m_hasStatus = hasStatus;
|
||||
if (hasStatus)
|
||||
{
|
||||
const SharedMemoryStatus& serverCmd = m_data->m_serverStatus;
|
||||
|
||||
switch (m_data->m_serverStatus.m_type)
|
||||
{
|
||||
case CMD_RESET_SIMULATION_COMPLETED:
|
||||
{
|
||||
m_data->m_debugLinesFrom.clear();
|
||||
m_data->m_debugLinesTo.clear();
|
||||
m_data->m_debugLinesColor.clear();
|
||||
for (int i=0;i<m_data->m_bodyJointMap.size();i++)
|
||||
{
|
||||
BodyJointInfoCache2** bodyJointsPtr = m_data->m_bodyJointMap.getAtIndex(i);
|
||||
if (bodyJointsPtr && *bodyJointsPtr)
|
||||
{
|
||||
BodyJointInfoCache2* bodyJoints = *bodyJointsPtr;
|
||||
for (int j=0;j<bodyJoints->m_jointInfo.size();j++) {
|
||||
if (bodyJoints->m_jointInfo[j].m_jointName)
|
||||
{
|
||||
free(bodyJoints->m_jointInfo[j].m_jointName);
|
||||
}
|
||||
if (bodyJoints->m_jointInfo[j].m_linkName)
|
||||
{
|
||||
free(bodyJoints->m_jointInfo[j].m_linkName);
|
||||
}
|
||||
}
|
||||
delete (*bodyJointsPtr);
|
||||
}
|
||||
}
|
||||
m_data->m_bodyJointMap.clear();
|
||||
|
||||
break;
|
||||
}
|
||||
case CMD_URDF_LOADING_COMPLETED:
|
||||
{
|
||||
if (serverCmd.m_dataStreamArguments.m_streamChunkLength > 0)
|
||||
{
|
||||
bParse::btBulletFile bf(
|
||||
&m_data->m_bulletStreamDataServerToClient[0],
|
||||
serverCmd.m_dataStreamArguments.m_streamChunkLength);
|
||||
bf.setFileDNAisMemoryDNA();
|
||||
bf.parse(false);
|
||||
int bodyIndex = serverCmd.m_dataStreamArguments.m_bodyUniqueId;
|
||||
|
||||
BodyJointInfoCache2* bodyJoints = new BodyJointInfoCache2;
|
||||
m_data->m_bodyJointMap.insert(bodyIndex,bodyJoints);
|
||||
|
||||
for (int i = 0; i < bf.m_multiBodies.size(); i++)
|
||||
{
|
||||
int flag = bf.getFlags();
|
||||
if ((flag & bParse::FD_DOUBLE_PRECISION) != 0)
|
||||
{
|
||||
Bullet::btMultiBodyDoubleData* mb =
|
||||
(Bullet::btMultiBodyDoubleData*)bf.m_multiBodies[i];
|
||||
|
||||
addJointInfoFromMultiBodyData(mb,bodyJoints, m_data->m_verboseOutput);
|
||||
} else
|
||||
{
|
||||
Bullet::btMultiBodyFloatData* mb =
|
||||
(Bullet::btMultiBodyFloatData*)bf.m_multiBodies[i];
|
||||
|
||||
addJointInfoFromMultiBodyData(mb,bodyJoints, m_data->m_verboseOutput);
|
||||
}
|
||||
}
|
||||
if (bf.ok()) {
|
||||
if (m_data->m_verboseOutput)
|
||||
{
|
||||
b3Printf("Received robot description ok!\n");
|
||||
}
|
||||
} else
|
||||
{
|
||||
b3Warning("Robot description not received");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
// b3Error("Unknown server status type");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
return hasStatus;
|
||||
}
|
||||
|
||||
int PhysicsDirect::getNumJoints(int bodyIndex) const
|
||||
{
|
||||
BodyJointInfoCache2** bodyJointsPtr = m_data->m_bodyJointMap[bodyIndex];
|
||||
if (bodyJointsPtr && *bodyJointsPtr)
|
||||
{
|
||||
BodyJointInfoCache2* bodyJoints = *bodyJointsPtr;
|
||||
return bodyJoints->m_jointInfo.size();
|
||||
}
|
||||
btAssert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PhysicsDirect::getJointInfo(int bodyIndex, int jointIndex, struct b3JointInfo& info) const
|
||||
{
|
||||
BodyJointInfoCache2** bodyJointsPtr = m_data->m_bodyJointMap[bodyIndex];
|
||||
if (bodyJointsPtr && *bodyJointsPtr)
|
||||
{
|
||||
BodyJointInfoCache2* bodyJoints = *bodyJointsPtr;
|
||||
info = bodyJoints->m_jointInfo[jointIndex];
|
||||
}
|
||||
}
|
||||
|
||||
///todo: move this out of the
|
||||
void PhysicsDirect::setSharedMemoryKey(int key)
|
||||
{
|
||||
//m_data->m_physicsServer->setSharedMemoryKey(key);
|
||||
//m_data->m_physicsClient->setSharedMemoryKey(key);
|
||||
}
|
||||
|
||||
void PhysicsDirect::uploadBulletFileToSharedMemory(const char* data, int len)
|
||||
{
|
||||
//m_data->m_physicsClient->uploadBulletFileToSharedMemory(data,len);
|
||||
}
|
||||
|
||||
int PhysicsDirect::getNumDebugLines() const
|
||||
{
|
||||
return m_data->m_debugLinesFrom.size();
|
||||
}
|
||||
|
||||
const float* PhysicsDirect::getDebugLinesFrom() const
|
||||
{
|
||||
if (getNumDebugLines())
|
||||
{
|
||||
return &m_data->m_debugLinesFrom[0].m_x;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
const float* PhysicsDirect::getDebugLinesTo() const
|
||||
{
|
||||
if (getNumDebugLines())
|
||||
{
|
||||
return &m_data->m_debugLinesTo[0].m_x;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
const float* PhysicsDirect::getDebugLinesColor() const
|
||||
{
|
||||
if (getNumDebugLines())
|
||||
{
|
||||
return &m_data->m_debugLinesColor[0].m_x;
|
||||
}
|
||||
return 0;
|
||||
}
|
62
examples/SharedMemory/PhysicsDirect.h
Normal file
62
examples/SharedMemory/PhysicsDirect.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef PHYSICS_DIRECT_H
|
||||
#define PHYSICS_DIRECT_H
|
||||
|
||||
//#include "SharedMemoryCommands.h"
|
||||
|
||||
|
||||
#include "PhysicsClient.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
|
||||
///todo: the PhysicsClient API was designed with shared memory in mind,
|
||||
///now it become more general we need to move out the shared memory specifics away
|
||||
///for example naming [disconnectSharedMemory -> disconnect] [ move setSharedMemoryKey to shared memory specific subclass ]
|
||||
///PhysicsDirect executes the commands directly, without transporting them or having a separate server executing commands
|
||||
class PhysicsDirect : public PhysicsClient
|
||||
{
|
||||
protected:
|
||||
|
||||
struct PhysicsDirectInternalData* m_data;
|
||||
|
||||
bool processDebugLines(const struct SharedMemoryCommand& orgCommand);
|
||||
|
||||
public:
|
||||
|
||||
PhysicsDirect();
|
||||
|
||||
virtual ~PhysicsDirect();
|
||||
|
||||
// return true if connection succesfull, can also check 'isConnected'
|
||||
virtual bool connect();
|
||||
|
||||
////todo: rename to 'disconnect'
|
||||
virtual void disconnectSharedMemory();
|
||||
|
||||
virtual bool isConnected() const;
|
||||
|
||||
// return non-null if there is a status, nullptr otherwise
|
||||
virtual const SharedMemoryStatus* processServerStatus();
|
||||
|
||||
virtual SharedMemoryCommand* getAvailableSharedMemoryCommand();
|
||||
|
||||
virtual bool canSubmitCommand() const;
|
||||
|
||||
virtual bool submitClientCommand(const struct SharedMemoryCommand& command);
|
||||
|
||||
virtual int getNumJoints(int bodyIndex) const;
|
||||
|
||||
virtual void getJointInfo(int bodyIndex, int jointIndex, struct b3JointInfo& info) const;
|
||||
|
||||
///todo: move this out of the
|
||||
virtual void setSharedMemoryKey(int key);
|
||||
|
||||
void uploadBulletFileToSharedMemory(const char* data, int len);
|
||||
|
||||
virtual int getNumDebugLines() const;
|
||||
|
||||
virtual const float* getDebugLinesFrom() const;
|
||||
virtual const float* getDebugLinesTo() const;
|
||||
virtual const float* getDebugLinesColor() const;
|
||||
|
||||
};
|
||||
|
||||
#endif //PHYSICS_DIRECT_H
|
14
examples/SharedMemory/PhysicsDirectC_API.cpp
Normal file
14
examples/SharedMemory/PhysicsDirectC_API.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "PhysicsDirectC_API.h"
|
||||
|
||||
#include "PhysicsDirect.h"
|
||||
|
||||
|
||||
|
||||
//think more about naming. The b3ConnectPhysicsLoopback
|
||||
b3PhysicsClientHandle b3ConnectPhysicsDirect()
|
||||
{
|
||||
PhysicsDirect* direct = new PhysicsDirect();
|
||||
bool connected = direct->connect();
|
||||
return (b3PhysicsClientHandle )direct;
|
||||
}
|
||||
|
19
examples/SharedMemory/PhysicsDirectC_API.h
Normal file
19
examples/SharedMemory/PhysicsDirectC_API.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef PHYSICS_DIRECT_C_API_H
|
||||
#define PHYSICS_DIRECT_C_API_H
|
||||
|
||||
#include "PhysicsClientC_API.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
///think more about naming. Directly execute commands without transport (no shared memory, UDP, socket, grpc etc)
|
||||
b3PhysicsClientHandle b3ConnectPhysicsDirect();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //PHYSICS_DIRECT_C_API_H
|
@ -1,5 +1,5 @@
|
||||
#include "PhysicsLoopBack.h"
|
||||
#include "PhysicsServer.h"
|
||||
#include "PhysicsServerSharedMemory.h"
|
||||
#include "PhysicsClientSharedMemory.h"
|
||||
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,66 +1,46 @@
|
||||
#ifndef PHYSICS_SERVER_SHARED_MEMORY_H
|
||||
#define PHYSICS_SERVER_SHARED_MEMORY_H
|
||||
#ifndef PHYSICS_SERVER_H
|
||||
#define PHYSICS_SERVER_H
|
||||
|
||||
#include "LinearMath/btVector3.h"
|
||||
|
||||
struct SharedMemLines
|
||||
|
||||
|
||||
class PhysicsServer
|
||||
{
|
||||
btVector3 m_from;
|
||||
btVector3 m_to;
|
||||
btVector3 m_color;
|
||||
};
|
||||
|
||||
|
||||
class PhysicsServerSharedMemory
|
||||
{
|
||||
struct PhysicsServerInternalData* m_data;
|
||||
|
||||
protected:
|
||||
|
||||
void createJointMotors(class btMultiBody* body);
|
||||
|
||||
virtual void createEmptyDynamicsWorld();
|
||||
virtual void deleteDynamicsWorld();
|
||||
|
||||
void releaseSharedMemory();
|
||||
|
||||
bool loadUrdf(const char* fileName, const class btVector3& pos, const class btQuaternion& orn,
|
||||
bool useMultiBody, bool useFixedBase, int* bodyUniqueId);
|
||||
|
||||
public:
|
||||
PhysicsServerSharedMemory();
|
||||
virtual ~PhysicsServerSharedMemory();
|
||||
|
||||
virtual void setSharedMemoryKey(int key);
|
||||
|
||||
//todo: implement option to allocated shared memory from client
|
||||
virtual bool connectSharedMemory( struct GUIHelperInterface* guiHelper);
|
||||
virtual ~PhysicsServer();
|
||||
|
||||
virtual void setSharedMemoryKey(int key)=0;
|
||||
|
||||
virtual bool connectSharedMemory( struct GUIHelperInterface* guiHelper)=0;
|
||||
|
||||
virtual void disconnectSharedMemory (bool deInitializeSharedMemory);
|
||||
virtual void disconnectSharedMemory (bool deInitializeSharedMemory)=0;
|
||||
|
||||
virtual void processClientCommands();
|
||||
virtual void processClientCommands()=0;
|
||||
|
||||
bool supportsJointMotor(class btMultiBody* body, int linkIndex);
|
||||
// virtual bool supportsJointMotor(class btMultiBody* body, int linkIndex)=0;
|
||||
|
||||
//@todo(erwincoumans) Should we have shared memory commands for picking objects?
|
||||
///The pickBody method will try to pick the first body along a ray, return true if succeeds, false otherwise
|
||||
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld);
|
||||
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld);
|
||||
virtual void removePickingConstraint();
|
||||
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)=0;
|
||||
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)=0;
|
||||
virtual void removePickingConstraint()=0;
|
||||
|
||||
//for physicsDebugDraw and renderScene are mainly for debugging purposes
|
||||
//and for physics visualization. The idea is that physicsDebugDraw can also send wireframe
|
||||
//to a physics client, over shared memory
|
||||
void physicsDebugDraw(int debugDrawFlags);
|
||||
void renderScene();
|
||||
virtual void physicsDebugDraw(int debugDrawFlags)=0;
|
||||
virtual void renderScene()=0;
|
||||
|
||||
void enableCommandLogging(bool enable, const char* fileName);
|
||||
void replayFromLogFile(const char* fileName);
|
||||
virtual void enableCommandLogging(bool enable, const char* fileName)=0;
|
||||
virtual void replayFromLogFile(const char* fileName)=0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //PHYSICS_SERVER_EXAMPLESHARED_MEMORY_H
|
||||
#endif //PHYSICS_SERVER_H
|
||||
|
||||
|
||||
|
1812
examples/SharedMemory/PhysicsServerCommandProcessor.cpp
Normal file
1812
examples/SharedMemory/PhysicsServerCommandProcessor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
53
examples/SharedMemory/PhysicsServerCommandProcessor.h
Normal file
53
examples/SharedMemory/PhysicsServerCommandProcessor.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef PHYSICS_SERVER_COMMAND_PROCESSOR_H
|
||||
#define PHYSICS_SERVER_COMMAND_PROCESSOR_H
|
||||
|
||||
#include "LinearMath/btVector3.h"
|
||||
|
||||
struct SharedMemLines
|
||||
{
|
||||
btVector3 m_from;
|
||||
btVector3 m_to;
|
||||
btVector3 m_color;
|
||||
};
|
||||
|
||||
///todo: naming. Perhaps PhysicsSdkCommandprocessor?
|
||||
class PhysicsServerCommandProcessor
|
||||
{
|
||||
|
||||
struct PhysicsServerCommandProcessorInternalData* m_data;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
bool loadUrdf(const char* fileName, const class btVector3& pos, const class btQuaternion& orn,
|
||||
bool useMultiBody, bool useFixedBase, int* bodyUniqueIdPtr, char* bufferServerToClient, int bufferSizeInBytes);
|
||||
|
||||
bool supportsJointMotor(class btMultiBody* body, int linkIndex);
|
||||
|
||||
public:
|
||||
PhysicsServerCommandProcessor();
|
||||
virtual ~PhysicsServerCommandProcessor();
|
||||
|
||||
void createJointMotors(class btMultiBody* body);
|
||||
|
||||
virtual void createEmptyDynamicsWorld();
|
||||
virtual void deleteDynamicsWorld();
|
||||
|
||||
virtual bool processCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes );
|
||||
|
||||
virtual void renderScene();
|
||||
virtual void physicsDebugDraw(int debugDrawFlags);
|
||||
virtual void setGuiHelper(struct GUIHelperInterface* guiHelper);
|
||||
|
||||
//@todo(erwincoumans) Should we have shared memory commands for picking objects?
|
||||
///The pickBody method will try to pick the first body along a ray, return true if succeeds, false otherwise
|
||||
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld);
|
||||
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld);
|
||||
virtual void removePickingConstraint();
|
||||
|
||||
void enableCommandLogging(bool enable, const char* fileName);
|
||||
void replayFromLogFile(const char* fileName);
|
||||
|
||||
};
|
||||
|
||||
#endif //PHYSICS_SERVER_COMMAND_PROCESSOR_H
|
@ -5,7 +5,7 @@
|
||||
|
||||
|
||||
|
||||
#include "PhysicsServer.h"
|
||||
#include "PhysicsServerSharedMemory.h"
|
||||
|
||||
#include "SharedMemoryCommon.h"
|
||||
|
||||
|
304
examples/SharedMemory/PhysicsServerSharedMemory.cpp
Normal file
304
examples/SharedMemory/PhysicsServerSharedMemory.cpp
Normal file
@ -0,0 +1,304 @@
|
||||
#include "PhysicsServerSharedMemory.h"
|
||||
#include "PosixSharedMemory.h"
|
||||
#include "Win32SharedMemory.h"
|
||||
|
||||
#include "../CommonInterfaces/CommonRenderInterface.h"
|
||||
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
|
||||
#include "Bullet3Common/b3Logging.h"
|
||||
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
||||
#include "SharedMemoryBlock.h"
|
||||
|
||||
#include "PhysicsServerCommandProcessor.h"
|
||||
|
||||
|
||||
|
||||
struct PhysicsServerSharedMemoryInternalData
|
||||
{
|
||||
|
||||
///end handle management
|
||||
|
||||
|
||||
SharedMemoryInterface* m_sharedMemory;
|
||||
SharedMemoryBlock* m_testBlock1;
|
||||
int m_sharedMemoryKey;
|
||||
bool m_isConnected;
|
||||
bool m_verboseOutput;
|
||||
PhysicsServerCommandProcessor* m_commandProcessor;
|
||||
|
||||
PhysicsServerSharedMemoryInternalData()
|
||||
:m_sharedMemory(0),
|
||||
m_testBlock1(0),
|
||||
m_sharedMemoryKey(SHARED_MEMORY_KEY),
|
||||
m_isConnected(false),
|
||||
m_verboseOutput(false),
|
||||
m_commandProcessor(0)
|
||||
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SharedMemoryStatus& createServerStatus(int statusType, int sequenceNumber, int timeStamp)
|
||||
{
|
||||
SharedMemoryStatus& serverCmd =m_testBlock1->m_serverCommands[0];
|
||||
serverCmd .m_type = statusType;
|
||||
serverCmd.m_sequenceNumber = sequenceNumber;
|
||||
serverCmd.m_timeStamp = timeStamp;
|
||||
return serverCmd;
|
||||
}
|
||||
void submitServerStatus(SharedMemoryStatus& status)
|
||||
{
|
||||
m_testBlock1->m_numServerCommands++;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
PhysicsServerSharedMemory::PhysicsServerSharedMemory()
|
||||
{
|
||||
m_data = new PhysicsServerSharedMemoryInternalData();
|
||||
|
||||
#ifdef _WIN32
|
||||
m_data->m_sharedMemory = new Win32SharedMemoryServer();
|
||||
#else
|
||||
m_data->m_sharedMemory = new PosixSharedMemory();
|
||||
#endif
|
||||
|
||||
m_data->m_commandProcessor = new PhysicsServerCommandProcessor;
|
||||
m_data->m_commandProcessor ->createEmptyDynamicsWorld();
|
||||
|
||||
|
||||
}
|
||||
|
||||
PhysicsServerSharedMemory::~PhysicsServerSharedMemory()
|
||||
{
|
||||
m_data->m_commandProcessor->deleteDynamicsWorld();
|
||||
delete m_data->m_commandProcessor;
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
void PhysicsServerSharedMemory::setSharedMemoryKey(int key)
|
||||
{
|
||||
m_data->m_sharedMemoryKey = key;
|
||||
}
|
||||
|
||||
|
||||
bool PhysicsServerSharedMemory::connectSharedMemory( struct GUIHelperInterface* guiHelper)
|
||||
{
|
||||
|
||||
m_data->m_commandProcessor->setGuiHelper(guiHelper);
|
||||
|
||||
|
||||
bool allowCreation = true;
|
||||
|
||||
|
||||
if (m_data->m_isConnected)
|
||||
{
|
||||
b3Warning("connectSharedMemory, while already connected");
|
||||
return m_data->m_isConnected;
|
||||
}
|
||||
|
||||
|
||||
int counter = 0;
|
||||
do
|
||||
{
|
||||
|
||||
m_data->m_testBlock1 = (SharedMemoryBlock*)m_data->m_sharedMemory->allocateSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE,allowCreation);
|
||||
if (m_data->m_testBlock1)
|
||||
{
|
||||
int magicId =m_data->m_testBlock1->m_magicId;
|
||||
if (m_data->m_verboseOutput)
|
||||
{
|
||||
b3Printf("magicId = %d\n", magicId);
|
||||
}
|
||||
|
||||
if (m_data->m_testBlock1->m_magicId !=SHARED_MEMORY_MAGIC_NUMBER)
|
||||
{
|
||||
InitSharedMemoryBlock(m_data->m_testBlock1);
|
||||
if (m_data->m_verboseOutput)
|
||||
{
|
||||
b3Printf("Created and initialized shared memory block\n");
|
||||
}
|
||||
m_data->m_isConnected = true;
|
||||
} else
|
||||
{
|
||||
m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE);
|
||||
m_data->m_testBlock1 = 0;
|
||||
m_data->m_isConnected = false;
|
||||
}
|
||||
} else
|
||||
{
|
||||
b3Error("Cannot connect to shared memory");
|
||||
m_data->m_isConnected = false;
|
||||
}
|
||||
} while (counter++ < 10 && !m_data->m_isConnected);
|
||||
|
||||
if (!m_data->m_isConnected)
|
||||
{
|
||||
b3Error("Server cannot connect to shared memory.\n");
|
||||
}
|
||||
|
||||
return m_data->m_isConnected;
|
||||
}
|
||||
|
||||
|
||||
void PhysicsServerSharedMemory::disconnectSharedMemory(bool deInitializeSharedMemory)
|
||||
{
|
||||
m_data->m_commandProcessor->setGuiHelper(0);
|
||||
|
||||
if (m_data->m_verboseOutput)
|
||||
{
|
||||
b3Printf("releaseSharedMemory1\n");
|
||||
}
|
||||
if (m_data->m_testBlock1)
|
||||
{
|
||||
if (m_data->m_verboseOutput)
|
||||
{
|
||||
b3Printf("m_testBlock1\n");
|
||||
}
|
||||
if (deInitializeSharedMemory)
|
||||
{
|
||||
m_data->m_testBlock1->m_magicId = 0;
|
||||
if (m_data->m_verboseOutput)
|
||||
{
|
||||
b3Printf("De-initialized shared memory, magic id = %d\n",m_data->m_testBlock1->m_magicId);
|
||||
}
|
||||
}
|
||||
btAssert(m_data->m_sharedMemory);
|
||||
m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE);
|
||||
}
|
||||
if (m_data->m_sharedMemory)
|
||||
{
|
||||
if (m_data->m_verboseOutput)
|
||||
{
|
||||
b3Printf("m_sharedMemory\n");
|
||||
}
|
||||
delete m_data->m_sharedMemory;
|
||||
m_data->m_sharedMemory = 0;
|
||||
m_data->m_testBlock1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsServerSharedMemory::releaseSharedMemory()
|
||||
{
|
||||
if (m_data->m_verboseOutput)
|
||||
{
|
||||
b3Printf("releaseSharedMemory1\n");
|
||||
}
|
||||
if (m_data->m_testBlock1)
|
||||
{
|
||||
if (m_data->m_verboseOutput)
|
||||
{
|
||||
b3Printf("m_testBlock1\n");
|
||||
}
|
||||
m_data->m_testBlock1->m_magicId = 0;
|
||||
if (m_data->m_verboseOutput)
|
||||
{
|
||||
b3Printf("magic id = %d\n",m_data->m_testBlock1->m_magicId);
|
||||
}
|
||||
btAssert(m_data->m_sharedMemory);
|
||||
m_data->m_sharedMemory->releaseSharedMemory( m_data->m_sharedMemoryKey
|
||||
, SHARED_MEMORY_SIZE);
|
||||
}
|
||||
if (m_data->m_sharedMemory)
|
||||
{
|
||||
if (m_data->m_verboseOutput)
|
||||
{
|
||||
b3Printf("m_sharedMemory\n");
|
||||
}
|
||||
delete m_data->m_sharedMemory;
|
||||
m_data->m_sharedMemory = 0;
|
||||
m_data->m_testBlock1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void PhysicsServerSharedMemory::processClientCommands()
|
||||
{
|
||||
if (m_data->m_isConnected && m_data->m_testBlock1)
|
||||
{
|
||||
#if 0
|
||||
m_data->m_commandProcessor->processLogCommand();
|
||||
|
||||
if (m_data->m_logPlayback)
|
||||
{
|
||||
if (m_data->m_testBlock1->m_numServerCommands>m_data->m_testBlock1->m_numProcessedServerCommands)
|
||||
{
|
||||
m_data->m_testBlock1->m_numProcessedServerCommands++;
|
||||
}
|
||||
//push a command from log file
|
||||
bool hasCommand = m_data->m_logPlayback->processNextCommand(&m_data->m_testBlock1->m_clientCommands[0]);
|
||||
if (hasCommand)
|
||||
{
|
||||
m_data->m_testBlock1->m_numClientCommands++;
|
||||
}
|
||||
}
|
||||
#endif 0
|
||||
///we ignore overflow of integer for now
|
||||
if (m_data->m_testBlock1->m_numClientCommands> m_data->m_testBlock1->m_numProcessedClientCommands)
|
||||
{
|
||||
|
||||
|
||||
//until we implement a proper ring buffer, we assume always maximum of 1 outstanding commands
|
||||
btAssert(m_data->m_testBlock1->m_numClientCommands==m_data->m_testBlock1->m_numProcessedClientCommands+1);
|
||||
|
||||
const SharedMemoryCommand& clientCmd =m_data->m_testBlock1->m_clientCommands[0];
|
||||
|
||||
m_data->m_testBlock1->m_numProcessedClientCommands++;
|
||||
//todo, timeStamp
|
||||
int timeStamp = 0;
|
||||
SharedMemoryStatus& serverStatusOut = m_data->createServerStatus(CMD_BULLET_DATA_STREAM_RECEIVED_COMPLETED,clientCmd.m_sequenceNumber,timeStamp);
|
||||
bool hasStatus = m_data->m_commandProcessor->processCommand(clientCmd, serverStatusOut,&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
|
||||
if (hasStatus)
|
||||
{
|
||||
m_data->submitServerStatus(serverStatusOut);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsServerSharedMemory::renderScene()
|
||||
{
|
||||
m_data->m_commandProcessor->renderScene();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void PhysicsServerSharedMemory::physicsDebugDraw(int debugDrawFlags)
|
||||
{
|
||||
m_data->m_commandProcessor->physicsDebugDraw(debugDrawFlags);
|
||||
}
|
||||
|
||||
|
||||
bool PhysicsServerSharedMemory::pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
{
|
||||
return m_data->m_commandProcessor->pickBody(rayFromWorld,rayToWorld);
|
||||
}
|
||||
|
||||
bool PhysicsServerSharedMemory::movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
{
|
||||
return m_data->m_commandProcessor->movePickedBody(rayFromWorld,rayToWorld);
|
||||
}
|
||||
void PhysicsServerSharedMemory::removePickingConstraint()
|
||||
{
|
||||
m_data->m_commandProcessor->removePickingConstraint();
|
||||
}
|
||||
|
||||
void PhysicsServerSharedMemory::enableCommandLogging(bool enable, const char* fileName)
|
||||
{
|
||||
m_data->m_commandProcessor->enableCommandLogging(enable,fileName);
|
||||
}
|
||||
|
||||
void PhysicsServerSharedMemory::replayFromLogFile(const char* fileName)
|
||||
{
|
||||
m_data->m_commandProcessor->replayFromLogFile(fileName);
|
||||
}
|
52
examples/SharedMemory/PhysicsServerSharedMemory.h
Normal file
52
examples/SharedMemory/PhysicsServerSharedMemory.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef PHYSICS_SERVER_SHARED_MEMORY_H
|
||||
#define PHYSICS_SERVER_SHARED_MEMORY_H
|
||||
|
||||
#include "PhysicsServer.h"
|
||||
|
||||
class PhysicsServerSharedMemory : public PhysicsServer
|
||||
{
|
||||
struct PhysicsServerSharedMemoryInternalData* m_data;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
void releaseSharedMemory();
|
||||
|
||||
|
||||
public:
|
||||
PhysicsServerSharedMemory();
|
||||
virtual ~PhysicsServerSharedMemory();
|
||||
|
||||
virtual void setSharedMemoryKey(int key);
|
||||
|
||||
//todo: implement option to allocated shared memory from client
|
||||
virtual bool connectSharedMemory( struct GUIHelperInterface* guiHelper);
|
||||
|
||||
virtual void disconnectSharedMemory (bool deInitializeSharedMemory);
|
||||
|
||||
virtual void processClientCommands();
|
||||
|
||||
//bool supportsJointMotor(class btMultiBody* body, int linkIndex);
|
||||
|
||||
//@todo(erwincoumans) Should we have shared memory commands for picking objects?
|
||||
///The pickBody method will try to pick the first body along a ray, return true if succeeds, false otherwise
|
||||
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld);
|
||||
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld);
|
||||
virtual void removePickingConstraint();
|
||||
|
||||
//for physicsDebugDraw and renderScene are mainly for debugging purposes
|
||||
//and for physics visualization. The idea is that physicsDebugDraw can also send wireframe
|
||||
//to a physics client, over shared memory
|
||||
void physicsDebugDraw(int debugDrawFlags);
|
||||
void renderScene();
|
||||
|
||||
void enableCommandLogging(bool enable, const char* fileName);
|
||||
void replayFromLogFile(const char* fileName);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //PHYSICS_SERVER_EXAMPLESHARED_MEMORY_H
|
||||
|
||||
|
@ -25,10 +25,12 @@ struct SharedMemoryBlock
|
||||
|
||||
//m_bulletStreamDataServerToClient is used to send (debug) data from server to client, for
|
||||
//example to provide all details of a multibody including joint/link names, after loading a URDF file.
|
||||
char m_bulletStreamDataServerToClient[SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE];
|
||||
char m_bulletStreamDataServerToClientRefactor[SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE];
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//http://stackoverflow.com/questions/24736304/unable-to-use-inline-in-declaration-get-error-c2054
|
||||
#ifdef _WIN32
|
||||
__inline
|
||||
|
@ -24,6 +24,7 @@
|
||||
typedef unsigned long long int smUint64_t;
|
||||
#endif
|
||||
|
||||
#define SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE (256*1024)
|
||||
|
||||
#define SHARED_MEMORY_SERVER_TEST_C
|
||||
#define MAX_DEGREE_OF_FREEDOM 64
|
||||
@ -31,6 +32,27 @@
|
||||
#define MAX_URDF_FILENAME_LENGTH 1024
|
||||
#define MAX_FILENAME_LENGTH MAX_URDF_FILENAME_LENGTH
|
||||
|
||||
struct TmpFloat3
|
||||
{
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_z;
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
__inline
|
||||
#else
|
||||
inline
|
||||
#endif
|
||||
TmpFloat3 CreateTmpFloat3(float x, float y, float z)
|
||||
{
|
||||
TmpFloat3 tmp;
|
||||
tmp.m_x = x;
|
||||
tmp.m_y = y;
|
||||
tmp.m_z = z;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
enum EnumUrdfArgsUpdateFlags
|
||||
{
|
||||
URDF_ARGS_FILE_NAME=1,
|
||||
|
@ -70,6 +70,12 @@ enum
|
||||
COLLISION_SHAPE_TYPE_SPHERE
|
||||
};
|
||||
|
||||
// copied from btMultiBodyLink.h
|
||||
enum JointType {
|
||||
eRevoluteType = 0,
|
||||
ePrismaticType = 1,
|
||||
};
|
||||
|
||||
struct b3JointInfo
|
||||
{
|
||||
char* m_linkName;
|
||||
|
@ -20,11 +20,25 @@ files {
|
||||
"PhysicsClientSharedMemory.cpp",
|
||||
"PhysicsClientExample.cpp",
|
||||
"PhysicsServerExample.cpp",
|
||||
"PhysicsServerSharedMemory.cpp",
|
||||
"PhysicsServerSharedMemory.h",
|
||||
"PhysicsServer.cpp",
|
||||
"PhysicsServer.h",
|
||||
"main.cpp",
|
||||
"PhysicsClientC_API.cpp",
|
||||
"PhysicsServer.cpp",
|
||||
"PosixSharedMemory.cpp",
|
||||
"Win32SharedMemory.cpp",
|
||||
"PhysicsDirect.cpp",
|
||||
"PhysicsDirect.h",
|
||||
"PhysicsDirectC_API.cpp",
|
||||
"PhysicsDirectC_API.h",
|
||||
"PhysicsLoopBack.cpp",
|
||||
"PhysicsLoopBack.h",
|
||||
"PhysicsLoopBackC_Api.cpp",
|
||||
"PhysicsLoopBackC_Api.h",
|
||||
"PhysicsServerCommandProcessor.cpp",
|
||||
"PhysicsServerCommandProcessor.h",
|
||||
"../Importers/ImportURDFDemo/ConvertRigidBodies2MultiBody.h",
|
||||
"../Importers/ImportURDFDemo/MultiBodyCreationInterface.h",
|
||||
"../Importers/ImportURDFDemo/MyMultiBodyCreator.cpp",
|
||||
|
@ -26,7 +26,7 @@ project ("Test_SharedMemoryPhysicsClient")
|
||||
"../../examples/Utils/b3ResourcePath.h",
|
||||
}
|
||||
|
||||
project ("Test_PhysicsLoopBack")
|
||||
project ("Test_PhysicsServerLoopBack")
|
||||
|
||||
language "C++"
|
||||
kind "ConsoleApp"
|
||||
@ -49,6 +49,10 @@ project ("Test_PhysicsLoopBack")
|
||||
"../../examples/SharedMemory/PhysicsClient.h",
|
||||
"../../examples/SharedMemory/PhysicsServer.cpp",
|
||||
"../../examples/SharedMemory/PhysicsServer.h",
|
||||
"../../examples/SharedMemory/PhysicsServerSharedMemory.cpp",
|
||||
"../../examples/SharedMemory/PhysicsServerSharedMemory.h",
|
||||
"../../examples/SharedMemory/PhysicsServerCommandProcessor.cpp",
|
||||
"../../examples/SharedMemory/PhysicsServerCommandProcessor.h",
|
||||
"../../examples/SharedMemory/PhysicsLoopBack.cpp",
|
||||
"../../examples/SharedMemory/PhysicsLoopBack.h",
|
||||
"../../examples/SharedMemory/PhysicsLoopBackC_Api.cpp",
|
||||
@ -79,3 +83,62 @@ project ("Test_PhysicsLoopBack")
|
||||
"../../examples/Importers/ImportURDFDemo/urdfStringSplit.cpp",
|
||||
}
|
||||
|
||||
project ("Test_PhysicsServerDirect")
|
||||
|
||||
language "C++"
|
||||
kind "ConsoleApp"
|
||||
|
||||
includedirs {"../../src", "../../examples/SharedMemory",
|
||||
"../../examples/ThirdPartyLibs"}
|
||||
defines {"PHYSICS_SERVER_DIRECT"}
|
||||
links {
|
||||
"BulletFileLoader",
|
||||
"BulletWorldImporter",
|
||||
"Bullet3Common",
|
||||
"BulletDynamics",
|
||||
"BulletCollision",
|
||||
"LinearMath"
|
||||
}
|
||||
|
||||
files {
|
||||
"test.c",
|
||||
"../../examples/SharedMemory/PhysicsClient.cpp",
|
||||
"../../examples/SharedMemory/PhysicsClient.h",
|
||||
"../../examples/SharedMemory/PhysicsServer.cpp",
|
||||
"../../examples/SharedMemory/PhysicsServer.h",
|
||||
"../../examples/SharedMemory/PhysicsServerSharedMemory.cpp",
|
||||
"../../examples/SharedMemory/PhysicsServerSharedMemory.h",
|
||||
"../../examples/SharedMemory/PhysicsDirect.cpp",
|
||||
"../../examples/SharedMemory/PhysicsDirect.h",
|
||||
"../../examples/SharedMemory/PhysicsDirectC_API.cpp",
|
||||
"../../examples/SharedMemory/PhysicsDirectC_API.h",
|
||||
"../../examples/SharedMemory/PhysicsServerCommandProcessor.cpp",
|
||||
"../../examples/SharedMemory/PhysicsServerCommandProcessor.h",
|
||||
"../../examples/SharedMemory/PhysicsClientSharedMemory.cpp",
|
||||
"../../examples/SharedMemory/PhysicsClientSharedMemory.h",
|
||||
"../../examples/SharedMemory/PhysicsClientC_API.cpp",
|
||||
"../../examples/SharedMemory/PhysicsClientC_API.h",
|
||||
"../../examples/SharedMemory/Win32SharedMemory.cpp",
|
||||
"../../examples/SharedMemory/Win32SharedMemory.h",
|
||||
"../../examples/SharedMemory/PosixSharedMemory.cpp",
|
||||
"../../examples/SharedMemory/PosixSharedMemory.h",
|
||||
"../../examples/Utils/b3ResourcePath.cpp",
|
||||
"../../examples/Utils/b3ResourcePath.h",
|
||||
"../../examples/ThirdPartyLibs/tinyxml/tinystr.cpp",
|
||||
"../../examples/ThirdPartyLibs/tinyxml/tinyxml.cpp",
|
||||
"../../examples/ThirdPartyLibs/tinyxml/tinyxmlerror.cpp",
|
||||
"../../examples/ThirdPartyLibs/tinyxml/tinyxmlparser.cpp",
|
||||
"../../examples/ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp",
|
||||
"../../examples/ThirdPartyLibs/Wavefront/tiny_obj_loader.h",
|
||||
"../../examples/Importers/ImportColladaDemo/LoadMeshFromCollada.cpp",
|
||||
"../../examples/Importers/ImportObjDemo/LoadMeshFromObj.cpp",
|
||||
"../../examples/Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp",
|
||||
"../../examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp",
|
||||
"../../examples/Importers/ImportURDFDemo/MyMultiBodyCreator.cpp",
|
||||
"../../examples/Importers/ImportURDFDemo/URDF2Bullet.cpp",
|
||||
"../../examples/Importers/ImportURDFDemo/UrdfParser.cpp",
|
||||
"../../examples/Importers/ImportURDFDemo/urdfStringSplit.cpp",
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,6 +5,11 @@
|
||||
#include "PhysicsLoopBackC_API.h"
|
||||
#endif //PHYSICS_LOOP_BACK
|
||||
|
||||
#ifdef PHYSICS_SERVER_DIRECT
|
||||
#include "PhysicsDirectC_API.h"
|
||||
#endif //PHYSICS_SERVER_DIRECT
|
||||
|
||||
|
||||
#include "SharedMemoryPublic.h"
|
||||
#include "Bullet3Common/b3Logging.h"
|
||||
#include <string.h>
|
||||
@ -28,12 +33,17 @@ int main(int argc, char* argv[])
|
||||
b3PhysicsClientHandle sm=0;
|
||||
int bodyIndex = -1;
|
||||
|
||||
|
||||
printf("hello world\n");
|
||||
#ifdef PHYSICS_LOOP_BACK
|
||||
sm = b3ConnectPhysicsLoopback(SHARED_MEMORY_KEY);
|
||||
#else
|
||||
sm = b3ConnectSharedMemory(SHARED_MEMORY_KEY);
|
||||
#endif
|
||||
|
||||
#ifdef PHYSICS_SERVER_DIRECT
|
||||
sm = b3ConnectPhysicsDirect();
|
||||
#else//PHYSICS_SERVER_DIRECT
|
||||
sm = b3ConnectSharedMemory(SHARED_MEMORY_KEY);
|
||||
#endif //PHYSICS_SERVER_DIRECT
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user