mirror of
https://github.com/bulletphysics/bullet3.git
synced 2026-10-22 00:30:58 +00:00
embed TCP graphics server in PyBullet for easier working-from-home
This allows to render at a different machine, sending all assets across the TCP network, using port 6667 by default. You can use ssh port forwarding to get this working: ssh -R 6667:localhost:6667 username@remotehost.com -v python3 -m pybullet_utils.graphicsServer python3 -m pybullet_utils.graphicsClient Note that there are still some tcp networking issues that can cause a hang, just restart graphics server and graphics client if it hangs.
This commit is contained in:
@@ -11,10 +11,557 @@
|
||||
#include "GraphicsSharedMemoryBlock.h"
|
||||
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
||||
#include "SharedMemoryPublic.h"
|
||||
#include "../MultiThreading/b3ThreadSupportInterface.h"
|
||||
#include "Utils/b3Clock.h"
|
||||
|
||||
#ifdef BT_ENABLE_CLSOCKET
|
||||
|
||||
#include "PassiveSocket.h" // Include header for active socket object definition
|
||||
#include <stdio.h>
|
||||
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
||||
#include "Bullet3Common/b3CommandLineArgs.h"
|
||||
#include "RemoteGUIHelper.h"
|
||||
#include "GraphicsSharedMemoryPublic.h"
|
||||
#include "GraphicsSharedMemoryCommands.h"
|
||||
|
||||
|
||||
bool gVerboseNetworkMessagesServer = false;
|
||||
|
||||
void MySerializeInt(unsigned int sz, unsigned char* output)
|
||||
{
|
||||
unsigned int tmp = sz;
|
||||
output[0] = tmp & 255;
|
||||
tmp = tmp >> 8;
|
||||
output[1] = tmp & 255;
|
||||
tmp = tmp >> 8;
|
||||
output[2] = tmp & 255;
|
||||
tmp = tmp >> 8;
|
||||
output[3] = tmp & 255;
|
||||
}
|
||||
|
||||
void submitStatus(CActiveSocket* pClient, GraphicsSharedMemoryStatus& serverStatus, b3AlignedObjectArray<char>& buffer)
|
||||
{
|
||||
b3AlignedObjectArray<unsigned char> packetData;
|
||||
unsigned char* statBytes = (unsigned char*)&serverStatus;
|
||||
|
||||
|
||||
//create packetData with [int packetSizeInBytes, status, streamBytes)
|
||||
packetData.resize(4 + sizeof(GraphicsSharedMemoryStatus) + serverStatus.m_numDataStreamBytes);
|
||||
int sz = packetData.size();
|
||||
int curPos = 0;
|
||||
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
{
|
||||
//printf("buffer.size = %d\n", buffer.size());
|
||||
printf("serverStatus packed size = %d\n", sz);
|
||||
}
|
||||
|
||||
MySerializeInt(sz, &packetData[curPos]);
|
||||
curPos += 4;
|
||||
for (int i = 0; i < sizeof(GraphicsSharedMemoryStatus); i++)
|
||||
{
|
||||
packetData[i + curPos] = statBytes[i];
|
||||
}
|
||||
curPos += sizeof(GraphicsSharedMemoryStatus);
|
||||
|
||||
for (int i = 0; i < serverStatus.m_numDataStreamBytes; i++)
|
||||
{
|
||||
packetData[i + curPos] = buffer[i];
|
||||
}
|
||||
|
||||
pClient->Send(&packetData[0], packetData.size());
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("pClient->Send serverStatus: %d\n", packetData.size());
|
||||
}
|
||||
|
||||
|
||||
#endif //BT_ENABLE_CLSOCKET
|
||||
|
||||
|
||||
#define MAX_GRAPHICS_SHARED_MEMORY_BLOCKS 1
|
||||
|
||||
|
||||
struct TCPArgs
|
||||
{
|
||||
TCPArgs()
|
||||
: m_cs(0),
|
||||
m_port(6667)
|
||||
{
|
||||
}
|
||||
b3CriticalSection* m_cs;
|
||||
int m_port;
|
||||
};
|
||||
|
||||
struct TCPThreadLocalStorage
|
||||
{
|
||||
int threadId;
|
||||
};
|
||||
|
||||
|
||||
enum TCPCommunicationEnums
|
||||
{
|
||||
eTCPRequestTerminate = 11,
|
||||
eTCPIsUnInitialized,
|
||||
eTCPIsInitialized,
|
||||
eTCPInitializationFailed,
|
||||
eTCPHasTerminated
|
||||
};
|
||||
|
||||
void TCPThreadFunc(void* userPtr, void* lsMemory)
|
||||
{
|
||||
printf("TCPThreadFunc thread started\n");
|
||||
|
||||
TCPArgs* args = (TCPArgs*)userPtr;
|
||||
//int workLeft = true;
|
||||
b3Clock clock;
|
||||
clock.reset();
|
||||
b3Clock sleepClock;
|
||||
bool init = true;
|
||||
if (init)
|
||||
{
|
||||
unsigned int cachedSharedParam = eTCPIsInitialized;
|
||||
|
||||
args->m_cs->lock();
|
||||
args->m_cs->setSharedParam(0, eTCPIsInitialized);
|
||||
args->m_cs->unlock();
|
||||
|
||||
double deltaTimeInSeconds = 0;
|
||||
int numCmdSinceSleep1ms = 0;
|
||||
unsigned long long int prevTime = clock.getTimeMicroseconds();
|
||||
|
||||
#ifdef BT_ENABLE_CLSOCKET
|
||||
b3Clock clock;
|
||||
double timeOutInSeconds = 10;
|
||||
|
||||
RemoteGUIHelper guiHelper;
|
||||
bool isPhysicsClientConnected = guiHelper.isConnected();
|
||||
bool exitRequested = false;
|
||||
|
||||
b3AlignedObjectArray< b3AlignedObjectArray<char> > slots;
|
||||
int maxSlots = 10;
|
||||
slots.resize(maxSlots);
|
||||
if (!isPhysicsClientConnected)
|
||||
{
|
||||
printf("TCP thread error connecting to shared memory. Machine needs a reboot?\n");
|
||||
}
|
||||
btAssert(isPhysicsClientConnected);
|
||||
|
||||
printf("Starting TCP server using port %d\n", args->m_port);
|
||||
|
||||
CPassiveSocket socket;
|
||||
CActiveSocket* pClient = NULL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Initialize our socket object
|
||||
//--------------------------------------------------------------------------
|
||||
socket.Initialize();
|
||||
|
||||
socket.Listen("localhost", args->m_port);
|
||||
|
||||
//socket.SetReceiveTimeout(1, 0);
|
||||
//socket.SetNonblocking();
|
||||
|
||||
int curNumErr = 0;
|
||||
|
||||
#endif
|
||||
|
||||
do
|
||||
{
|
||||
{
|
||||
b3Clock::usleep(0);
|
||||
}
|
||||
///////////////////////////////
|
||||
|
||||
#ifdef BT_ENABLE_CLSOCKET
|
||||
|
||||
{
|
||||
b3Clock::usleep(0);
|
||||
|
||||
if ((pClient = socket.Accept()) != NULL)
|
||||
{
|
||||
b3AlignedObjectArray<char> bytesReceived;
|
||||
|
||||
int clientPort = socket.GetClientPort();
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("connected from %s:%d\n", socket.GetClientAddr(), clientPort);
|
||||
|
||||
if (pClient->Receive(4))
|
||||
{
|
||||
int clientKey = *(int*)pClient->GetData();
|
||||
|
||||
if (clientKey == GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER)
|
||||
{
|
||||
printf("Client version OK %d\n", clientKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Server version (%d) mismatches Client Version (%d)\n", GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER, clientKey);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Receive request from the client.
|
||||
//----------------------------------------------------------------------
|
||||
while (cachedSharedParam != eTCPRequestTerminate)
|
||||
{
|
||||
//printf("try receive\n");
|
||||
bool receivedData = false;
|
||||
|
||||
int maxLen = 4 + sizeof(GraphicsSharedMemoryCommand) + GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE;
|
||||
|
||||
if (pClient->Receive(maxLen))
|
||||
{
|
||||
//heuristic to detect disconnected clients
|
||||
CSimpleSocket::CSocketError err = pClient->GetSocketError();
|
||||
|
||||
if (err != CSimpleSocket::SocketSuccess || !pClient->IsSocketValid())
|
||||
{
|
||||
b3Clock::usleep(100);
|
||||
|
||||
curNumErr++;
|
||||
|
||||
if (curNumErr > 100)
|
||||
{
|
||||
printf("TCP Connection error = %d, curNumErr = %d\n", (int)err, curNumErr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curNumErr = 0;
|
||||
char* msg2 = (char*)pClient->GetData();
|
||||
int numBytesRec2 = pClient->GetBytesReceived();
|
||||
if (numBytesRec2 < 0)
|
||||
{
|
||||
numBytesRec2 = 0;
|
||||
}
|
||||
int curSize = bytesReceived.size();
|
||||
bytesReceived.resize(bytesReceived.size() + numBytesRec2);
|
||||
for (int i = 0; i < numBytesRec2; i++)
|
||||
{
|
||||
bytesReceived[curSize + i] = msg2[i];
|
||||
}
|
||||
|
||||
if (bytesReceived.size() >= 4)
|
||||
{
|
||||
int numBytesRec = bytesReceived.size();
|
||||
if (numBytesRec >= 10)
|
||||
{
|
||||
if (strncmp(&bytesReceived[0], "disconnect", 10) == 0)
|
||||
{
|
||||
printf("Disconnect request received\n");
|
||||
bytesReceived.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
{
|
||||
printf("received message length [%d]\n", numBytesRec);
|
||||
}
|
||||
|
||||
receivedData = true;
|
||||
|
||||
GraphicsSharedMemoryCommand cmd;
|
||||
|
||||
GraphicsSharedMemoryCommand* cmdPtr = 0;
|
||||
|
||||
int type = *(int*)&bytesReceived[0];
|
||||
|
||||
//performance test
|
||||
if (numBytesRec == sizeof(int))
|
||||
{
|
||||
cmdPtr = &cmd;
|
||||
cmd.m_type = *(int*)&bytesReceived[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (numBytesRec == sizeof(GraphicsSharedMemoryCommand))
|
||||
{
|
||||
cmdPtr = (GraphicsSharedMemoryCommand*)&bytesReceived[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (numBytesRec == 36)
|
||||
{
|
||||
cmdPtr = &cmd;
|
||||
memcpy(&cmd, &bytesReceived[0], numBytesRec);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cmdPtr)
|
||||
{
|
||||
GraphicsSharedMemoryStatus serverStatus;
|
||||
serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_FAILED;
|
||||
serverStatus.m_numDataStreamBytes = 0;
|
||||
b3AlignedObjectArray<char> buffer;
|
||||
buffer.resize(GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
|
||||
bool hasStatus = true;
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("processing command:");
|
||||
switch (cmdPtr->m_type)
|
||||
{
|
||||
case GFX_CMD_0:
|
||||
{
|
||||
int axis = cmdPtr->m_upAxisYCommand.m_enableUpAxisY ? 1 : 2;
|
||||
guiHelper.setUpAxis(axis);
|
||||
serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_COMPLETED;
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("GFX_CMD_0\n");
|
||||
break;
|
||||
}
|
||||
|
||||
case GFX_CMD_SET_VISUALIZER_FLAG:
|
||||
{
|
||||
guiHelper.setVisualizerFlag(
|
||||
cmdPtr->m_visualizerFlagCommand.m_visualizerFlag,
|
||||
cmdPtr->m_visualizerFlagCommand.m_enable);
|
||||
serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_COMPLETED;
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("GFX_CMD_SET_VISUALIZER_FLAG\n");
|
||||
break;
|
||||
}
|
||||
case GFX_CMD_UPLOAD_DATA:
|
||||
{
|
||||
int slot = cmdPtr->m_uploadDataCommand.m_dataSlot;
|
||||
|
||||
submitStatus(pClient, serverStatus, buffer);
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("GFX_CMD_UPLOAD_DATA receiving data\n");
|
||||
if (pClient->Receive(cmdPtr->m_uploadDataCommand.m_numBytes))
|
||||
{
|
||||
|
||||
//heuristic to detect disconnected clients
|
||||
CSimpleSocket::CSocketError err = pClient->GetSocketError();
|
||||
|
||||
if (err != CSimpleSocket::SocketSuccess || !pClient->IsSocketValid())
|
||||
{
|
||||
curNumErr++;
|
||||
printf("TCP Connection error = %d, curNumErr = %d\n", (int)err, curNumErr);
|
||||
}
|
||||
char* msg2 = (char*)pClient->GetData();
|
||||
int numBytesRec2 = pClient->GetBytesReceived();
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("received %d bytes\n", numBytesRec2);
|
||||
slots[slot].resize(numBytesRec2);
|
||||
for (int i = 0; i < numBytesRec2; i++)
|
||||
{
|
||||
slots[slot][i] = msg2[i];
|
||||
}
|
||||
}
|
||||
serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_COMPLETED;
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("GFX_CMD_UPLOAD_DATA\n");
|
||||
break;
|
||||
}
|
||||
case GFX_CMD_REGISTER_TEXTURE:
|
||||
{
|
||||
const unsigned char* texels = (const unsigned char*)&slots[0][0];
|
||||
serverStatus.m_registerTextureStatus.m_textureId = guiHelper.registerTexture(texels, cmdPtr->m_registerTextureCommand.m_width,
|
||||
cmdPtr->m_registerTextureCommand.m_height);
|
||||
serverStatus.m_type = GFX_CMD_REGISTER_TEXTURE_COMPLETED;
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("GFX_CMD_REGISTER_TEXTURE\n");
|
||||
break;
|
||||
}
|
||||
case GFX_CMD_REGISTER_GRAPHICS_SHAPE:
|
||||
{
|
||||
const float* vertices = (const float*)&slots[0][0];
|
||||
const int* indices = (const int*)&slots[1][0];
|
||||
|
||||
serverStatus.m_registerGraphicsShapeStatus.m_shapeId = guiHelper.registerGraphicsShape(vertices, cmdPtr->m_registerGraphicsShapeCommand.m_numVertices, indices,
|
||||
cmdPtr->m_registerGraphicsShapeCommand.m_numIndices, cmdPtr->m_registerGraphicsShapeCommand.m_primitiveType,
|
||||
cmdPtr->m_registerGraphicsShapeCommand.m_textureId);
|
||||
serverStatus.m_type = GFX_CMD_REGISTER_GRAPHICS_SHAPE_COMPLETED;
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("GFX_CMD_REGISTER_GRAPHICS_SHAPE\n");
|
||||
break;
|
||||
}
|
||||
case GFX_CMD_REGISTER_GRAPHICS_INSTANCE:
|
||||
{
|
||||
serverStatus.m_registerGraphicsInstanceStatus.m_graphicsInstanceId =
|
||||
guiHelper.registerGraphicsInstance(
|
||||
cmdPtr->m_registerGraphicsInstanceCommand.m_shapeIndex,
|
||||
cmdPtr->m_registerGraphicsInstanceCommand.m_position,
|
||||
cmdPtr->m_registerGraphicsInstanceCommand.m_quaternion,
|
||||
cmdPtr->m_registerGraphicsInstanceCommand.m_color,
|
||||
cmdPtr->m_registerGraphicsInstanceCommand.m_scaling);
|
||||
serverStatus.m_type = GFX_CMD_REGISTER_GRAPHICS_INSTANCE_COMPLETED;
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("GFX_CMD_REGISTER_GRAPHICS_INSTANCE\n");
|
||||
break;
|
||||
}
|
||||
case GFX_CMD_SYNCHRONIZE_TRANSFORMS:
|
||||
{
|
||||
const GUISyncPosition* positions = (const GUISyncPosition*)&slots[0][0];
|
||||
guiHelper.syncPhysicsToGraphics2(positions, cmdPtr->m_syncTransformsCommand.m_numPositions);
|
||||
serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_COMPLETED;
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("GFX_CMD_SYNCHRONIZE_TRANSFORMS\n");
|
||||
break;
|
||||
}
|
||||
case GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES:
|
||||
{
|
||||
guiHelper.removeAllGraphicsInstances();
|
||||
serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_COMPLETED;
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES\n");
|
||||
break;
|
||||
}
|
||||
case GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE:
|
||||
{
|
||||
guiHelper.removeGraphicsInstance(cmdPtr->m_removeGraphicsInstanceCommand.m_graphicsUid);
|
||||
serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_COMPLETED;
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE\n");
|
||||
break;
|
||||
}
|
||||
case GFX_CMD_CHANGE_RGBA_COLOR:
|
||||
{
|
||||
guiHelper.changeRGBAColor(cmdPtr->m_changeRGBAColorCommand.m_graphicsUid,
|
||||
cmdPtr->m_changeRGBAColorCommand.m_rgbaColor);
|
||||
serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_COMPLETED;
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("GFX_CMD_CHANGE_RGBA_COLOR\n");
|
||||
break;
|
||||
}
|
||||
case GFX_CMD_GET_CAMERA_INFO:
|
||||
{
|
||||
//bool RemoteGUIHelper::getCameraInfo(int* width, int* height,
|
||||
// float viewMatrix[16], float projectionMatrix[16],
|
||||
// float camUp[3], float camForward[3], float hor[3], float vert[3],
|
||||
// float* yaw, float* pitch, float* camDist, float camTarget[3]) const
|
||||
|
||||
guiHelper.getCameraInfo(&serverStatus.m_getCameraInfoStatus.width,
|
||||
&serverStatus.m_getCameraInfoStatus.height,
|
||||
serverStatus.m_getCameraInfoStatus.viewMatrix,
|
||||
serverStatus.m_getCameraInfoStatus.projectionMatrix,
|
||||
serverStatus.m_getCameraInfoStatus.camUp,
|
||||
serverStatus.m_getCameraInfoStatus.camForward,
|
||||
serverStatus.m_getCameraInfoStatus.hor,
|
||||
serverStatus.m_getCameraInfoStatus.vert,
|
||||
&serverStatus.m_getCameraInfoStatus.yaw,
|
||||
&serverStatus.m_getCameraInfoStatus.pitch,
|
||||
&serverStatus.m_getCameraInfoStatus.camDist,
|
||||
serverStatus.m_getCameraInfoStatus.camTarget);
|
||||
serverStatus.m_type = GFX_CMD_GET_CAMERA_INFO_COMPLETED;
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
printf("GFX_CMD_GET_CAMERA_INFO\n");
|
||||
break;
|
||||
}
|
||||
|
||||
case GFX_CMD_INVALID:
|
||||
case GFX_CMD_MAX_CLIENT_COMMANDS:
|
||||
default:
|
||||
{
|
||||
printf("UNKNOWN COMMAND!\n");
|
||||
btAssert(0);
|
||||
hasStatus = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double startTimeSeconds = clock.getTimeInSeconds();
|
||||
double curTimeSeconds = clock.getTimeInSeconds();
|
||||
|
||||
if (gVerboseNetworkMessagesServer)
|
||||
{
|
||||
//printf("buffer.size = %d\n", buffer.size());
|
||||
printf("serverStatus.m_numDataStreamBytes = %d\n", serverStatus.m_numDataStreamBytes);
|
||||
}
|
||||
if (hasStatus)
|
||||
{
|
||||
submitStatus(pClient, serverStatus, buffer);
|
||||
}
|
||||
|
||||
bytesReceived.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
//likely an incomplete packet, let's append more bytes
|
||||
//printf("received packet with unknown contents\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!receivedData)
|
||||
{
|
||||
//printf("Didn't receive data.\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("Disconnecting client.\n");
|
||||
pClient->Close();
|
||||
delete pClient;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //BT_ENABLE_CLSOCKET
|
||||
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
args->m_cs->lock();
|
||||
cachedSharedParam = args->m_cs->getSharedParam(0);
|
||||
args->m_cs->unlock();
|
||||
|
||||
} while (cachedSharedParam != eTCPRequestTerminate);
|
||||
|
||||
socket.Close();
|
||||
socket.Shutdown(CSimpleSocket::Both);
|
||||
}
|
||||
else
|
||||
{
|
||||
args->m_cs->lock();
|
||||
args->m_cs->setSharedParam(0, eTCPInitializationFailed);
|
||||
args->m_cs->unlock();
|
||||
}
|
||||
|
||||
printf("TCPThreadFunc thread exit\n");
|
||||
//do nothing
|
||||
}
|
||||
|
||||
void* TCPlsMemoryFunc()
|
||||
{
|
||||
//don't create local store memory, just return 0
|
||||
return new TCPThreadLocalStorage;
|
||||
}
|
||||
|
||||
void TCPlsMemoryReleaseFunc(void* ptr)
|
||||
{
|
||||
TCPThreadLocalStorage* p = (TCPThreadLocalStorage*)ptr;
|
||||
delete p;
|
||||
}
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "../MultiThreading/b3PosixThreadSupport.h"
|
||||
|
||||
b3ThreadSupportInterface* createTCPThreadSupport(int numThreads)
|
||||
{
|
||||
b3PosixThreadSupport::ThreadConstructionInfo constructionInfo("TCPThreads",
|
||||
TCPThreadFunc,
|
||||
TCPlsMemoryFunc,
|
||||
TCPlsMemoryReleaseFunc,
|
||||
numThreads);
|
||||
b3ThreadSupportInterface* threadSupport = new b3PosixThreadSupport(constructionInfo);
|
||||
|
||||
return threadSupport;
|
||||
}
|
||||
|
||||
#elif defined(_WIN32)
|
||||
#include "../MultiThreading/b3Win32ThreadSupport.h"
|
||||
|
||||
b3ThreadSupportInterface* createTCPThreadSupport(int numThreads)
|
||||
{
|
||||
b3Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("TCPThreads", TCPThreadFunc, TCPlsMemoryFunc, TCPlsMemoryReleaseFunc, numThreads);
|
||||
b3Win32ThreadSupport* threadSupport = new b3Win32ThreadSupport(threadConstructionInfo);
|
||||
return threadSupport;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
class GraphicsServerExample : public CommonExampleInterface
|
||||
{
|
||||
CommonGraphicsApp* m_app;
|
||||
@@ -29,7 +576,10 @@ class GraphicsServerExample : public CommonExampleInterface
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_z;
|
||||
|
||||
|
||||
b3ThreadSupportInterface* m_threadSupport;
|
||||
TCPArgs m_args;
|
||||
|
||||
public:
|
||||
GraphicsServerExample(GUIHelperInterface* guiHelper)
|
||||
: m_guiHelper(guiHelper),
|
||||
@@ -42,6 +592,7 @@ public:
|
||||
m_app = guiHelper->getAppInterface();
|
||||
m_app->setUpAxis(2);
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < MAX_GRAPHICS_SHARED_MEMORY_BLOCKS; i++)
|
||||
{
|
||||
@@ -54,23 +605,54 @@ public:
|
||||
m_sharedMemory = new PosixSharedMemory();
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
{
|
||||
int boxId = m_app->registerCubeShape(0.1, 0.1, 0.1);
|
||||
btVector3 pos(0, 0, 0);
|
||||
btQuaternion orn(0, 0, 0, 1);
|
||||
btVector4 color(0.3, 0.3, 0.3, 1);
|
||||
btVector3 scaling(1, 1, 1);
|
||||
m_app->m_renderer->registerGraphicsInstance(boxId, pos, orn, color, scaling);
|
||||
}
|
||||
|
||||
m_app->m_renderer->writeTransforms();
|
||||
#endif
|
||||
connectSharedMemory(m_guiHelper, m_sharedMemoryKey);
|
||||
|
||||
|
||||
|
||||
m_threadSupport = createTCPThreadSupport(1);
|
||||
m_args.m_cs = m_threadSupport->createCriticalSection();
|
||||
m_args.m_cs->setSharedParam(0, eTCPIsUnInitialized);
|
||||
m_threadSupport->runTask(B3_THREAD_SCHEDULE_TASK, (void*)&this->m_args, 0);
|
||||
|
||||
bool isUninitialized = true;
|
||||
|
||||
while (isUninitialized)
|
||||
{
|
||||
m_args.m_cs->lock();
|
||||
isUninitialized = (m_args.m_cs->getSharedParam(0) == eTCPIsUnInitialized);
|
||||
m_args.m_cs->unlock();
|
||||
#ifdef _WIN32
|
||||
b3Clock::usleep(1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
virtual ~GraphicsServerExample()
|
||||
{
|
||||
|
||||
m_args.m_cs->setSharedParam(0, eTCPRequestTerminate);
|
||||
|
||||
int numActiveThreads = 1;
|
||||
while (numActiveThreads)
|
||||
{
|
||||
int arg0, arg1;
|
||||
if (m_threadSupport->isTaskCompleted(&arg0, &arg1, 0))
|
||||
{
|
||||
numActiveThreads--;
|
||||
printf("numActiveThreads = %d\n", numActiveThreads);
|
||||
}
|
||||
else
|
||||
{
|
||||
b3Clock::usleep(0);
|
||||
}
|
||||
};
|
||||
|
||||
m_threadSupport->deleteCriticalSection(m_args.m_cs);
|
||||
|
||||
delete m_threadSupport;
|
||||
m_threadSupport = 0;
|
||||
|
||||
disconnectSharedMemory();
|
||||
}
|
||||
|
||||
|
||||
@@ -218,6 +218,11 @@ RemoteGUIHelper::~RemoteGUIHelper()
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
bool RemoteGUIHelper::isConnected() const
|
||||
{
|
||||
return m_data->isConnected();
|
||||
}
|
||||
|
||||
void RemoteGUIHelper::setVisualizerFlag(int flag, int enable)
|
||||
{
|
||||
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
|
||||
|
||||
@@ -12,6 +12,8 @@ struct RemoteGUIHelper : public GUIHelperInterface
|
||||
|
||||
virtual ~RemoteGUIHelper();
|
||||
|
||||
bool isConnected() const;
|
||||
|
||||
virtual void setVisualizerFlag(int flag, int enable);
|
||||
|
||||
virtual void createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color);
|
||||
|
||||
75
examples/SharedMemory/RemoteGUIHelperTCP.h
Normal file
75
examples/SharedMemory/RemoteGUIHelperTCP.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#ifndef REMOTE_HELPER_TCP_H
|
||||
#define REMOTE_HELPER_TCP_H
|
||||
|
||||
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
||||
|
||||
///a RemoteGUIHelper will connect to an existing graphics server over TCP
|
||||
struct RemoteGUIHelperTCP : public GUIHelperInterface
|
||||
{
|
||||
struct RemoteGUIHelperTCPInternalData* m_data;
|
||||
|
||||
RemoteGUIHelperTCP(const char* hostName, int port);
|
||||
|
||||
virtual ~RemoteGUIHelperTCP();
|
||||
|
||||
virtual void setVisualizerFlag(int flag, int enable);
|
||||
|
||||
virtual void createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color);
|
||||
|
||||
virtual void createCollisionObjectGraphicsObject(btCollisionObject* body, const btVector3& color);
|
||||
|
||||
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape);
|
||||
|
||||
virtual bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3], float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float camTarget[3]) const;
|
||||
|
||||
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld);
|
||||
virtual void syncPhysicsToGraphics2(const class btDiscreteDynamicsWorld* rbWorld);
|
||||
virtual void syncPhysicsToGraphics2(const GUISyncPosition* positions, int numPositions);
|
||||
|
||||
virtual void render(const btDiscreteDynamicsWorld* rbWorld);
|
||||
|
||||
virtual void createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld);
|
||||
|
||||
virtual int registerTexture(const unsigned char* texels, int width, int height);
|
||||
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId);
|
||||
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling);
|
||||
virtual void removeAllGraphicsInstances();
|
||||
virtual void removeGraphicsInstance(int graphicsUid);
|
||||
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]);
|
||||
|
||||
virtual Common2dCanvasInterface* get2dCanvasInterface();
|
||||
|
||||
virtual CommonParameterInterface* getParameterInterface();
|
||||
|
||||
virtual CommonRenderInterface* getRenderInterface();
|
||||
|
||||
virtual CommonGraphicsApp* getAppInterface();
|
||||
|
||||
virtual void setUpAxis(int axis);
|
||||
|
||||
virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ);
|
||||
|
||||
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
|
||||
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
|
||||
float* depthBuffer, int depthBufferSizeInPixels,
|
||||
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
|
||||
int startPixelIndex, int width, int height, int* numPixelsCopied);
|
||||
|
||||
virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]);
|
||||
|
||||
virtual void setProjectiveTexture(bool useProjectiveTexture);
|
||||
|
||||
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld);
|
||||
|
||||
virtual void drawText3D(const char* txt, float posX, float posZY, float posZ, float size);
|
||||
|
||||
virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag);
|
||||
|
||||
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid);
|
||||
virtual void removeUserDebugItem(int debugItemUniqueId);
|
||||
virtual void removeAllUserDebugItems();
|
||||
|
||||
int uploadData(const unsigned char* data, int sizeInBytes, int slot);
|
||||
};
|
||||
|
||||
#endif //REMOTE_HELPER_TCP_H
|
||||
637
examples/SharedMemory/RemoteGuiHelperTCP.cpp
Normal file
637
examples/SharedMemory/RemoteGuiHelperTCP.cpp
Normal file
@@ -0,0 +1,637 @@
|
||||
#include "RemoteGUIHelperTCP.h"
|
||||
|
||||
#include "../CommonInterfaces/CommonExampleInterface.h"
|
||||
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
||||
#include "Bullet3Common/b3Logging.h"
|
||||
#include "GraphicsSharedMemoryCommands.h"
|
||||
#include "PosixSharedMemory.h"
|
||||
#include "Win32SharedMemory.h"
|
||||
#include "GraphicsSharedMemoryBlock.h"
|
||||
|
||||
#include "Bullet3Common/b3Scalar.h"
|
||||
#include "LinearMath/btMinMax.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||
#include "Bullet3Common/b3AlignedObjectArray.h"
|
||||
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
|
||||
|
||||
#include "ActiveSocket.h"
|
||||
#include <string>
|
||||
static unsigned int b3DeserializeInt3(const unsigned char* input)
|
||||
{
|
||||
unsigned int tmp = (input[3] << 24) + (input[2] << 16) + (input[1] << 8) + input[0];
|
||||
return tmp;
|
||||
}
|
||||
static bool gVerboseNetworkMessagesClient3 = false;
|
||||
|
||||
const char* cmd2txt[]=
|
||||
{
|
||||
"GFX_CMD_INVALID",
|
||||
"GFX_CMD_0",
|
||||
"GFX_CMD_SET_VISUALIZER_FLAG",
|
||||
"GFX_CMD_UPLOAD_DATA",
|
||||
"GFX_CMD_REGISTER_TEXTURE",
|
||||
"GFX_CMD_REGISTER_GRAPHICS_SHAPE",
|
||||
"GFX_CMD_REGISTER_GRAPHICS_INSTANCE",
|
||||
"GFX_CMD_SYNCHRONIZE_TRANSFORMS",
|
||||
"GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES",
|
||||
"GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE",
|
||||
"GFX_CMD_CHANGE_RGBA_COLOR",
|
||||
"GFX_CMD_GET_CAMERA_INFO",
|
||||
//don't go beyond this command!
|
||||
"GFX_CMD_MAX_CLIENT_COMMANDS",
|
||||
};
|
||||
|
||||
|
||||
struct RemoteGUIHelperTCPInternalData
|
||||
{
|
||||
// GUIHelperInterface* m_guiHelper;
|
||||
bool m_waitingForServer;
|
||||
std::string m_hostName;
|
||||
int m_port;
|
||||
|
||||
GraphicsSharedMemoryStatus m_lastServerStatus;
|
||||
CActiveSocket m_tcpSocket;
|
||||
bool m_isConnected;
|
||||
b3AlignedObjectArray<unsigned char> m_tempBuffer;
|
||||
GraphicsSharedMemoryStatus m_lastStatus;
|
||||
GraphicsSharedMemoryCommand m_command;
|
||||
double m_timeOutInSeconds;
|
||||
b3AlignedObjectArray<char> m_stream;
|
||||
|
||||
RemoteGUIHelperTCPInternalData(const char* hostName, int port)
|
||||
: m_waitingForServer(false),
|
||||
m_hostName(hostName),
|
||||
m_port(port),
|
||||
m_timeOutInSeconds(60.)
|
||||
{
|
||||
m_isConnected = false;
|
||||
connect();
|
||||
m_tcpSocket.SetBlocking();
|
||||
}
|
||||
|
||||
virtual ~RemoteGUIHelperTCPInternalData()
|
||||
{
|
||||
disconnect();
|
||||
|
||||
}
|
||||
|
||||
virtual bool isConnected()
|
||||
{
|
||||
return m_isConnected;
|
||||
}
|
||||
|
||||
bool canSubmitCommand() const
|
||||
{
|
||||
if (m_isConnected && !m_waitingForServer)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct GraphicsSharedMemoryCommand* getAvailableSharedMemoryCommand()
|
||||
{
|
||||
static int sequence = 0;
|
||||
m_command.m_sequenceNumber = sequence++;
|
||||
return &m_command;
|
||||
}
|
||||
|
||||
bool submitClientCommand(const GraphicsSharedMemoryCommand& command)
|
||||
{
|
||||
if (gVerboseNetworkMessagesClient3)
|
||||
printf("submitClientCommand: %d %s\n", command.m_type, cmd2txt[command.m_type]);
|
||||
/// at the moment we allow a maximum of 1 outstanding command, so we check for this
|
||||
// once the server processed the command and returns a status, we clear the flag
|
||||
// "m_data->m_waitingForServer" and allow submitting the next command
|
||||
btAssert(!m_waitingForServer);
|
||||
if (!m_waitingForServer)
|
||||
{
|
||||
int sz = 0;
|
||||
unsigned char* data = 0;
|
||||
m_tempBuffer.clear();
|
||||
sz = sizeof(GraphicsSharedMemoryCommand);
|
||||
data = (unsigned char*)&command;
|
||||
//printf("submit command of type %d\n", command.m_type);
|
||||
m_tcpSocket.Send((const uint8*)data, sz);
|
||||
m_waitingForServer = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const GraphicsSharedMemoryStatus* processServerStatus()
|
||||
{
|
||||
|
||||
bool hasStatus = false;
|
||||
|
||||
//int serviceResult = enet_host_service(m_client, &m_event, 0);
|
||||
int maxLen = 4 + sizeof(GraphicsSharedMemoryStatus) + GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE;
|
||||
|
||||
int rBytes = m_tcpSocket.Receive(maxLen);
|
||||
if (rBytes <= 0)
|
||||
return false;
|
||||
|
||||
//append to tmp buffer
|
||||
//recBytes
|
||||
|
||||
unsigned char* d2 = (unsigned char*)m_tcpSocket.GetData();
|
||||
|
||||
int curSize = m_tempBuffer.size();
|
||||
m_tempBuffer.resize(curSize + rBytes);
|
||||
for (int i = 0; i < rBytes; i++)
|
||||
{
|
||||
m_tempBuffer[curSize + i] = d2[i];
|
||||
}
|
||||
|
||||
int packetSizeInBytes = -1;
|
||||
|
||||
if (m_tempBuffer.size() >= 4)
|
||||
{
|
||||
packetSizeInBytes = b3DeserializeInt3(&m_tempBuffer[0]);
|
||||
}
|
||||
|
||||
if (m_tempBuffer.size() == packetSizeInBytes)
|
||||
{
|
||||
unsigned char* data = &m_tempBuffer[0];
|
||||
if (gVerboseNetworkMessagesClient3)
|
||||
{
|
||||
printf("A packet of length %d bytes received\n", m_tempBuffer.size());
|
||||
}
|
||||
|
||||
hasStatus = true;
|
||||
GraphicsSharedMemoryStatus* statPtr = (GraphicsSharedMemoryStatus*)&data[4];
|
||||
#if 0
|
||||
if (statPtr->m_type == CMD_STEP_FORWARD_SIMULATION_COMPLETED)
|
||||
{
|
||||
GraphicsSharedMemoryStatus dummy;
|
||||
dummy.m_type = CMD_STEP_FORWARD_SIMULATION_COMPLETED;
|
||||
m_lastStatus = dummy;
|
||||
m_stream.resize(0);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
m_lastStatus = *statPtr;
|
||||
int streamOffsetInBytes = 4 + sizeof(GraphicsSharedMemoryStatus);
|
||||
int numStreamBytes = packetSizeInBytes - streamOffsetInBytes;
|
||||
m_stream.resize(numStreamBytes);
|
||||
for (int i = 0; i < numStreamBytes; i++)
|
||||
{
|
||||
m_stream[i] = data[i + streamOffsetInBytes];
|
||||
}
|
||||
}
|
||||
m_tempBuffer.clear();
|
||||
m_waitingForServer = false;
|
||||
if (gVerboseNetworkMessagesClient3)
|
||||
printf("processServerStatus: %d\n", m_lastStatus.m_type);
|
||||
return &m_lastStatus;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool connect()
|
||||
{
|
||||
if (m_isConnected)
|
||||
return true;
|
||||
|
||||
m_tcpSocket.Initialize();
|
||||
|
||||
m_isConnected = m_tcpSocket.Open(m_hostName.c_str(), m_port);
|
||||
if (m_isConnected)
|
||||
{
|
||||
m_tcpSocket.SetSendTimeout(m_timeOutInSeconds, 0);
|
||||
m_tcpSocket.SetReceiveTimeout(m_timeOutInSeconds, 0);
|
||||
}
|
||||
int key = GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER;
|
||||
m_tcpSocket.Send((uint8*)&key, 4);
|
||||
|
||||
return m_isConnected;
|
||||
|
||||
}
|
||||
|
||||
void disconnect()
|
||||
{
|
||||
const char msg[16] = "disconnect";
|
||||
m_tcpSocket.Send((const uint8*)msg, 10);
|
||||
m_tcpSocket.Close();
|
||||
m_isConnected = false;
|
||||
}
|
||||
};
|
||||
|
||||
RemoteGUIHelperTCP::RemoteGUIHelperTCP(const char* hostName, int port)
|
||||
{
|
||||
m_data = new RemoteGUIHelperTCPInternalData(hostName, port);
|
||||
if (m_data->canSubmitCommand())
|
||||
{
|
||||
removeAllGraphicsInstances();
|
||||
}
|
||||
}
|
||||
|
||||
RemoteGUIHelperTCP::~RemoteGUIHelperTCP()
|
||||
{
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::setVisualizerFlag(int flag, int enable)
|
||||
{
|
||||
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
|
||||
if (cmd)
|
||||
{
|
||||
cmd->m_updateFlags = 0;
|
||||
cmd->m_visualizerFlagCommand.m_visualizerFlag = flag;
|
||||
cmd->m_visualizerFlagCommand.m_enable = enable;
|
||||
cmd->m_type = GFX_CMD_SET_VISUALIZER_FLAG;
|
||||
m_data->submitClientCommand(*cmd);
|
||||
}
|
||||
const GraphicsSharedMemoryStatus* status = 0;
|
||||
while ((status = m_data->processServerStatus()) == 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color)
|
||||
{
|
||||
printf("todo: createRigidBodyGraphicsObject\n");
|
||||
}
|
||||
|
||||
bool RemoteGUIHelperTCP::getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3], float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float camTarget[3]) const
|
||||
{
|
||||
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
|
||||
if (cmd)
|
||||
{
|
||||
|
||||
cmd->m_updateFlags = 0;
|
||||
cmd->m_type = GFX_CMD_GET_CAMERA_INFO;
|
||||
m_data->submitClientCommand(*cmd);
|
||||
}
|
||||
const GraphicsSharedMemoryStatus* status = 0;
|
||||
while ((status = m_data->processServerStatus()) == 0)
|
||||
{
|
||||
}
|
||||
if (status->m_type == GFX_CMD_GET_CAMERA_INFO_COMPLETED)
|
||||
{
|
||||
*width = status->m_getCameraInfoStatus.width;
|
||||
*height = status->m_getCameraInfoStatus.height;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
viewMatrix[i] = status->m_getCameraInfoStatus.viewMatrix[i];
|
||||
projectionMatrix[i] = status->m_getCameraInfoStatus.projectionMatrix[i];
|
||||
}
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
camUp[i] = status->m_getCameraInfoStatus.camUp[i];
|
||||
camForward[i] = status->m_getCameraInfoStatus.camForward[i];
|
||||
hor[i] = status->m_getCameraInfoStatus.hor[i];
|
||||
vert[i] = status->m_getCameraInfoStatus.vert[i];
|
||||
camTarget[i] = status->m_getCameraInfoStatus.camTarget[i];
|
||||
}
|
||||
*yaw = status->m_getCameraInfoStatus.yaw;
|
||||
*pitch = status->m_getCameraInfoStatus.pitch;
|
||||
*camDist = status->m_getCameraInfoStatus.camDist;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::createCollisionObjectGraphicsObject(btCollisionObject* body, const btVector3& color)
|
||||
{
|
||||
if (body->getUserIndex() < 0)
|
||||
{
|
||||
btCollisionShape* shape = body->getCollisionShape();
|
||||
btTransform startTransform = body->getWorldTransform();
|
||||
int graphicsShapeId = shape->getUserIndex();
|
||||
if (graphicsShapeId >= 0)
|
||||
{
|
||||
// btAssert(graphicsShapeId >= 0);
|
||||
//the graphics shape is already scaled
|
||||
float localScaling[4] = {1.f, 1.f, 1.f, 1.f};
|
||||
float colorRGBA[4] = {(float)color[0], (float)color[1], (float)color[2], (float)color[3]};
|
||||
float pos[4] = {(float)startTransform.getOrigin()[0], (float)startTransform.getOrigin()[1], (float)startTransform.getOrigin()[2], (float)startTransform.getOrigin()[3]};
|
||||
float orn[4] = {(float)startTransform.getRotation()[0], (float)startTransform.getRotation()[1], (float)startTransform.getRotation()[2], (float)startTransform.getRotation()[3]};
|
||||
int graphicsInstanceId = registerGraphicsInstance(graphicsShapeId, pos, orn, colorRGBA, localScaling);
|
||||
body->setUserIndex(graphicsInstanceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)
|
||||
{
|
||||
printf("todo; createCollisionShapeGraphicsObject\n");
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)
|
||||
{
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::syncPhysicsToGraphics2(const btDiscreteDynamicsWorld* rbWorld)
|
||||
{
|
||||
b3AlignedObjectArray<GUISyncPosition> updatedPositions;
|
||||
|
||||
int numCollisionObjects = rbWorld->getNumCollisionObjects();
|
||||
{
|
||||
B3_PROFILE("write all InstanceTransformToCPU2");
|
||||
for (int i = 0; i < numCollisionObjects; i++)
|
||||
{
|
||||
//B3_PROFILE("writeSingleInstanceTransformToCPU");
|
||||
btCollisionObject* colObj = rbWorld->getCollisionObjectArray()[i];
|
||||
btCollisionShape* collisionShape = colObj->getCollisionShape();
|
||||
|
||||
btVector3 pos = colObj->getWorldTransform().getOrigin();
|
||||
btQuaternion orn = colObj->getWorldTransform().getRotation();
|
||||
int index = colObj->getUserIndex();
|
||||
if (index >= 0)
|
||||
{
|
||||
GUISyncPosition p;
|
||||
p.m_graphicsInstanceId = index;
|
||||
for (int q = 0; q < 4; q++)
|
||||
{
|
||||
p.m_pos[q] = pos[q];
|
||||
p.m_orn[q] = orn[q];
|
||||
}
|
||||
updatedPositions.push_back(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updatedPositions.size())
|
||||
{
|
||||
syncPhysicsToGraphics2(&updatedPositions[0], updatedPositions.size());
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::syncPhysicsToGraphics2(const GUISyncPosition* positions, int numPositions)
|
||||
{
|
||||
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
|
||||
if (cmd)
|
||||
{
|
||||
uploadData((unsigned char*)positions, numPositions * sizeof(GUISyncPosition), 0);
|
||||
cmd->m_updateFlags = 0;
|
||||
cmd->m_syncTransformsCommand.m_numPositions = numPositions;
|
||||
cmd->m_type = GFX_CMD_SYNCHRONIZE_TRANSFORMS;
|
||||
m_data->submitClientCommand(*cmd);
|
||||
}
|
||||
const GraphicsSharedMemoryStatus* status = 0;
|
||||
while ((status = m_data->processServerStatus()) == 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::render(const btDiscreteDynamicsWorld* rbWorld)
|
||||
{
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld)
|
||||
{
|
||||
}
|
||||
|
||||
int RemoteGUIHelperTCP::uploadData(const unsigned char* data, int sizeInBytes, int slot)
|
||||
{
|
||||
int chunkSize = GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE;
|
||||
int remainingBytes = sizeInBytes;
|
||||
int offset = 0;
|
||||
|
||||
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
|
||||
cmd->m_updateFlags = 0;
|
||||
cmd->m_type = GFX_CMD_UPLOAD_DATA;
|
||||
cmd->m_uploadDataCommand.m_numBytes = sizeInBytes;
|
||||
cmd->m_uploadDataCommand.m_dataOffset = offset;
|
||||
cmd->m_uploadDataCommand.m_dataSlot = slot;
|
||||
m_data->submitClientCommand(*cmd);
|
||||
|
||||
const GraphicsSharedMemoryStatus* status = 0;
|
||||
while ((status = m_data->processServerStatus()) == 0)
|
||||
{
|
||||
}
|
||||
|
||||
if (gVerboseNetworkMessagesClient3)
|
||||
printf("sending %d bytes\n", sizeInBytes);
|
||||
m_data->m_tcpSocket.Send((const uint8*)data, sizeInBytes);
|
||||
|
||||
|
||||
status = 0;
|
||||
while ((status = m_data->processServerStatus()) == 0)
|
||||
{
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RemoteGUIHelperTCP::registerTexture(const unsigned char* texels, int width, int height)
|
||||
{
|
||||
int textureId = -1;
|
||||
|
||||
//first upload all data
|
||||
|
||||
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
|
||||
if (cmd)
|
||||
{
|
||||
int sizeInBytes = width * height * 3; //rgb
|
||||
uploadData(texels, sizeInBytes, 0);
|
||||
cmd->m_updateFlags = 0;
|
||||
cmd->m_type = GFX_CMD_REGISTER_TEXTURE;
|
||||
cmd->m_registerTextureCommand.m_width = width;
|
||||
cmd->m_registerTextureCommand.m_height = height;
|
||||
m_data->submitClientCommand(*cmd);
|
||||
const GraphicsSharedMemoryStatus* status = 0;
|
||||
while ((status = m_data->processServerStatus()) == 0)
|
||||
{
|
||||
}
|
||||
if (status->m_type == GFX_CMD_REGISTER_TEXTURE_COMPLETED)
|
||||
{
|
||||
textureId = status->m_registerTextureStatus.m_textureId;
|
||||
}
|
||||
}
|
||||
|
||||
return textureId;
|
||||
}
|
||||
|
||||
int RemoteGUIHelperTCP::registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId)
|
||||
{
|
||||
int shapeId = -1;
|
||||
|
||||
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
|
||||
if (cmd)
|
||||
{
|
||||
uploadData((unsigned char*)vertices, numvertices * 9 * sizeof(float), 0);
|
||||
uploadData((unsigned char*)indices, numIndices * sizeof(int), 1);
|
||||
cmd->m_type = GFX_CMD_REGISTER_GRAPHICS_SHAPE;
|
||||
cmd->m_updateFlags = 0;
|
||||
cmd->m_registerGraphicsShapeCommand.m_numVertices = numvertices;
|
||||
cmd->m_registerGraphicsShapeCommand.m_numIndices = numIndices;
|
||||
cmd->m_registerGraphicsShapeCommand.m_primitiveType = primitiveType;
|
||||
cmd->m_registerGraphicsShapeCommand.m_textureId = textureId;
|
||||
|
||||
m_data->submitClientCommand(*cmd);
|
||||
const GraphicsSharedMemoryStatus* status = 0;
|
||||
while ((status = m_data->processServerStatus()) == 0)
|
||||
{
|
||||
}
|
||||
if (status->m_type == GFX_CMD_REGISTER_GRAPHICS_SHAPE_COMPLETED)
|
||||
{
|
||||
shapeId = status->m_registerGraphicsShapeStatus.m_shapeId;
|
||||
}
|
||||
}
|
||||
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
int RemoteGUIHelperTCP::registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling)
|
||||
{
|
||||
int graphicsInstanceId = -1;
|
||||
|
||||
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
|
||||
if (cmd)
|
||||
{
|
||||
cmd->m_type = GFX_CMD_REGISTER_GRAPHICS_INSTANCE;
|
||||
cmd->m_updateFlags = 0;
|
||||
cmd->m_registerGraphicsInstanceCommand.m_shapeIndex = shapeIndex;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
cmd->m_registerGraphicsInstanceCommand.m_position[i] = position[i];
|
||||
cmd->m_registerGraphicsInstanceCommand.m_quaternion[i] = quaternion[i];
|
||||
cmd->m_registerGraphicsInstanceCommand.m_color[i] = color[i];
|
||||
cmd->m_registerGraphicsInstanceCommand.m_scaling[i] = scaling[i];
|
||||
}
|
||||
m_data->submitClientCommand(*cmd);
|
||||
const GraphicsSharedMemoryStatus* status = 0;
|
||||
while ((status = m_data->processServerStatus()) == 0)
|
||||
{
|
||||
}
|
||||
if (status->m_type == GFX_CMD_REGISTER_GRAPHICS_INSTANCE_COMPLETED)
|
||||
{
|
||||
graphicsInstanceId = status->m_registerGraphicsInstanceStatus.m_graphicsInstanceId;
|
||||
}
|
||||
}
|
||||
return graphicsInstanceId;
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::removeAllGraphicsInstances()
|
||||
{
|
||||
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
|
||||
if (cmd)
|
||||
{
|
||||
cmd->m_updateFlags = 0;
|
||||
cmd->m_type = GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES;
|
||||
m_data->submitClientCommand(*cmd);
|
||||
const GraphicsSharedMemoryStatus* status = 0;
|
||||
while ((status = m_data->processServerStatus()) == 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::removeGraphicsInstance(int graphicsUid)
|
||||
{
|
||||
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
|
||||
if (cmd)
|
||||
{
|
||||
cmd->m_updateFlags = 0;
|
||||
cmd->m_type = GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE;
|
||||
cmd->m_removeGraphicsInstanceCommand.m_graphicsUid = graphicsUid;
|
||||
m_data->submitClientCommand(*cmd);
|
||||
const GraphicsSharedMemoryStatus* status = 0;
|
||||
while ((status = m_data->processServerStatus()) == 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
void RemoteGUIHelperTCP::changeRGBAColor(int instanceUid, const double rgbaColor[4])
|
||||
{
|
||||
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
|
||||
if (cmd)
|
||||
{
|
||||
cmd->m_updateFlags = 0;
|
||||
cmd->m_type = GFX_CMD_CHANGE_RGBA_COLOR;
|
||||
cmd->m_changeRGBAColorCommand.m_graphicsUid = instanceUid;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
cmd->m_changeRGBAColorCommand.m_rgbaColor[i] = rgbaColor[i];
|
||||
}
|
||||
m_data->submitClientCommand(*cmd);
|
||||
const GraphicsSharedMemoryStatus* status = 0;
|
||||
while ((status = m_data->processServerStatus()) == 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Common2dCanvasInterface* RemoteGUIHelperTCP::get2dCanvasInterface()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CommonParameterInterface* RemoteGUIHelperTCP::getParameterInterface()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CommonRenderInterface* RemoteGUIHelperTCP::getRenderInterface()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CommonGraphicsApp* RemoteGUIHelperTCP::getAppInterface()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::setUpAxis(int axis)
|
||||
{
|
||||
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
|
||||
if (cmd)
|
||||
{
|
||||
cmd->m_updateFlags = 0;
|
||||
cmd->m_upAxisYCommand.m_enableUpAxisY = axis == 1;
|
||||
cmd->m_type = GFX_CMD_0;
|
||||
m_data->submitClientCommand(*cmd);
|
||||
const GraphicsSharedMemoryStatus* status = 0;
|
||||
while ((status = m_data->processServerStatus()) == 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
void RemoteGUIHelperTCP::resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ)
|
||||
{
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
|
||||
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
|
||||
float* depthBuffer, int depthBufferSizeInPixels,
|
||||
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
|
||||
int startPixelIndex, int width, int height, int* numPixelsCopied)
|
||||
|
||||
{
|
||||
if (numPixelsCopied)
|
||||
*numPixelsCopied = 0;
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16])
|
||||
{
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::setProjectiveTexture(bool useProjectiveTexture)
|
||||
{
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
|
||||
{
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::drawText3D(const char* txt, float posX, float posZY, float posZ, float size)
|
||||
{
|
||||
}
|
||||
|
||||
void RemoteGUIHelperTCP::drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag)
|
||||
{
|
||||
}
|
||||
|
||||
int RemoteGUIHelperTCP::addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
void RemoteGUIHelperTCP::removeUserDebugItem(int debugItemUniqueId)
|
||||
{
|
||||
}
|
||||
void RemoteGUIHelperTCP::removeAllUserDebugItems()
|
||||
{
|
||||
}
|
||||
@@ -152,10 +152,16 @@ class InProcessPhysicsClientExistingExampleBrowser : public PhysicsClientSharedM
|
||||
SharedMemoryInterface* m_sharedMem;
|
||||
b3Clock m_clock;
|
||||
unsigned long long int m_prevTime;
|
||||
struct GUIHelperInterface* m_guiHelper;
|
||||
|
||||
public:
|
||||
InProcessPhysicsClientExistingExampleBrowser(struct GUIHelperInterface* guiHelper, bool useInProcessMemory, bool skipGraphicsUpdate)
|
||||
InProcessPhysicsClientExistingExampleBrowser(struct GUIHelperInterface* guiHelper, bool useInProcessMemory, bool skipGraphicsUpdate, bool ownsGuiHelper)
|
||||
{
|
||||
if (ownsGuiHelper)
|
||||
{
|
||||
m_guiHelper = guiHelper;
|
||||
}
|
||||
|
||||
m_sharedMem = 0;
|
||||
CommonExampleOptions options(guiHelper);
|
||||
|
||||
@@ -179,6 +185,7 @@ public:
|
||||
//s_instancingRenderer->removeAllInstances();
|
||||
delete m_physicsServerExample;
|
||||
delete m_sharedMem;
|
||||
delete m_guiHelper;
|
||||
}
|
||||
|
||||
// return non-null if there is a status, nullptr otherwise
|
||||
@@ -257,7 +264,7 @@ B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingEx
|
||||
bool useInprocessMemory = true;
|
||||
bool skipGraphicsUpdate = false;
|
||||
|
||||
InProcessPhysicsClientExistingExampleBrowser* cl = new InProcessPhysicsClientExistingExampleBrowser(guiHelper, useInprocessMemory, skipGraphicsUpdate);
|
||||
InProcessPhysicsClientExistingExampleBrowser* cl = new InProcessPhysicsClientExistingExampleBrowser(guiHelper, useInprocessMemory, skipGraphicsUpdate, false);
|
||||
|
||||
cl->connect();
|
||||
return (b3PhysicsClientHandle)cl;
|
||||
@@ -277,7 +284,7 @@ B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingEx
|
||||
}
|
||||
bool useInprocessMemory = false;
|
||||
bool skipGraphicsUpdate = true;
|
||||
InProcessPhysicsClientExistingExampleBrowser* cl = new InProcessPhysicsClientExistingExampleBrowser(guiHelper, useInprocessMemory, skipGraphicsUpdate);
|
||||
InProcessPhysicsClientExistingExampleBrowser* cl = new InProcessPhysicsClientExistingExampleBrowser(guiHelper, useInprocessMemory, skipGraphicsUpdate, false);
|
||||
|
||||
cl->setSharedMemoryKey(sharedMemoryKey + 1);
|
||||
cl->connect();
|
||||
@@ -290,13 +297,15 @@ B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingEx
|
||||
{
|
||||
gSharedMemoryKey = sharedMemoryKey;
|
||||
GUIHelperInterface* guiHelper = (GUIHelperInterface*)guiHelperPtr;
|
||||
bool ownsGuiHelper = false;
|
||||
if (!guiHelper)
|
||||
{
|
||||
guiHelper = new RemoteGUIHelper();
|
||||
ownsGuiHelper = true;
|
||||
}
|
||||
bool useInprocessMemory = false;
|
||||
bool skipGraphicsUpdate = false;
|
||||
InProcessPhysicsClientExistingExampleBrowser* cl = new InProcessPhysicsClientExistingExampleBrowser(guiHelper, useInprocessMemory, skipGraphicsUpdate);
|
||||
InProcessPhysicsClientExistingExampleBrowser* cl = new InProcessPhysicsClientExistingExampleBrowser(guiHelper, useInprocessMemory, skipGraphicsUpdate, ownsGuiHelper);
|
||||
|
||||
cl->setSharedMemoryKey(sharedMemoryKey + 1);
|
||||
cl->connect();
|
||||
@@ -305,6 +314,25 @@ B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingEx
|
||||
return (b3PhysicsClientHandle)cl;
|
||||
}
|
||||
|
||||
#include "RemoteGuiHelperTCP.h"
|
||||
|
||||
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnectTCP(const char* hostName, int port)
|
||||
{
|
||||
bool ownsGuiHelper = true;
|
||||
GUIHelperInterface* guiHelper = new RemoteGUIHelperTCP(hostName, port);
|
||||
|
||||
bool useInprocessMemory = true;
|
||||
bool skipGraphicsUpdate = false;
|
||||
InProcessPhysicsClientExistingExampleBrowser* cl = new InProcessPhysicsClientExistingExampleBrowser(guiHelper, useInprocessMemory, skipGraphicsUpdate, ownsGuiHelper);
|
||||
|
||||
//cl->setSharedMemoryKey(sharedMemoryKey + 1);
|
||||
cl->connect();
|
||||
//backward compatiblity
|
||||
gSharedMemoryKey = SHARED_MEMORY_KEY;
|
||||
return (b3PhysicsClientHandle)cl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//backward compatiblity
|
||||
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect2(void* guiHelperPtr)
|
||||
|
||||
@@ -26,6 +26,7 @@ extern "C"
|
||||
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect3(void* guiHelperPtr, int sharedMemoryKey);
|
||||
//create a shared memory physics server, with a RemoteGUIHelper (connect to remote graphics server) and allow to set shared memory key
|
||||
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect4(void* guiHelperPtr, int sharedMemoryKey);
|
||||
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnectTCP(const char* hostName, int port);
|
||||
|
||||
///ignore the following APIs, they are for internal use for example browser
|
||||
void b3InProcessRenderSceneInternal(b3PhysicsClientHandle clientHandle);
|
||||
|
||||
@@ -903,6 +903,7 @@ enum eCONNECT_METHOD
|
||||
eCONNECT_PHYSX=13,
|
||||
eCONNECT_SHARED_MEMORY_GUI=14,
|
||||
eCONNECT_GRAPHICS_SERVER = 15,
|
||||
eCONNECT_GRAPHICS_SERVER_TCP = 16,
|
||||
};
|
||||
|
||||
enum eURDF_Flags
|
||||
|
||||
18
examples/pybullet/examples/graphicsClient.py
Normal file
18
examples/pybullet/examples/graphicsClient.py
Normal file
@@ -0,0 +1,18 @@
|
||||
import pybullet as p
|
||||
import time
|
||||
|
||||
p.connect(p.GRAPHICS_SERVER_TCP)
|
||||
import pybullet_data as pd
|
||||
p.setAdditionalSearchPath(pd.getDataPath())
|
||||
|
||||
p.loadURDF("plane.urdf")
|
||||
p.loadURDF("r2d2.urdf", [0,0,3])
|
||||
p.setGravity(0,0,-10)
|
||||
gravId = p.addUserDebugParameter("gravity",0,10,0)
|
||||
while p.isConnected():
|
||||
p.stepSimulation()
|
||||
|
||||
grav = p.readUserDebugParameter(gravId)
|
||||
#print("grav=",grav)
|
||||
time.sleep(1./240.)
|
||||
|
||||
7
examples/pybullet/examples/graphicsServer.py
Normal file
7
examples/pybullet/examples/graphicsServer.py
Normal file
@@ -0,0 +1,7 @@
|
||||
import pybullet as p
|
||||
import time
|
||||
|
||||
p.connect(p.GRAPHICS_SERVER)
|
||||
while p.isConnected():
|
||||
#p.stepSimulation()
|
||||
time.sleep(1./240.)
|
||||
18
examples/pybullet/gym/pybullet_utils/graphicsClient.py
Normal file
18
examples/pybullet/gym/pybullet_utils/graphicsClient.py
Normal file
@@ -0,0 +1,18 @@
|
||||
import pybullet as p
|
||||
import time
|
||||
|
||||
p.connect(p.GRAPHICS_SERVER_TCP)
|
||||
import pybullet_data as pd
|
||||
p.setAdditionalSearchPath(pd.getDataPath())
|
||||
|
||||
p.loadURDF("plane.urdf")
|
||||
p.loadURDF("r2d2.urdf", [0,0,3])
|
||||
p.setGravity(0,0,-10)
|
||||
gravId = p.addUserDebugParameter("gravity",0,10,0)
|
||||
while p.isConnected():
|
||||
p.stepSimulation()
|
||||
|
||||
grav = p.readUserDebugParameter(gravId)
|
||||
#print("grav=",grav)
|
||||
time.sleep(1./240.)
|
||||
|
||||
7
examples/pybullet/gym/pybullet_utils/graphicsServer.py
Normal file
7
examples/pybullet/gym/pybullet_utils/graphicsServer.py
Normal file
@@ -0,0 +1,7 @@
|
||||
import pybullet as p
|
||||
import time
|
||||
|
||||
p.connect(p.GRAPHICS_SERVER)
|
||||
print("started graphics server")
|
||||
while p.isConnected():
|
||||
time.sleep(1./240.)
|
||||
@@ -124,14 +124,15 @@ if not _OPTIONS["no-enet"] then
|
||||
"../../examples/SharedMemory/PhysicsServerExample.cpp",
|
||||
"../../examples/SharedMemory/PhysicsServerExampleBullet2.cpp",
|
||||
"../SharedMemory/GraphicsClientExample.cpp",
|
||||
"../SharedMemory/GraphicsClientExample.h",
|
||||
"../SharedMemory/GraphicsServerExample.cpp",
|
||||
"../SharedMemory/GraphicsServerExample.h",
|
||||
"../SharedMemory/GraphicsSharedMemoryBlock.h",
|
||||
"../SharedMemory/GraphicsSharedMemoryCommands.h",
|
||||
"../SharedMemory/GraphicsSharedMemoryPublic.h",
|
||||
"../SharedMemory/RemoteGUIHelper.cpp",
|
||||
"../SharedMemory/RemoteGUIHelper.h",
|
||||
"../SharedMemory/GraphicsClientExample.h",
|
||||
"../SharedMemory/GraphicsServerExample.cpp",
|
||||
"../SharedMemory/GraphicsServerExample.h",
|
||||
"../SharedMemory/GraphicsSharedMemoryBlock.h",
|
||||
"../SharedMemory/GraphicsSharedMemoryCommands.h",
|
||||
"../SharedMemory/GraphicsSharedMemoryPublic.h",
|
||||
"../SharedMemory/RemoteGUIHelper.cpp",
|
||||
"../SharedMemory/RemoteGUIHelperTCP.cpp",
|
||||
"../SharedMemory/RemoteGUIHelper.h",
|
||||
"../../examples/SharedMemory/SharedMemoryInProcessPhysicsC_API.cpp",
|
||||
"../../examples/SharedMemory/PhysicsServerSharedMemory.cpp",
|
||||
"../../examples/SharedMemory/PhysicsServerSharedMemory.h",
|
||||
|
||||
@@ -483,6 +483,17 @@ static PyObject* pybullet_connectPhysicsServer(PyObject* self, PyObject* args, P
|
||||
break;
|
||||
}
|
||||
|
||||
case eCONNECT_GRAPHICS_SERVER_TCP:
|
||||
{
|
||||
#ifdef BT_ENABLE_CLSOCKET
|
||||
sm = b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnectTCP(hostName, tcpPort);
|
||||
#else
|
||||
PyErr_SetString(SpamError, "TCP is not enabled in this pybullet build");
|
||||
return NULL;
|
||||
#endif//BT_ENABLE_CLSOCKET
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case eCONNECT_DIRECT:
|
||||
{
|
||||
@@ -12583,6 +12594,7 @@ initpybullet(void)
|
||||
PyModule_AddIntConstant(m, "SHARED_MEMORY_GUI", eCONNECT_SHARED_MEMORY_GUI); // user read
|
||||
PyModule_AddIntConstant(m, "GRAPHICS_CLIENT", eCONNECT_SHARED_MEMORY_GUI); // user read
|
||||
PyModule_AddIntConstant(m, "GRAPHICS_SERVER", eCONNECT_GRAPHICS_SERVER); // user read
|
||||
PyModule_AddIntConstant(m, "GRAPHICS_SERVER_TCP", eCONNECT_GRAPHICS_SERVER_TCP); // user read
|
||||
|
||||
|
||||
|
||||
|
||||
4
setup.py
4
setup.py
@@ -127,7 +127,9 @@ sources = ["examples/pybullet/pybullet.c"]\
|
||||
+["examples/SharedMemory/PhysicsClient.cpp"]\
|
||||
+["examples/SharedMemory/PhysicsServer.cpp"]\
|
||||
+["examples/SharedMemory/GraphicsClientExample.cpp"]\
|
||||
+["examples/SharedMemory/GraphicsServerExample.cpp"]\
|
||||
+["examples/SharedMemory/RemoteGUIHelper.cpp"]\
|
||||
+["examples/SharedMemory/RemoteGuiHelperTCP.cpp"]\
|
||||
+["examples/SharedMemory/PhysicsServerExample.cpp"]\
|
||||
+["examples/SharedMemory/PhysicsServerExampleBullet2.cpp"]\
|
||||
+["examples/SharedMemory/SharedMemoryInProcessPhysicsC_API.cpp"]\
|
||||
@@ -499,7 +501,7 @@ if 'BT_USE_EGL' in EGL_CXX_FLAGS:
|
||||
|
||||
setup(
|
||||
name='pybullet',
|
||||
version='2.6.9',
|
||||
version='2.7.0',
|
||||
description=
|
||||
'Official Python Interface for the Bullet Physics SDK specialized for Robotics Simulation and Reinforcement Learning',
|
||||
long_description=
|
||||
|
||||
Reference in New Issue
Block a user