From 97083923220845ef04e73cfa6ef34d0142f07576 Mon Sep 17 00:00:00 2001 From: erwincoumans Date: Fri, 4 Nov 2016 13:15:10 -0700 Subject: [PATCH 01/10] work-in-progress add UDP network connection for physics client <-> server. also set spinning friction in rolling friction demo (otherwise objects may keep on spinning forever) --- build3/premake4.lua | 19 +- build_cmake_pybullet_win32.bat | 4 + examples/ExampleBrowser/CMakeLists.txt | 1 + .../ExampleBrowser/OpenGLExampleBrowser.cpp | 6 +- examples/ExampleBrowser/main.cpp | 4 + examples/ExampleBrowser/premake4.lua | 8 + .../MultiThreading/MultiThreadingExample.cpp | 3 + .../OpenGLWindow/GLInstancingRenderer.cpp | 8 +- examples/RoboticsLearning/b3RobotSimAPI.cpp | 5 +- .../RollingFrictionDemo.cpp | 10 +- examples/SharedMemory/PhysicsClientC_API.cpp | 132 ++-- examples/SharedMemory/PhysicsClientC_API.h | 12 +- .../PhysicsClientSharedMemory.cpp | 14 +- .../SharedMemory/PhysicsClientSharedMemory.h | 2 +- .../PhysicsClientSharedMemory2.cpp | 27 + .../SharedMemory/PhysicsClientSharedMemory2.h | 18 + .../PhysicsClientSharedMemory2_C_API.cpp | 19 + .../PhysicsClientSharedMemory2_C_API.h | 18 + .../PhysicsClientSharedMemory_C_API.cpp | 11 + .../PhysicsClientSharedMemory_C_API.h | 16 + examples/SharedMemory/PhysicsClientUDP.cpp | 577 ++++++++++++++++++ examples/SharedMemory/PhysicsClientUDP.h | 37 ++ .../SharedMemory/PhysicsClientUDP_C_API.cpp | 21 + .../SharedMemory/PhysicsClientUDP_C_API.h | 19 + .../PhysicsCommandProcessorInterface.h | 27 + examples/SharedMemory/PhysicsDirect.cpp | 264 +++++--- examples/SharedMemory/PhysicsDirect.h | 7 +- examples/SharedMemory/PhysicsDirectC_API.cpp | 10 +- .../PhysicsServerCommandProcessor.cpp | 21 +- .../PhysicsServerCommandProcessor.h | 38 +- .../SharedMemoryCommandProcessor.cpp | 216 +++++++ .../SharedMemoryCommandProcessor.h | 37 ++ examples/SharedMemory/SharedMemoryCommands.h | 5 +- examples/SharedMemory/premake4.lua | 13 +- examples/SharedMemory/udp/main.cpp | 187 ++++++ examples/SharedMemory/udp/premake4.lua | 46 ++ .../StandaloneMain/hellovr_opengl_main.cpp | 4 +- examples/ThirdPartyLibs/enet/premake4.lua | 3 +- examples/pybullet/CMakeLists.txt | 51 +- examples/pybullet/premake4.lua | 29 +- examples/pybullet/pybullet.c | 23 +- test/SharedMemory/CMakeLists.txt | 5 +- test/SharedMemory/premake4.lua | 2 + test/SharedMemory/test.c | 12 +- test/enet/chat/client/main.cpp | 165 +++++ test/enet/{ => chat}/client/premake4.lua | 4 +- test/enet/chat/server/main.cpp | 103 ++++ test/enet/{ => chat}/server/premake4.lua | 4 +- .../{ => nat_punchthrough}/client/main.cpp | 0 .../enet/nat_punchthrough/client/premake4.lua | 25 + .../{ => nat_punchthrough}/server/main.cpp | 0 .../enet/nat_punchthrough/server/premake4.lua | 26 + 52 files changed, 2104 insertions(+), 214 deletions(-) create mode 100644 build_cmake_pybullet_win32.bat create mode 100644 examples/SharedMemory/PhysicsClientSharedMemory2.cpp create mode 100644 examples/SharedMemory/PhysicsClientSharedMemory2.h create mode 100644 examples/SharedMemory/PhysicsClientSharedMemory2_C_API.cpp create mode 100644 examples/SharedMemory/PhysicsClientSharedMemory2_C_API.h create mode 100644 examples/SharedMemory/PhysicsClientSharedMemory_C_API.cpp create mode 100644 examples/SharedMemory/PhysicsClientSharedMemory_C_API.h create mode 100644 examples/SharedMemory/PhysicsClientUDP.cpp create mode 100644 examples/SharedMemory/PhysicsClientUDP.h create mode 100644 examples/SharedMemory/PhysicsClientUDP_C_API.cpp create mode 100644 examples/SharedMemory/PhysicsClientUDP_C_API.h create mode 100644 examples/SharedMemory/PhysicsCommandProcessorInterface.h create mode 100644 examples/SharedMemory/SharedMemoryCommandProcessor.cpp create mode 100644 examples/SharedMemory/SharedMemoryCommandProcessor.h create mode 100644 examples/SharedMemory/udp/main.cpp create mode 100644 examples/SharedMemory/udp/premake4.lua create mode 100644 test/enet/chat/client/main.cpp rename test/enet/{ => chat}/client/premake4.lua (70%) create mode 100644 test/enet/chat/server/main.cpp rename test/enet/{ => chat}/server/premake4.lua (70%) rename test/enet/{ => nat_punchthrough}/client/main.cpp (100%) create mode 100644 test/enet/nat_punchthrough/client/premake4.lua rename test/enet/{ => nat_punchthrough}/server/main.cpp (100%) create mode 100644 test/enet/nat_punchthrough/server/premake4.lua diff --git a/build3/premake4.lua b/build3/premake4.lua index f0de611fd..06e85d591 100644 --- a/build3/premake4.lua +++ b/build3/premake4.lua @@ -73,8 +73,8 @@ newoption { - trigger = "enet", - description = "Enable enet NAT punchthrough test" + trigger = "no-enet", + description = "Disable enet and enet tests" } newoption @@ -261,14 +261,19 @@ end if not _OPTIONS["no-test"] then include "../test/SharedMemory" - if _OPTIONS["enet"] then - include "../examples/ThirdPartyLibs/enet" - include "../test/enet/client" - include "../test/enet/server" - end + end end + if not _OPTIONS["no-enet"] then + include "../examples/ThirdPartyLibs/enet" + include "../test/enet/nat_punchthrough/client" + include "../test/enet/nat_punchthrough/server" + include "../test/enet/chat/client" + include "../test/enet/chat/server" + defines {"BT_ENABLE_ENET"} + end + if _OPTIONS["no-bullet3"] then print "--no-bullet3 implies --no-demos" _OPTIONS["no-demos"] = "1" diff --git a/build_cmake_pybullet_win32.bat b/build_cmake_pybullet_win32.bat new file mode 100644 index 000000000..33317f2c1 --- /dev/null +++ b/build_cmake_pybullet_win32.bat @@ -0,0 +1,4 @@ +mkdir cm +cd cm +cmake -DBUILD_PYBULLET=ON -DCMAKE_BUILD_TYPE=Release -DPYTHON_INCLUDE_DIR=c:\python-3.5.2\include -DPYTHON_LIBRARY=c:\python-3.5.2\libs\python35_d.lib .. +start . diff --git a/examples/ExampleBrowser/CMakeLists.txt b/examples/ExampleBrowser/CMakeLists.txt index 024d928d3..f85beb6d5 100644 --- a/examples/ExampleBrowser/CMakeLists.txt +++ b/examples/ExampleBrowser/CMakeLists.txt @@ -146,6 +146,7 @@ SET(BulletExampleBrowser_SRCS ../SharedMemory/PhysicsServer.cpp ../SharedMemory/PhysicsClientSharedMemory.cpp + ../SharedMemory/PhysicsClientSharedMemory_C_API.cpp ../SharedMemory/PhysicsClient.cpp ../SharedMemory/PhysicsClientC_API.cpp ../SharedMemory/PhysicsServerExample.cpp diff --git a/examples/ExampleBrowser/OpenGLExampleBrowser.cpp b/examples/ExampleBrowser/OpenGLExampleBrowser.cpp index 70e717159..962f04437 100644 --- a/examples/ExampleBrowser/OpenGLExampleBrowser.cpp +++ b/examples/ExampleBrowser/OpenGLExampleBrowser.cpp @@ -134,9 +134,9 @@ int gSharedMemoryKey=-1; int gPreferredOpenCLDeviceIndex=-1; int gPreferredOpenCLPlatformIndex=-1; -int gGpuArraySizeX=15; -int gGpuArraySizeY=15; -int gGpuArraySizeZ=15; +int gGpuArraySizeX=45; +int gGpuArraySizeY=55; +int gGpuArraySizeZ=45; //#include //unsigned int fp_control_state = _controlfp(_EM_INEXACT, _MCW_EM); diff --git a/examples/ExampleBrowser/main.cpp b/examples/ExampleBrowser/main.cpp index d0f132c1a..05985d41e 100644 --- a/examples/ExampleBrowser/main.cpp +++ b/examples/ExampleBrowser/main.cpp @@ -15,6 +15,8 @@ #include "../Importers/ImportURDFDemo/ImportURDFSetup.h" #include "../Importers/ImportSDFDemo/ImportSDFSetup.h" #include "../Importers/ImportSTLDemo/ImportSTLSetup.h" +#include "../Importers/ImportBullet/SerializeSetup.h" + #include "LinearMath/btAlignedAllocator.h" @@ -34,6 +36,8 @@ int main(int argc, char* argv[]) exampleBrowser->registerFileImporter(".sdf", ImportSDFCreateFunc); exampleBrowser->registerFileImporter(".obj", ImportObjCreateFunc); exampleBrowser->registerFileImporter(".stl", ImportSTLCreateFunc); + exampleBrowser->registerFileImporter(".bullet", SerializeBulletCreateFunc); + clock.reset(); if (init) diff --git a/examples/ExampleBrowser/premake4.lua b/examples/ExampleBrowser/premake4.lua index c28ae0e5a..ff47ffc73 100644 --- a/examples/ExampleBrowser/premake4.lua +++ b/examples/ExampleBrowser/premake4.lua @@ -63,6 +63,14 @@ project "App_BulletExampleBrowser" "../SharedMemory/PhysicsServer.cpp", "../SharedMemory/PhysicsServerSharedMemory.cpp", "../SharedMemory/PhysicsClientSharedMemory.cpp", + "../SharedMemory/PhysicsClientSharedMemory_C_API.cpp", + "../SharedMemory/PhysicsClientSharedMemory_C_API.h", + "../SharedMemory/PhysicsClientSharedMemory2.cpp", + "../SharedMemory/PhysicsClientSharedMemory2.h", + "../SharedMemory/PhysicsClientSharedMemory2_C_API.cpp", + "../SharedMemory/PhysicsClientSharedMemory2_C_API.h", + "../SharedMemory/SharedMemoryCommandProcessor.cpp", + "../SharedMemory/SharedMemoryCommandProcessor.h", "../SharedMemory/SharedMemoryInProcessPhysicsC_API.cpp", "../SharedMemory/PhysicsClient.cpp", "../SharedMemory/PosixSharedMemory.cpp", diff --git a/examples/MultiThreading/MultiThreadingExample.cpp b/examples/MultiThreading/MultiThreadingExample.cpp index 1969912b9..33eb0e751 100644 --- a/examples/MultiThreading/MultiThreadingExample.cpp +++ b/examples/MultiThreading/MultiThreadingExample.cpp @@ -11,6 +11,7 @@ #include "stb_image/stb_image.h" #include "Bullet3Common/b3Quaternion.h" #include "Bullet3Common/b3Matrix3x3.h" +#include "../Utils/b3Clock.h" #include "../CommonInterfaces/CommonParameterInterface.h" #include "LinearMath/btAlignedObjectArray.h" @@ -134,6 +135,8 @@ void SampleThreadFunc(void* userPtr,void* lsMemory) job->executeJob(localStorage->threadId); } + b3Clock::usleep(250); + args->m_cs->lock(); int exitMagicNumber = args->m_cs->getSharedParam(1); requestExit = (exitMagicNumber==MAGIC_RESET_NUMBER); diff --git a/examples/OpenGLWindow/GLInstancingRenderer.cpp b/examples/OpenGLWindow/GLInstancingRenderer.cpp index 718a9fc60..c6f620bab 100644 --- a/examples/OpenGLWindow/GLInstancingRenderer.cpp +++ b/examples/OpenGLWindow/GLInstancingRenderer.cpp @@ -17,9 +17,9 @@ subject to the following restrictions: ///todo: make this configurable in the gui bool useShadowMap = true;// true;//false;//true; -int shadowMapWidth= 2048; -int shadowMapHeight= 2048; -float shadowMapWorldSize=5; +int shadowMapWidth= 4096; +int shadowMapHeight= 4096; +float shadowMapWorldSize=10; #define MAX_POINTS_IN_BATCH 1024 #define MAX_LINES_IN_BATCH 1024 @@ -1539,7 +1539,7 @@ void GLInstancingRenderer::renderSceneInternal(int renderMode) b3Assert(glGetError() ==GL_NO_ERROR); } else { - //glDisable(GL_CULL_FACE); + glEnable(GL_CULL_FACE); glCullFace(GL_BACK); } diff --git a/examples/RoboticsLearning/b3RobotSimAPI.cpp b/examples/RoboticsLearning/b3RobotSimAPI.cpp index 40527e481..81c308b92 100644 --- a/examples/RoboticsLearning/b3RobotSimAPI.cpp +++ b/examples/RoboticsLearning/b3RobotSimAPI.cpp @@ -5,6 +5,8 @@ #include "Bullet3Common/b3AlignedObjectArray.h" #include "../CommonInterfaces/CommonRenderInterface.h" //#include "../CommonInterfaces/CommonExampleInterface.h" +#include "../SharedMemory/PhysicsServerCommandProcessor.h" + #include "../CommonInterfaces/CommonGUIHelperInterface.h" #include "../SharedMemory/PhysicsServerSharedMemory.h" #include "../SharedMemory/PhysicsServerSharedMemory.h" @@ -893,7 +895,8 @@ bool b3RobotSimAPI::connect(GUIHelperInterface* guiHelper) } else { - m_data->m_clientServerDirect = new PhysicsDirect(); + PhysicsServerCommandProcessor* sdk = new PhysicsServerCommandProcessor; + m_data->m_clientServerDirect = new PhysicsDirect(sdk); bool connected = m_data->m_clientServerDirect->connect(guiHelper); m_data->m_physicsClient = (b3PhysicsClientHandle)m_data->m_clientServerDirect; diff --git a/examples/RollingFrictionDemo/RollingFrictionDemo.cpp b/examples/RollingFrictionDemo/RollingFrictionDemo.cpp index 7e53be9b0..65a2404d3 100644 --- a/examples/RollingFrictionDemo/RollingFrictionDemo.cpp +++ b/examples/RollingFrictionDemo/RollingFrictionDemo.cpp @@ -123,8 +123,8 @@ void RollingFrictionDemo::initPhysics() btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); - body->setFriction(1); - body->setRollingFriction(1); + body->setFriction(.5); + //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } @@ -153,8 +153,7 @@ void RollingFrictionDemo::initPhysics() btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); - body->setFriction(1); - body->setRollingFriction(1); + body->setFriction(.1); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } @@ -217,7 +216,8 @@ void RollingFrictionDemo::initPhysics() btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->setFriction(1.f); - body->setRollingFriction(.3); + body->setRollingFriction(.1); + body->setSpinningFriction(0.1); body->setAnisotropicFriction(colShape->getAnisotropicRollingFrictionDirection(),btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); diff --git a/examples/SharedMemory/PhysicsClientC_API.cpp b/examples/SharedMemory/PhysicsClientC_API.cpp index 434a99b7f..325c12fed 100644 --- a/examples/SharedMemory/PhysicsClientC_API.cpp +++ b/examples/SharedMemory/PhysicsClientC_API.cpp @@ -58,21 +58,25 @@ b3SharedMemoryCommandHandle b3LoadUrdfCommandInit(b3PhysicsClientHandle physClie b3Assert(cl); b3Assert(cl->canSubmitCommand()); - - struct SharedMemoryCommand* command = cl->getAvailableSharedMemoryCommand(); - b3Assert(command); - command->m_type = CMD_LOAD_URDF; - int len = strlen(urdfFileName); - if (lencanSubmitCommand()) { - strcpy(command->m_urdfArguments.m_urdfFileName,urdfFileName); - } else - { - command->m_urdfArguments.m_urdfFileName[0] = 0; + struct SharedMemoryCommand* command = cl->getAvailableSharedMemoryCommand(); + b3Assert(command); + command->m_type = CMD_LOAD_URDF; + int len = strlen(urdfFileName); + if (len < MAX_URDF_FILENAME_LENGTH) + { + strcpy(command->m_urdfArguments.m_urdfFileName, urdfFileName); + } + else + { + command->m_urdfArguments.m_urdfFileName[0] = 0; + } + command->m_updateFlags = URDF_ARGS_FILE_NAME; + + return (b3SharedMemoryCommandHandle)command; } - command->m_updateFlags = URDF_ARGS_FILE_NAME; - - return (b3SharedMemoryCommandHandle) command; + return 0; } b3SharedMemoryCommandHandle b3LoadBunnyCommandInit(b3PhysicsClientHandle physClient) @@ -116,35 +120,52 @@ int b3LoadUrdfCommandSetUseFixedBase(b3SharedMemoryCommandHandle commandHandle, struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle; b3Assert(command); b3Assert(command->m_type == CMD_LOAD_URDF); - command->m_updateFlags |=URDF_ARGS_USE_FIXED_BASE; - command->m_urdfArguments.m_useFixedBase = useFixedBase; - - return 0; + if (command && (command->m_type == CMD_LOAD_URDF)) + { + command->m_updateFlags |= URDF_ARGS_USE_FIXED_BASE; + command->m_urdfArguments.m_useFixedBase = useFixedBase; + return 0; + } + return -1; } int b3LoadUrdfCommandSetStartPosition(b3SharedMemoryCommandHandle commandHandle, double startPosX,double startPosY,double startPosZ) { struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle; b3Assert(command); - b3Assert(command->m_type == CMD_LOAD_URDF); - command->m_urdfArguments.m_initialPosition[0] = startPosX; - command->m_urdfArguments.m_initialPosition[1] = startPosY; - command->m_urdfArguments.m_initialPosition[2] = startPosZ; - command->m_updateFlags|=URDF_ARGS_INITIAL_POSITION; - return 0; + if (command) + { + b3Assert(command->m_type == CMD_LOAD_URDF); + if (command->m_type == CMD_LOAD_URDF) + { + command->m_urdfArguments.m_initialPosition[0] = startPosX; + command->m_urdfArguments.m_initialPosition[1] = startPosY; + command->m_urdfArguments.m_initialPosition[2] = startPosZ; + command->m_updateFlags |= URDF_ARGS_INITIAL_POSITION; + } + return 0; + } + return -1; } int b3LoadUrdfCommandSetStartOrientation(b3SharedMemoryCommandHandle commandHandle, double startOrnX,double startOrnY,double startOrnZ, double startOrnW) { struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle; b3Assert(command); - b3Assert(command->m_type == CMD_LOAD_URDF); - command->m_urdfArguments.m_initialOrientation[0] = startOrnX; - command->m_urdfArguments.m_initialOrientation[1] = startOrnY; - command->m_urdfArguments.m_initialOrientation[2] = startOrnZ; - command->m_urdfArguments.m_initialOrientation[3] = startOrnW; - command->m_updateFlags|=URDF_ARGS_INITIAL_ORIENTATION; - return 0; + if (command) + { + b3Assert(command->m_type == CMD_LOAD_URDF); + if (command->m_type == CMD_LOAD_URDF) + { + command->m_urdfArguments.m_initialOrientation[0] = startOrnX; + command->m_urdfArguments.m_initialOrientation[1] = startOrnY; + command->m_urdfArguments.m_initialOrientation[2] = startOrnZ; + command->m_urdfArguments.m_initialOrientation[3] = startOrnW; + command->m_updateFlags |= URDF_ARGS_INITIAL_ORIENTATION; + } + return 0; + } + return -1; } b3SharedMemoryCommandHandle b3InitPhysicsParamCommand(b3PhysicsClientHandle physClient) @@ -174,7 +195,7 @@ int b3PhysicsParamSetRealTimeSimulation(b3SharedMemoryCommandHandle commandH { struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle; b3Assert(command->m_type == CMD_SEND_PHYSICS_SIMULATION_PARAMETERS); - command->m_physSimParamArgs.m_allowRealTimeSimulation = enableRealTimeSimulation; + command->m_physSimParamArgs.m_allowRealTimeSimulation = (enableRealTimeSimulation!=0); command->m_updateFlags |= SIM_PARAM_UPDATE_REAL_TIME_SIMULATION; return 0; } @@ -621,20 +642,11 @@ int b3CreateSensorEnableIMUForLink(b3SharedMemoryCommandHandle commandHandle, in } -b3PhysicsClientHandle b3ConnectSharedMemory(int key) -{ - - PhysicsClientSharedMemory* cl = new PhysicsClientSharedMemory(); - ///client should never create shared memory, only the server does - cl->setSharedMemoryKey(key); - cl->connect(); - return (b3PhysicsClientHandle ) cl; -} - void b3DisconnectSharedMemory(b3PhysicsClientHandle physClient) { PhysicsClient* cl = (PhysicsClient* ) physClient; + cl->disconnectSharedMemory(); delete cl; } @@ -772,22 +784,34 @@ int b3SubmitClientCommand(b3PhysicsClientHandle physClient, const b3SharedMemory { struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle; PhysicsClient* cl = (PhysicsClient* ) physClient; - return (int)cl->submitClientCommand(*command); + b3Assert(command); + b3Assert(cl); + if (command && cl) + { + return (int)cl->submitClientCommand(*command); + } + return -1; + } b3SharedMemoryStatusHandle b3SubmitClientCommandAndWaitStatus(b3PhysicsClientHandle physClient, const b3SharedMemoryCommandHandle commandHandle) { - int timeout = 1024*1024*1024; - b3SharedMemoryStatusHandle statusHandle=0; - - b3SubmitClientCommand(physClient,commandHandle); - - while ((statusHandle==0) && (timeout-- > 0)) - { - statusHandle =b3ProcessServerStatus(physClient); - } - return (b3SharedMemoryStatusHandle) statusHandle; - + int timeout = 1024 * 1024 * 1024; + b3SharedMemoryStatusHandle statusHandle = 0; + b3Assert(commandHandle); + b3Assert(physClient); + if (physClient && commandHandle) + { + b3SubmitClientCommand(physClient, commandHandle); + + while ((statusHandle == 0) && (timeout-- > 0)) + { + statusHandle = b3ProcessServerStatus(physClient); + } + return (b3SharedMemoryStatusHandle)statusHandle; + } + + return 0; } @@ -1546,4 +1570,4 @@ int b3GetStatusInverseKinematicsJointPositions(b3SharedMemoryStatusHandle status } return true; -} \ No newline at end of file +} diff --git a/examples/SharedMemory/PhysicsClientC_API.h b/examples/SharedMemory/PhysicsClientC_API.h index 68e579f6f..8a1381bf9 100644 --- a/examples/SharedMemory/PhysicsClientC_API.h +++ b/examples/SharedMemory/PhysicsClientC_API.h @@ -11,14 +11,18 @@ B3_DECLARE_HANDLE(b3SharedMemoryCommandHandle); B3_DECLARE_HANDLE(b3SharedMemoryStatusHandle); +///There are several connection methods, see following header files: +#include "PhysicsClientSharedMemory_C_API.h" +#include "PhysicsClientSharedMemory2_C_API.h" +#include "PhysicsDirectC_API.h" +#include "PhysicsClientUDP_C_API.h" +#include "SharedMemoryInProcessPhysicsC_API.h" + #ifdef __cplusplus extern "C" { #endif -///b3ConnectSharedMemory will connect to a physics server over shared memory, so -///make sure to start the server first. -///and a way to spawn an OpenGL 3D GUI physics server and connect (b3CreateInProcessPhysicsServerAndConnect) -b3PhysicsClientHandle b3ConnectSharedMemory(int key); + ///b3DisconnectSharedMemory will disconnect the client from the server and cleanup memory. void b3DisconnectSharedMemory(b3PhysicsClientHandle physClient); diff --git a/examples/SharedMemory/PhysicsClientSharedMemory.cpp b/examples/SharedMemory/PhysicsClientSharedMemory.cpp index 9dda6aca1..65f4d8aba 100644 --- a/examples/SharedMemory/PhysicsClientSharedMemory.cpp +++ b/examples/SharedMemory/PhysicsClientSharedMemory.cpp @@ -124,8 +124,11 @@ bool PhysicsClientSharedMemory::getJointInfo(int bodyUniqueId, int jointIndex, b if (bodyJointsPtr && *bodyJointsPtr) { BodyJointInfoCache* bodyJoints = *bodyJointsPtr; - info = bodyJoints->m_jointInfo[jointIndex]; - return true; + if ((jointIndex >= 0) && (jointIndex < bodyJoints->m_jointInfo.size())) + { + info = bodyJoints->m_jointInfo[jointIndex]; + return true; + } } return false; } @@ -210,7 +213,7 @@ void PhysicsClientSharedMemory::processBodyJointInfo(int bodyUniqueId, const Sha { bParse::btBulletFile bf( &this->m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0], - serverCmd.m_dataStreamArguments.m_streamChunkLength); + serverCmd.m_numDataStreamBytes); bf.setFileDNAisMemoryDNA(); bf.parse(false); @@ -291,16 +294,17 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() { break; } + case CMD_URDF_LOADING_COMPLETED: { if (m_data->m_verboseOutput) { b3Printf("Server loading the URDF OK\n"); } - if (serverCmd.m_dataStreamArguments.m_streamChunkLength > 0) { + if (serverCmd.m_numDataStreamBytes > 0) { bParse::btBulletFile bf( this->m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor, - serverCmd.m_dataStreamArguments.m_streamChunkLength); + serverCmd.m_numDataStreamBytes); bf.setFileDNAisMemoryDNA(); bf.parse(false); int bodyUniqueId = serverCmd.m_dataStreamArguments.m_bodyUniqueId; diff --git a/examples/SharedMemory/PhysicsClientSharedMemory.h b/examples/SharedMemory/PhysicsClientSharedMemory.h index 2dc659646..1ebe5bccd 100644 --- a/examples/SharedMemory/PhysicsClientSharedMemory.h +++ b/examples/SharedMemory/PhysicsClientSharedMemory.h @@ -12,7 +12,7 @@ class PhysicsClientSharedMemory : public PhysicsClient { protected: virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem); void processBodyJointInfo(int bodyUniqueId, const struct SharedMemoryStatus& serverCmd); - + public: PhysicsClientSharedMemory(); diff --git a/examples/SharedMemory/PhysicsClientSharedMemory2.cpp b/examples/SharedMemory/PhysicsClientSharedMemory2.cpp new file mode 100644 index 000000000..7eea2298d --- /dev/null +++ b/examples/SharedMemory/PhysicsClientSharedMemory2.cpp @@ -0,0 +1,27 @@ + +#include "PhysicsClientSharedMemory2.h" +#include "PosixSharedMemory.h" +#include "Win32SharedMemory.h" +#include "Bullet3Common/b3Logging.h" +#include "Bullet3Common/b3Scalar.h" + +#include "SharedMemoryCommandProcessor.h" + + +PhysicsClientSharedMemory2::PhysicsClientSharedMemory2(SharedMemoryCommandProcessor* proc) + :PhysicsDirect(proc) +{ + m_proc = proc; +} +PhysicsClientSharedMemory2::~PhysicsClientSharedMemory2() +{ +} + +void PhysicsClientSharedMemory2::setSharedMemoryInterface(class SharedMemoryInterface* sharedMem) +{ + if (m_proc) + { + m_proc->setSharedMemoryInterface(sharedMem); + } +} + diff --git a/examples/SharedMemory/PhysicsClientSharedMemory2.h b/examples/SharedMemory/PhysicsClientSharedMemory2.h new file mode 100644 index 000000000..e3b109370 --- /dev/null +++ b/examples/SharedMemory/PhysicsClientSharedMemory2.h @@ -0,0 +1,18 @@ +#ifndef PHYSICS_CLIENT_SHARED_MEMORY2_H +#define PHYSICS_CLIENT_SHARED_MEMORY2_H + +#include "PhysicsDirect.h" + +class PhysicsClientSharedMemory2 : public PhysicsDirect +{ + class SharedMemoryCommandProcessor* m_proc; + +public: + PhysicsClientSharedMemory2(SharedMemoryCommandProcessor* proc); + virtual ~PhysicsClientSharedMemory2(); + + void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem); + +}; + +#endif //PHYSICS_CLIENT_SHARED_MEMORY2_H \ No newline at end of file diff --git a/examples/SharedMemory/PhysicsClientSharedMemory2_C_API.cpp b/examples/SharedMemory/PhysicsClientSharedMemory2_C_API.cpp new file mode 100644 index 000000000..7323205d0 --- /dev/null +++ b/examples/SharedMemory/PhysicsClientSharedMemory2_C_API.cpp @@ -0,0 +1,19 @@ +#include "PhysicsClientSharedMemory2_C_API.h" + +#include "PhysicsDirect.h" +#include "SharedMemoryCommandProcessor.h" + +b3PhysicsClientHandle b3ConnectSharedMemory2(int key) +{ + + SharedMemoryCommandProcessor* cmdProc = new SharedMemoryCommandProcessor(); + cmdProc->setSharedMemoryKey(key); + PhysicsDirect* cl = new PhysicsDirect(cmdProc); + + cl->setSharedMemoryKey(key); + + cl->connect(); + + return (b3PhysicsClientHandle)cl; +} + diff --git a/examples/SharedMemory/PhysicsClientSharedMemory2_C_API.h b/examples/SharedMemory/PhysicsClientSharedMemory2_C_API.h new file mode 100644 index 000000000..95d4bf690 --- /dev/null +++ b/examples/SharedMemory/PhysicsClientSharedMemory2_C_API.h @@ -0,0 +1,18 @@ +#ifndef PHYSICS_CLIENT_SHARED_MEMORY2_H +#define PHYSICS_CLIENT_SHARED_MEMORY2_H + +#include "PhysicsClientC_API.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +b3PhysicsClientHandle b3ConnectSharedMemory2(int key); + + +#ifdef __cplusplus +} +#endif + +#endif //PHYSICS_CLIENT_SHARED_MEMORY2_H diff --git a/examples/SharedMemory/PhysicsClientSharedMemory_C_API.cpp b/examples/SharedMemory/PhysicsClientSharedMemory_C_API.cpp new file mode 100644 index 000000000..36c794f80 --- /dev/null +++ b/examples/SharedMemory/PhysicsClientSharedMemory_C_API.cpp @@ -0,0 +1,11 @@ +#include "PhysicsClientSharedMemory_C_API.h" + +#include "PhysicsClientSharedMemory.h" + +b3PhysicsClientHandle b3ConnectSharedMemory(int key) +{ + PhysicsClientSharedMemory* cl = new PhysicsClientSharedMemory(); + cl->setSharedMemoryKey(key); + cl->connect(); + return (b3PhysicsClientHandle)cl; +} diff --git a/examples/SharedMemory/PhysicsClientSharedMemory_C_API.h b/examples/SharedMemory/PhysicsClientSharedMemory_C_API.h new file mode 100644 index 000000000..2a4e4e665 --- /dev/null +++ b/examples/SharedMemory/PhysicsClientSharedMemory_C_API.h @@ -0,0 +1,16 @@ +#ifndef PHYSICS_CLIENT_SHARED_MEMORY_H +#define PHYSICS_CLIENT_SHARED_MEMORY_H + +#include "PhysicsClientC_API.h" + +#ifdef __cplusplus +extern "C" { +#endif + + b3PhysicsClientHandle b3ConnectSharedMemory(int key); + +#ifdef __cplusplus +} +#endif + +#endif //PHYSICS_CLIENT_SHARED_MEMORY_H diff --git a/examples/SharedMemory/PhysicsClientUDP.cpp b/examples/SharedMemory/PhysicsClientUDP.cpp new file mode 100644 index 000000000..a112e0900 --- /dev/null +++ b/examples/SharedMemory/PhysicsClientUDP.cpp @@ -0,0 +1,577 @@ +#include "PhysicsClientUDP.h" +#include +#include +#include +#include "../Utils/b3Clock.h" +#include "PhysicsClient.h" +//#include "LinearMath/btVector3.h" +#include "SharedMemoryCommands.h" +#include +#include "Bullet3Common/b3Logging.h" +#include "../MultiThreading/b3ThreadSupportInterface.h" +void UDPThreadFunc(void* userPtr, void* lsMemory); +void* UDPlsMemoryFunc(); + +#ifndef _WIN32 +#include "../MultiThreading/b3PosixThreadSupport.h" + +b3ThreadSupportInterface* createUDPThreadSupport(int numThreads) +{ + b3PosixThreadSupport::ThreadConstructionInfo constructionInfo("UDPThread", + UDPThreadFunc, + UDPlsMemoryFunc, + numThreads); + b3ThreadSupportInterface* threadSupport = new b3PosixThreadSupport(constructionInfo); + + return threadSupport; + +} + + +#elif defined( _WIN32) +#include "../MultiThreading/b3Win32ThreadSupport.h" + +b3ThreadSupportInterface* createUDPThreadSupport(int numThreads) +{ + b3Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("UDPThread", UDPThreadFunc, UDPlsMemoryFunc, numThreads); + b3Win32ThreadSupport* threadSupport = new b3Win32ThreadSupport(threadConstructionInfo); + return threadSupport; + +} +#endif + + + +struct UDPThreadLocalStorage +{ + int threadId; +}; + + + +unsigned int b3DeserializeInt(const unsigned char* input) +{ + unsigned int tmp = (input[3] << 24) + (input[2] << 16) + (input[1] << 8) + input[0]; + return tmp; +} + +struct UdpNetworkedInternalData +{ + ENetHost* m_client; + ENetAddress m_address; + ENetPeer* m_peer; + ENetEvent m_event; + bool m_isConnected; + + b3ThreadSupportInterface* m_threadSupport; + + b3CriticalSection* m_cs; + + UdpNetworkedInternalData* m_udpInternalData; + + + SharedMemoryCommand m_clientCmd; + bool m_hasCommand; + + bool m_hasStatus; + SharedMemoryStatus m_lastStatus; + b3AlignedObjectArray m_stream; + + std::string m_hostName; + int m_port; + + UdpNetworkedInternalData() + :m_client(0), + m_peer(0), + m_isConnected(false), + m_threadSupport(0), + m_hasCommand(false), + m_hasStatus(false) + { + + } + + bool connectUDP() + { + if (m_isConnected) + return true; + + + + if (enet_initialize() != 0) + { + fprintf(stderr, "Error initialising enet"); + exit(EXIT_FAILURE); + + } + + m_client = enet_host_create(NULL, /* create a client host */ + 1, /* number of clients */ + 2, /* number of channels */ + 57600 / 8, /* incoming bandwith */ + 14400 / 8); /* outgoing bandwith */ + + if (m_client == NULL) { + fprintf(stderr, "Could not create client host"); + return false; + } + + enet_address_set_host(&m_address, m_hostName.c_str()); + m_address.port = m_port; + + m_peer = enet_host_connect(m_client, + &m_address, /* address to connect to */ + 2, /* number of channels */ + 0); /* user data supplied to + the receiving host */ + + if (m_peer == NULL) { + fprintf(stderr, "No available peers for initiating an ENet " + "connection.\n"); + return false; + + } + + + /* Try to connect to server within 5 seconds */ + if (enet_host_service(m_client, &m_event, 5000) > 0 && + m_event.type == ENET_EVENT_TYPE_CONNECT) + { + puts("Connection to server succeeded."); + } + else + { + /* Either the 5 seconds are up or a disconnect event was */ + /* received. Reset the peer in the event the 5 seconds */ + /* had run out without any significant event. */ + enet_peer_reset(m_peer); + + fprintf(stderr, "Connection to server failed."); + return false; + } + + + int serviceResult = enet_host_service(m_client, &m_event, 0); + + if (serviceResult > 0) + { + switch (m_event.type) + { + case ENET_EVENT_TYPE_CONNECT: + printf("A new client connected from %x:%u.\n", + m_event.peer->address.host, + m_event.peer->address.port); + m_event.peer->data = (void*)"New User"; + break; + + case ENET_EVENT_TYPE_RECEIVE: + printf("A packet of length %u containing '%s' was " + "received from %s on channel %u.\n", + m_event.packet->dataLength, + m_event.packet->data, + m_event.peer->data, + m_event.channelID); + + /* Clean up the packet now that we're done using it. + > */ + enet_packet_destroy(m_event.packet); + + break; + + case ENET_EVENT_TYPE_DISCONNECT: + printf("%s disconected.\n", m_event.peer->data); + + break; + } + } + else if (serviceResult > 0) + { + puts("Error with servicing the client"); + return false; + } + + m_isConnected = true; + return m_isConnected; + } + + bool checkData() + { + bool hasStatus = false; + + int serviceResult = enet_host_service(m_client, &m_event, 100); + + if (serviceResult > 0) + { + switch (m_event.type) + { + case ENET_EVENT_TYPE_CONNECT: + printf("A new client connected from %x:%u.\n", + m_event.peer->address.host, + m_event.peer->address.port); + + m_event.peer->data = (void*)"New User"; + break; + + case ENET_EVENT_TYPE_RECEIVE: + { + printf("A packet of length %u containing '%s' was " + "received from %s on channel %u.\n", + m_event.packet->dataLength, + m_event.packet->data, + m_event.peer->data, + m_event.channelID); + + + int packetSizeInBytes = b3DeserializeInt(m_event.packet->data); + + if (packetSizeInBytes == m_event.packet->dataLength) + { + + SharedMemoryStatus* statPtr = (SharedMemoryStatus*)&m_event.packet->data[4]; + m_lastStatus = *statPtr; + int streamOffsetInBytes = 4 + sizeof(SharedMemoryStatus); + int numStreamBytes = packetSizeInBytes - streamOffsetInBytes; + m_stream.resize(numStreamBytes); + for (int i = 0; i < numStreamBytes; i++) + { + m_stream[i] = m_event.packet->data[i + streamOffsetInBytes]; + } + } + else + { + printf("unknown status message received\n"); + } + enet_packet_destroy(m_event.packet); + hasStatus = true; + break; + } + case ENET_EVENT_TYPE_DISCONNECT: + { + printf("%s disconected.\n", m_event.peer->data); + + break; + } + } + } + else if (serviceResult > 0) + { + puts("Error with servicing the client"); + } + + return hasStatus; + } + +}; + +enum UDPThreadEnums +{ + eUDPRequestTerminate = 13, + eUDPIsUnInitialized, + eUDPIsInitialized, + eUDPInitializationFailed, + eUDPHasTerminated +}; + + + +enum UDPCommandEnums +{ + eUDPIdle = 13, + eUDP_ConnectRequest, + eUDP_Connected, + eUDP_ConnectionFailed, + eUDP_DisconnectRequest, + eUDP_Disconnected, + +}; + +void UDPThreadFunc(void* userPtr, void* lsMemory) +{ + printf("UDPThreadFunc thread started\n"); + UDPThreadLocalStorage* localStorage = (UDPThreadLocalStorage*)lsMemory; + + UdpNetworkedInternalData* args = (UdpNetworkedInternalData*)userPtr; + int workLeft = true; + b3Clock clock; + clock.reset(); + bool init = true; + if (init) + { + + args->m_cs->lock(); + args->m_cs->setSharedParam(0, eUDPIsInitialized); + args->m_cs->unlock(); + + + double deltaTimeInSeconds = 0; + + do + { + deltaTimeInSeconds += double(clock.getTimeMicroseconds()) / 1000000.; + + if (deltaTimeInSeconds<(1. / 5000.)) + { +// b3Clock::usleep(250); + } + else + { + + clock.reset(); + deltaTimeInSeconds = 0.f; + switch (args->m_cs->getSharedParam(1)) + { + case eUDP_ConnectRequest: + { + bool connected = args->connectUDP(); + if (connected) + { + args->m_cs->setSharedParam(1, eUDP_Connected); + } + else + { + args->m_cs->setSharedParam(1, eUDP_ConnectionFailed); + } + break; + } + default: + { + } + }; + + if (args->m_isConnected) + { + + args->m_cs->lock(); + bool hasCommand = args->m_hasCommand; + args->m_cs->unlock(); + + + if (hasCommand) + { + + int sz = sizeof(SharedMemoryCommand); + ENetPacket *packet = enet_packet_create(&args->m_clientCmd, sz, ENET_PACKET_FLAG_RELIABLE); + int res = enet_peer_send(args->m_peer, 0, packet); + args->m_cs->lock(); + args->m_hasCommand = false; + args->m_cs->unlock(); + } + + + bool hasNewStatus = args->checkData(); + if (hasNewStatus) + { + if (args->m_hasStatus) + { + //overflow: last status hasn't been processed yet + b3Assert(0); + printf("Error: received new status but previous status not processed yet"); + } + else + { + args->m_cs->lock(); + args->m_hasStatus = hasNewStatus; + args->m_cs->unlock(); + } + } + } + + } + + } while (args->m_cs->getSharedParam(0) != eUDPRequestTerminate); + } + else + { + args->m_cs->lock(); + args->m_cs->setSharedParam(0, eUDPInitializationFailed); + args->m_cs->unlock(); + } + + + printf("finished\n"); + +} + + + +void* UDPlsMemoryFunc() +{ + //don't create local store memory, just return 0 + return new UDPThreadLocalStorage; +} + + + + + + + +UdpNetworkedPhysicsProcessor::UdpNetworkedPhysicsProcessor(const char* hostName, int port) +{ + m_data = new UdpNetworkedInternalData; + if (hostName) + { + m_data->m_hostName = hostName; + } + m_data->m_port = port; + +} + +UdpNetworkedPhysicsProcessor::~UdpNetworkedPhysicsProcessor() +{ + disconnect(); + delete m_data; +} + +bool UdpNetworkedPhysicsProcessor::processCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes) +{ + int sz = sizeof(SharedMemoryCommand); + int timeout = 1024 * 1024 * 1024; + + m_data->m_cs->lock(); + m_data->m_clientCmd = clientCmd; + m_data->m_hasCommand = true; + m_data->m_cs->unlock(); + + while (m_data->m_hasCommand && (timeout-- > 0)) + { +// b3Clock::usleep(100); + } + +#if 0 + + timeout = 1024 * 1024 * 1024; + + bool hasStatus = false; + + const SharedMemoryStatus* stat = 0; + while ((!hasStatus) && (timeout-- > 0)) + { + hasStatus = receiveStatus(serverStatusOut, bufferServerToClient, bufferSizeInBytes); + b3Clock::usleep(100); + } + return hasStatus; + +#endif + + return false; +} + +bool UdpNetworkedPhysicsProcessor::receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes) +{ + bool hasStatus = false; + if (m_data->m_hasStatus) + { + hasStatus = true; + serverStatusOut = m_data->m_lastStatus; + int numStreamBytes = m_data->m_stream.size(); + + if (numStreamBytes < bufferSizeInBytes) + { + for (int i = 0; i < numStreamBytes; i++) + { + bufferServerToClient[i] = m_data->m_stream[i]; + } + } + else + { + printf("Error: steam buffer overflow\n"); + } + + m_data->m_cs->lock(); + m_data->m_hasStatus = false; + m_data->m_cs->unlock(); + } + + + return hasStatus; + +} + + +void UdpNetworkedPhysicsProcessor::renderScene() +{ +} + +void UdpNetworkedPhysicsProcessor::physicsDebugDraw(int debugDrawFlags) +{ +} + +void UdpNetworkedPhysicsProcessor::setGuiHelper(struct GUIHelperInterface* guiHelper) +{ +} + +bool UdpNetworkedPhysicsProcessor::isConnected() const +{ + return m_data->m_isConnected; +} + + +bool UdpNetworkedPhysicsProcessor::connect() +{ + if (m_data->m_threadSupport==0) + { + m_data->m_threadSupport = createUDPThreadSupport(1); + + m_data->m_cs = m_data->m_threadSupport->createCriticalSection(); + m_data->m_cs->setSharedParam(0, eUDPIsUnInitialized); + m_data->m_threadSupport->runTask(B3_THREAD_SCHEDULE_TASK, (void*) m_data, 0); + + while (m_data->m_cs->getSharedParam(0) == eUDPIsUnInitialized) + { + b3Clock::usleep(1000); + } + + m_data->m_cs->lock(); + m_data->m_cs->setSharedParam(1, eUDP_ConnectRequest); + m_data->m_cs->unlock(); + + while (m_data->m_cs->getSharedParam(1) == eUDP_ConnectRequest) + { + b3Clock::usleep(1000); + } + + } + + + return true; +} + +void UdpNetworkedPhysicsProcessor::disconnect() +{ + if (m_data->m_threadSupport) + { + m_data->m_cs->lock(); + m_data->m_cs->setSharedParam(0, eUDPRequestTerminate); + m_data->m_cs->unlock(); + + int numActiveThreads = 1; + + while (numActiveThreads) + { + int arg0, arg1; + if (m_data->m_threadSupport->isTaskCompleted(&arg0, &arg1, 0)) + { + numActiveThreads--; + printf("numActiveThreads = %d\n", numActiveThreads); + } + else + { + b3Clock::usleep(1000); + } + }; + + printf("stopping threads\n"); + + delete m_data->m_threadSupport; + m_data->m_threadSupport = 0; + } + + + +} + + + + + diff --git a/examples/SharedMemory/PhysicsClientUDP.h b/examples/SharedMemory/PhysicsClientUDP.h new file mode 100644 index 000000000..27b94fd48 --- /dev/null +++ b/examples/SharedMemory/PhysicsClientUDP.h @@ -0,0 +1,37 @@ +#ifndef PHYSICS_CLIENT_UDP_H +#define PHYSICS_CLIENT_UDP_H + +#include "PhysicsDirect.h" +#include "PhysicsServerCommandProcessor.h" + +class UdpNetworkedPhysicsProcessor : public PhysicsCommandProcessorInterface +{ + + struct UdpNetworkedInternalData* m_data; + +public: + UdpNetworkedPhysicsProcessor(const char* hostName, int port); + + virtual ~UdpNetworkedPhysicsProcessor(); + + virtual bool connect(); + + virtual void disconnect(); + + virtual bool isConnected() const; + + virtual bool processCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); + + virtual bool receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); + + virtual void renderScene(); + + virtual void physicsDebugDraw(int debugDrawFlags); + + virtual void setGuiHelper(struct GUIHelperInterface* guiHelper); + +}; + + +#endif //PHYSICS_CLIENT_UDP_H + diff --git a/examples/SharedMemory/PhysicsClientUDP_C_API.cpp b/examples/SharedMemory/PhysicsClientUDP_C_API.cpp new file mode 100644 index 000000000..f48fdedb8 --- /dev/null +++ b/examples/SharedMemory/PhysicsClientUDP_C_API.cpp @@ -0,0 +1,21 @@ + +#include "PhysicsClientUDP_C_API.h" +#include "PhysicsClientUDP.h" +#include "PhysicsDirect.h" +#include + +//think more about naming. The b3ConnectPhysicsLoopback +b3PhysicsClientHandle b3ConnectPhysicsUDP(const char* hostName, int port) +{ + + UdpNetworkedPhysicsProcessor* udp = new UdpNetworkedPhysicsProcessor(hostName, port); + + PhysicsDirect* direct = new PhysicsDirect(udp); + + bool connected = direct->connect(); + printf("direct!\n"); + return (b3PhysicsClientHandle)direct; +} + + + diff --git a/examples/SharedMemory/PhysicsClientUDP_C_API.h b/examples/SharedMemory/PhysicsClientUDP_C_API.h new file mode 100644 index 000000000..fdb97bcab --- /dev/null +++ b/examples/SharedMemory/PhysicsClientUDP_C_API.h @@ -0,0 +1,19 @@ +#ifndef PHYSICS_CLIENT_UDP_C_API_H +#define PHYSICS_CLIENT_UDP_C_API_H + +#include "PhysicsClientC_API.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + ///send physics commands using UDP networking + b3PhysicsClientHandle b3ConnectPhysicsUDP(const char* hostName, int port); + + +#ifdef __cplusplus +} +#endif + +#endif //PHYSICS_CLIENT_UDP_C_API_H diff --git a/examples/SharedMemory/PhysicsCommandProcessorInterface.h b/examples/SharedMemory/PhysicsCommandProcessorInterface.h new file mode 100644 index 000000000..39b5f36d5 --- /dev/null +++ b/examples/SharedMemory/PhysicsCommandProcessorInterface.h @@ -0,0 +1,27 @@ +#ifndef PHYSICS_COMMAND_PROCESSOR_INTERFACE_H +#define PHYSICS_COMMAND_PROCESSOR_INTERFACE_H + +class PhysicsCommandProcessorInterface +{ + +public: + virtual ~PhysicsCommandProcessorInterface() {} + + virtual bool connect()=0; + + virtual void disconnect() = 0; + + virtual bool isConnected() const = 0; + + virtual bool processCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes) = 0; + + virtual bool receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes) = 0; + + virtual void renderScene() = 0; + virtual void physicsDebugDraw(int debugDrawFlags) = 0; + virtual void setGuiHelper(struct GUIHelperInterface* guiHelper) = 0; + + +}; + +#endif //PHYSICS_COMMAND_PROCESSOR_INTERFACE_H diff --git a/examples/SharedMemory/PhysicsDirect.cpp b/examples/SharedMemory/PhysicsDirect.cpp index 65c1beb13..8b21eeaa3 100644 --- a/examples/SharedMemory/PhysicsDirect.cpp +++ b/examples/SharedMemory/PhysicsDirect.cpp @@ -3,7 +3,9 @@ #include "PhysicsClientSharedMemory.h" #include "../CommonInterfaces/CommonGUIHelperInterface.h" #include "SharedMemoryCommands.h" -#include "PhysicsServerCommandProcessor.h" +#include "PhysicsCommandProcessorInterface.h" + + #include "LinearMath/btHashMap.h" #include "LinearMath/btAlignedObjectArray.h" #include "../../Extras/Serialize/BulletFileLoader/btBulletFile.h" @@ -44,26 +46,34 @@ struct PhysicsDirectInternalData btAlignedObjectArray m_cachedVisualShapes; - PhysicsServerCommandProcessor* m_commandProcessor; + PhysicsCommandProcessorInterface* m_commandProcessor; + bool m_ownsCommandProcessor; PhysicsDirectInternalData() :m_hasStatus(false), - m_verboseOutput(false) + m_verboseOutput(false), + m_ownsCommandProcessor(false) { } }; -PhysicsDirect::PhysicsDirect() +PhysicsDirect::PhysicsDirect(PhysicsCommandProcessorInterface* physSdk) { m_data = new PhysicsDirectInternalData; - m_data->m_commandProcessor = new PhysicsServerCommandProcessor; - - + m_data->m_commandProcessor = physSdk; + m_data->m_ownsCommandProcessor = false; } PhysicsDirect::~PhysicsDirect() { - delete m_data->m_commandProcessor; + if (m_data->m_commandProcessor->isConnected()) + { + m_data->m_commandProcessor->disconnect(); + } + if (m_data->m_ownsCommandProcessor) + { + delete m_data->m_commandProcessor; + } delete m_data; } @@ -71,23 +81,26 @@ PhysicsDirect::~PhysicsDirect() // return true if connection succesfull, can also check 'isConnected' bool PhysicsDirect::connect() { + bool connected = m_data->m_commandProcessor->connect(); m_data->m_commandProcessor->setGuiHelper(&m_data->m_noGfx); - - return true; + return connected; } // return true if connection succesfull, can also check 'isConnected' bool PhysicsDirect::connect(struct GUIHelperInterface* guiHelper) { + bool connected = m_data->m_commandProcessor->connect(); + m_data->m_commandProcessor->setGuiHelper(guiHelper); - return true; + return connected; } void PhysicsDirect::renderScene() { m_data->m_commandProcessor->renderScene(); } + void PhysicsDirect::debugDraw(int debugDrawMode) { m_data->m_commandProcessor->physicsDebugDraw(debugDrawMode); @@ -96,21 +109,31 @@ void PhysicsDirect::debugDraw(int debugDrawMode) ////todo: rename to 'disconnect' void PhysicsDirect::disconnectSharedMemory() { + m_data->m_commandProcessor->disconnect(); m_data->m_commandProcessor->setGuiHelper(0); } bool PhysicsDirect::isConnected() const { - return true; + return m_data->m_commandProcessor->isConnected(); } // return non-null if there is a status, nullptr otherwise const SharedMemoryStatus* PhysicsDirect::processServerStatus() { + + if (!m_data->m_hasStatus) + { + m_data->m_hasStatus = m_data->m_commandProcessor->receiveStatus(m_data->m_serverStatus, &m_data->m_bulletStreamDataServerToClient[0], SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); + } + SharedMemoryStatus* stat = 0; if (m_data->m_hasStatus) { stat = &m_data->m_serverStatus; + + postProcessStatus(m_data->m_serverStatus); + m_data->m_hasStatus = false; } return stat; @@ -136,7 +159,19 @@ bool PhysicsDirect::processDebugLines(const struct SharedMemoryCommand& orgComma { bool hasStatus = m_data->m_commandProcessor->processCommand(command,m_data->m_serverStatus,&m_data->m_bulletStreamDataServerToClient[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); + + int timeout = 1024 * 1024 * 1024; + while ((!hasStatus) && (timeout-- > 0)) + { + const SharedMemoryStatus* stat = processServerStatus(); + if (stat) + { + hasStatus = true; + } + } + m_data->m_hasStatus = hasStatus; + if (hasStatus) { btAssert(m_data->m_serverStatus.m_type == CMD_DEBUG_LINES_COMPLETED); @@ -184,6 +219,8 @@ bool PhysicsDirect::processDebugLines(const struct SharedMemoryCommand& orgComma if (serverCmd.m_sendDebugLinesArgs.m_numRemainingDebugLines > 0) { + m_data->m_hasStatus = false; + command.m_type = CMD_REQUEST_DEBUG_LINES; command.m_requestDebugLinesArguments.m_startingLineIndex = serverCmd.m_sendDebugLinesArgs.m_numDebugLines + @@ -204,6 +241,17 @@ bool PhysicsDirect::processVisualShapeData(const struct SharedMemoryCommand& org do { bool hasStatus = m_data->m_commandProcessor->processCommand(command, m_data->m_serverStatus, &m_data->m_bulletStreamDataServerToClient[0], SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); + + int timeout = 1024 * 1024 * 1024; + while ((!hasStatus) && (timeout-- > 0)) + { + const SharedMemoryStatus* stat = processServerStatus(); + if (stat) + { + hasStatus = true; + } + } + m_data->m_hasStatus = hasStatus; if (hasStatus) { @@ -223,6 +271,8 @@ bool PhysicsDirect::processVisualShapeData(const struct SharedMemoryCommand& org if (serverCmd.m_sendVisualShapeArgs.m_numRemainingVisualShapes >0 && serverCmd.m_sendVisualShapeArgs.m_numVisualShapesCopied) { + m_data->m_hasStatus = false; + command.m_type = CMD_REQUEST_VISUAL_SHAPE_INFO; command.m_requestVisualShapeDataArguments.m_startingVisualShapeIndex = serverCmd.m_sendVisualShapeArgs.m_startingVisualShapeIndex + serverCmd.m_sendVisualShapeArgs.m_numVisualShapesCopied; command.m_requestVisualShapeDataArguments.m_bodyUniqueId = serverCmd.m_sendVisualShapeArgs.m_bodyUniqueId; @@ -243,7 +293,19 @@ bool PhysicsDirect::processContactPointData(const struct SharedMemoryCommand& or 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; + + int timeout = 1024 * 1024 * 1024; + while ((!hasStatus) && (timeout-- > 0)) + { + const SharedMemoryStatus* stat = processServerStatus(); + if (stat) + { + hasStatus = true; + } + } + + + m_data->m_hasStatus = hasStatus; if (hasStatus) { if (m_data->m_verboseOutput) @@ -264,7 +326,10 @@ bool PhysicsDirect::processContactPointData(const struct SharedMemoryCommand& or if (serverCmd.m_sendContactPointArgs.m_numRemainingContactPoints>0 && serverCmd.m_sendContactPointArgs.m_numContactPointsCopied) { - command.m_type = CMD_REQUEST_CONTACT_POINT_INFORMATION; + + m_data->m_hasStatus = false; + + command.m_type = CMD_REQUEST_CONTACT_POINT_INFORMATION; command.m_requestContactPointArguments.m_startingContactPointIndex = serverCmd.m_sendContactPointArgs.m_startingContactPointIndex+serverCmd.m_sendContactPointArgs.m_numContactPointsCopied; command.m_requestContactPointArguments.m_objectAIndexFilter = -1; command.m_requestContactPointArguments.m_objectBIndexFilter = -1; @@ -289,6 +354,18 @@ bool PhysicsDirect::processCamera(const struct SharedMemoryCommand& orgCommand) { bool hasStatus = m_data->m_commandProcessor->processCommand(command,m_data->m_serverStatus,&m_data->m_bulletStreamDataServerToClient[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); + + int timeout = 1024 * 1024 * 1024; + while ((!hasStatus) && (timeout-- > 0)) + { + const SharedMemoryStatus* stat = processServerStatus(); + if (stat) + { + hasStatus = true; + } + } + + m_data->m_hasStatus = hasStatus; if (hasStatus) { @@ -340,6 +417,7 @@ bool PhysicsDirect::processCamera(const struct SharedMemoryCommand& orgCommand) if (serverCmd.m_sendPixelDataArguments.m_numRemainingPixels > 0 && serverCmd.m_sendPixelDataArguments.m_numPixelsCopied) { + m_data->m_hasStatus = false; // continue requesting remaining pixels command.m_type = CMD_REQUEST_CAMERA_IMAGE_DATA; @@ -365,7 +443,7 @@ void PhysicsDirect::processBodyJointInfo(int bodyUniqueId, const SharedMemorySta { bParse::btBulletFile bf( &m_data->m_bulletStreamDataServerToClient[0], - serverCmd.m_dataStreamArguments.m_streamChunkLength); + serverCmd.m_numDataStreamBytes); bf.setFileDNAisMemoryDNA(); bf.parse(false); @@ -402,6 +480,87 @@ void PhysicsDirect::processBodyJointInfo(int bodyUniqueId, const SharedMemorySta } } +void PhysicsDirect::postProcessStatus(const struct SharedMemoryStatus& serverCmd) +{ + switch (serverCmd.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; im_bodyJointMap.size(); i++) + { + BodyJointInfoCache2** bodyJointsPtr = m_data->m_bodyJointMap.getAtIndex(i); + if (bodyJointsPtr && *bodyJointsPtr) + { + BodyJointInfoCache2* bodyJoints = *bodyJointsPtr; + for (int j = 0; jm_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_SDF_LOADING_COMPLETED: + { + //we'll stream further info from the physics server + //so serverCmd will be invalid, make a copy + + + int numBodies = serverCmd.m_sdfLoadedArgs.m_numBodies; + for (int i = 0; im_commandProcessor->processCommand(infoRequestCommand, infoStatus, &m_data->m_bulletStreamDataServerToClient[0], SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); + + + int timeout = 1024 * 1024 * 1024; + while ((!hasStatus) && (timeout-- > 0)) + { + hasStatus = m_data->m_commandProcessor->receiveStatus(infoStatus, &m_data->m_bulletStreamDataServerToClient[0], SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); + } + + if (hasStatus) + { + processBodyJointInfo(bodyUniqueId, infoStatus); + } + } + break; + } + case CMD_URDF_LOADING_COMPLETED: + { + + if (serverCmd.m_numDataStreamBytes > 0) + { + int bodyIndex = serverCmd.m_dataStreamArguments.m_bodyUniqueId; + processBodyJointInfo(bodyIndex, serverCmd); + } + break; + } + + default: + { + // b3Error("Unknown server status type"); + } + }; + + +} bool PhysicsDirect::submitClientCommand(const struct SharedMemoryCommand& command) { if (command.m_type==CMD_REQUEST_DEBUG_LINES) @@ -427,78 +586,7 @@ bool PhysicsDirect::submitClientCommand(const struct SharedMemoryCommand& comman 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;im_bodyJointMap.size();i++) - { - BodyJointInfoCache2** bodyJointsPtr = m_data->m_bodyJointMap.getAtIndex(i); - if (bodyJointsPtr && *bodyJointsPtr) - { - BodyJointInfoCache2* bodyJoints = *bodyJointsPtr; - for (int j=0;jm_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_SDF_LOADING_COMPLETED: - { - //we'll stream further info from the physics server - //so serverCmd will be invalid, make a copy - - - int numBodies = serverCmd.m_sdfLoadedArgs.m_numBodies; - for (int i=0;im_commandProcessor->processCommand(infoRequestCommand,infoStatus,&m_data->m_bulletStreamDataServerToClient[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); - if (hasStatus) - { - processBodyJointInfo(bodyUniqueId, infoStatus); - } - } - break; - } - case CMD_URDF_LOADING_COMPLETED: - { - - if (serverCmd.m_dataStreamArguments.m_streamChunkLength > 0) - { - int bodyIndex = serverCmd.m_dataStreamArguments.m_bodyUniqueId; - processBodyJointInfo(bodyIndex,serverCmd); - } - break; - } - - default: - { - // b3Error("Unknown server status type"); - } - }; - - + postProcessStatus(m_data->m_serverStatus); } return hasStatus; } @@ -549,7 +637,7 @@ bool PhysicsDirect::getJointInfo(int bodyIndex, int jointIndex, struct b3JointIn if (bodyJointsPtr && *bodyJointsPtr) { BodyJointInfoCache2* bodyJoints = *bodyJointsPtr; - if (jointIndex < bodyJoints->m_jointInfo.size()) + if ((jointIndex >=0) && (jointIndex < bodyJoints->m_jointInfo.size())) { info = bodyJoints->m_jointInfo[jointIndex]; return true; diff --git a/examples/SharedMemory/PhysicsDirect.h b/examples/SharedMemory/PhysicsDirect.h index 2252da3c3..968f8f560 100644 --- a/examples/SharedMemory/PhysicsDirect.h +++ b/examples/SharedMemory/PhysicsDirect.h @@ -7,9 +7,6 @@ #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 { @@ -27,9 +24,11 @@ protected: void processBodyJointInfo(int bodyUniqueId, const struct SharedMemoryStatus& serverCmd); + void postProcessStatus(const struct SharedMemoryStatus& serverCmd); + public: - PhysicsDirect(); + PhysicsDirect(class PhysicsCommandProcessorInterface* physSdk); virtual ~PhysicsDirect(); diff --git a/examples/SharedMemory/PhysicsDirectC_API.cpp b/examples/SharedMemory/PhysicsDirectC_API.cpp index e5e73b203..61ceef26f 100644 --- a/examples/SharedMemory/PhysicsDirectC_API.cpp +++ b/examples/SharedMemory/PhysicsDirectC_API.cpp @@ -2,13 +2,21 @@ #include "PhysicsDirect.h" +#include "PhysicsServerCommandProcessor.h" + //think more about naming. The b3ConnectPhysicsLoopback b3PhysicsClientHandle b3ConnectPhysicsDirect() { - PhysicsDirect* direct = new PhysicsDirect(); + PhysicsServerCommandProcessor* sdk = new PhysicsServerCommandProcessor; + + PhysicsDirect* direct = new PhysicsDirect(sdk); bool connected = direct->connect(); return (b3PhysicsClientHandle )direct; } + + +// + diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp index 667179239..278f0b7ee 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp @@ -1187,6 +1187,8 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm //catch uninitialized cases serverStatusOut.m_type = CMD_INVALID_STATUS; + serverStatusOut.m_numDataStreamBytes = 0; + serverStatusOut.m_dataStream = 0; //consume the command switch (clientCmd.m_type) @@ -1244,7 +1246,8 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm } //9 floats per line: 3 floats for 'from', 3 floats for 'to' and 3 floats for 'color' - int maxNumLines = bufferSizeInBytes/(sizeof(float)*9)-1; + int bytesPerLine = (sizeof(float) * 9); + int maxNumLines = bufferSizeInBytes/bytesPerLine-1; if (startingLineIndex >m_data->m_remoteDebugDrawer->m_lines2.size()) { b3Warning("m_startingLineIndex exceeds total number of debug lines"); @@ -1277,7 +1280,7 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm } serverStatusOut.m_type = CMD_DEBUG_LINES_COMPLETED; - + serverStatusOut.m_numDataStreamBytes = numLines * bytesPerLine; serverStatusOut.m_sendDebugLinesArgs.m_numDebugLines = numLines; serverStatusOut.m_sendDebugLinesArgs.m_startingLineIndex = startingLineIndex; serverStatusOut.m_sendDebugLinesArgs.m_numRemainingDebugLines = m_data->m_remoteDebugDrawer->m_lines2.size()-(startingLineIndex+numLines); @@ -1327,6 +1330,8 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm float* depthBuffer = (float*)(bufferServerToClient+numRequestedPixels*4); int* segmentationMaskBuffer = (int*)(bufferServerToClient+numRequestedPixels*8); + serverStatusOut.m_numDataStreamBytes = numRequestedPixels * totalBytesPerPixel; + if ((clientCmd.m_updateFlags & ER_BULLET_HARDWARE_OPENGL)!=0) { m_data->m_guiHelper->copyCameraImageData(clientCmd.m_requestPixelDataArguments.m_viewMatrix, @@ -1368,6 +1373,7 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm } serverStatusOut.m_type = CMD_CAMERA_IMAGE_COMPLETED; + serverStatusOut.m_sendPixelDataArguments.m_numPixelsCopied = numPixelsCopied; serverStatusOut.m_sendPixelDataArguments.m_numRemainingPixels = numRemainingPixels - numPixelsCopied; serverStatusOut.m_sendPixelDataArguments.m_startingPixelIndex = startPixelIndex; @@ -1386,7 +1392,8 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm serverStatusOut.m_type = CMD_BODY_INFO_COMPLETED; serverStatusOut.m_dataStreamArguments.m_bodyUniqueId = sdfInfoArgs.m_bodyUniqueId; - serverStatusOut.m_dataStreamArguments.m_streamChunkLength = streamSizeInBytes; + serverStatusOut.m_numDataStreamBytes = streamSizeInBytes; + hasStatus = true; break; } @@ -1606,11 +1613,11 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm m_data->m_guiHelper->autogenerateGraphicsObjects(this->m_data->m_dynamicsWorld); serverStatusOut.m_type = CMD_URDF_LOADING_COMPLETED; - serverStatusOut.m_dataStreamArguments.m_streamChunkLength = 0; + if (m_data->m_urdfLinkNameMapper.size()) { - serverStatusOut.m_dataStreamArguments.m_streamChunkLength = m_data->m_urdfLinkNameMapper.at(m_data->m_urdfLinkNameMapper.size()-1)->m_memSerializer->getCurrentBufferSize(); + serverStatusOut.m_numDataStreamBytes = m_data->m_urdfLinkNameMapper.at(m_data->m_urdfLinkNameMapper.size()-1)->m_memSerializer->getCurrentBufferSize(); } serverStatusOut.m_dataStreamArguments.m_bodyUniqueId = bodyUniqueId; hasStatus = true; @@ -2583,7 +2590,7 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm serverCmd.m_sendContactPointArgs.m_startingContactPointIndex = clientCmd.m_requestContactPointArguments.m_startingContactPointIndex; serverCmd.m_sendContactPointArgs.m_numRemainingContactPoints = numContactPoints - clientCmd.m_requestContactPointArguments.m_startingContactPointIndex - serverCmd.m_sendContactPointArgs.m_numContactPointsCopied; - + serverCmd.m_numDataStreamBytes = totalBytesPerContact * serverCmd.m_sendContactPointArgs.m_numContactPointsCopied; serverCmd.m_type = CMD_CONTACT_POINT_INFORMATION_COMPLETED; //CMD_CONTACT_POINT_INFORMATION_FAILED, hasStatus = true; break; @@ -3006,7 +3013,7 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm serverCmd.m_sendVisualShapeArgs.m_numVisualShapesCopied = 1; serverCmd.m_sendVisualShapeArgs.m_startingVisualShapeIndex = clientCmd.m_requestVisualShapeDataArguments.m_startingVisualShapeIndex; serverCmd.m_sendVisualShapeArgs.m_bodyUniqueId = clientCmd.m_requestVisualShapeDataArguments.m_bodyUniqueId; - + serverCmd.m_numDataStreamBytes = sizeof(b3VisualShapeData)*serverCmd.m_sendVisualShapeArgs.m_numVisualShapesCopied; serverCmd.m_type =CMD_VISUAL_SHAPE_INFO_COMPLETED; hasStatus = true; break; diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.h b/examples/SharedMemory/PhysicsServerCommandProcessor.h index 2814d11dd..e271cdff6 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.h +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.h @@ -3,6 +3,8 @@ #include "LinearMath/btVector3.h" +#include "PhysicsCommandProcessorInterface.h" + struct SharedMemLines { btVector3 m_from; @@ -10,8 +12,10 @@ struct SharedMemLines btVector3 m_color; }; + + ///todo: naming. Perhaps PhysicsSdkCommandprocessor? -class PhysicsServerCommandProcessor +class PhysicsServerCommandProcessor : public PhysicsCommandProcessorInterface { struct PhysicsServerCommandProcessorInternalData* m_data; @@ -22,15 +26,15 @@ class PhysicsServerCommandProcessor protected: - - bool loadSdf(const char* fileName, char* bufferServerToClient, int bufferSizeInBytes, bool useMultiBody); + + bool loadSdf(const char* fileName, char* bufferServerToClient, int bufferSizeInBytes, bool useMultiBody); bool loadUrdf(const char* fileName, const class btVector3& pos, const class btQuaternion& orn, - bool useMultiBody, bool useFixedBase, int* bodyUniqueIdPtr, char* bufferServerToClient, int bufferSizeInBytes); + bool useMultiBody, bool useFixedBase, int* bodyUniqueIdPtr, char* bufferServerToClient, int bufferSizeInBytes); bool supportsJointMotor(class btMultiBody* body, int linkIndex); - + int createBodyInfoStream(int bodyUniqueId, char* bufferServerToClient, int bufferSizeInBytes); void deleteCachedInverseDynamicsBodies(); @@ -39,12 +43,30 @@ public: 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 bool connect() + { + return true; + }; + + virtual void disconnect() {} + + virtual bool isConnected() const + { + return true; + } + + + + virtual bool processCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); + + virtual bool receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes) + { + return false; + }; virtual void renderScene(); virtual void physicsDebugDraw(int debugDrawFlags); diff --git a/examples/SharedMemory/SharedMemoryCommandProcessor.cpp b/examples/SharedMemory/SharedMemoryCommandProcessor.cpp new file mode 100644 index 000000000..406b9ae4f --- /dev/null +++ b/examples/SharedMemory/SharedMemoryCommandProcessor.cpp @@ -0,0 +1,216 @@ +#include "SharedMemoryCommandProcessor.h" + +#include "PosixSharedMemory.h" +#include "Win32SharedMemory.h" +#include "Bullet3Common/b3Logging.h" +#include "Bullet3Common/b3Scalar.h" + +#include "SharedMemoryBlock.h" + + +struct SharedMemoryCommandProcessorInternalData +{ + int m_sharedMemoryKey; + bool m_isConnected; + SharedMemoryInterface* m_sharedMemory; + bool m_ownsSharedMemory; + bool m_verboseOutput; + bool m_waitingForServer; + SharedMemoryStatus m_lastServerStatus; + SharedMemoryBlock* m_testBlock1; + + + SharedMemoryCommandProcessorInternalData() + :m_sharedMemoryKey(SHARED_MEMORY_KEY), + m_isConnected(false), + m_sharedMemory(0), + m_ownsSharedMemory(false), + m_verboseOutput(false), + m_waitingForServer(false), + m_testBlock1(0) + { + + } +}; + +SharedMemoryCommandProcessor::SharedMemoryCommandProcessor() +{ + m_data = new SharedMemoryCommandProcessorInternalData; + m_data->m_sharedMemoryKey = SHARED_MEMORY_KEY; +#ifdef _WIN32 + m_data->m_sharedMemory = new Win32SharedMemoryClient(); +#else + m_data->m_sharedMemory = new PosixSharedMemory(); +#endif + m_data->m_ownsSharedMemory = true; + + +} + +SharedMemoryCommandProcessor::~SharedMemoryCommandProcessor() +{ + if (m_data->m_isConnected) + { + disconnect(); + } + if (m_data->m_ownsSharedMemory) + { + delete m_data->m_sharedMemory; + } + delete m_data; + +} + +bool SharedMemoryCommandProcessor::connect() +{ + + if (m_data->m_isConnected) + return true; + + bool allowCreation = false; + m_data->m_testBlock1 = (SharedMemoryBlock*)m_data->m_sharedMemory->allocateSharedMemory( + m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE, allowCreation); + + if (m_data->m_testBlock1) { + if (m_data->m_testBlock1->m_magicId != SHARED_MEMORY_MAGIC_NUMBER) { + b3Error("Error: please start server before client\n"); + m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, + SHARED_MEMORY_SIZE); + m_data->m_testBlock1 = 0; + return false; + } + else { + if (m_data->m_verboseOutput) { + b3Printf("Connected to existing shared memory, status OK.\n"); + } + m_data->m_isConnected = true; + } + } + else { + b3Error("Cannot connect to shared memory"); + return false; + } + return true; + +} + +void SharedMemoryCommandProcessor::disconnect() +{ + if (m_data->m_isConnected && m_data->m_sharedMemory) + { + m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE); + } + m_data->m_isConnected = false; + +} + +bool SharedMemoryCommandProcessor::isConnected() const +{ + return m_data->m_isConnected; +} + + +bool SharedMemoryCommandProcessor::processCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes) +{ + if (!m_data->m_waitingForServer) { + if (&m_data->m_testBlock1->m_clientCommands[0] != &clientCmd) { + m_data->m_testBlock1->m_clientCommands[0] = clientCmd; + } + m_data->m_testBlock1->m_numClientCommands++; + m_data->m_waitingForServer = true; + } + + return false; +} + +bool SharedMemoryCommandProcessor::receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes) +{ + SharedMemoryStatus* stat = 0; + + m_data->m_lastServerStatus.m_dataStream = 0; + m_data->m_lastServerStatus.m_numDataStreamBytes = 0; + + if (!m_data->m_testBlock1) + { + //m_data->m_lastServerStatus.m_type = CMD_SHARED_MEMORY_NOT_INITIALIZED; + //return &m_data->m_lastServerStatus; + //serverStatusOut = m_data->m_lastServerStatus; + return false; + } + + if (!m_data->m_waitingForServer) { + return false; + } + + if (m_data->m_testBlock1->m_magicId != SHARED_MEMORY_MAGIC_NUMBER) + { + //m_data->m_lastServerStatus.m_type = CMD_SHARED_MEMORY_NOT_INITIALIZED; + //return &m_data->m_lastServerStatus; + return false; + } + + if (m_data->m_testBlock1->m_numServerCommands > + m_data->m_testBlock1->m_numProcessedServerCommands) + { + b3Assert(m_data->m_testBlock1->m_numServerCommands == + m_data->m_testBlock1->m_numProcessedServerCommands + 1); + + const SharedMemoryStatus& serverCmd = m_data->m_testBlock1->m_serverCommands[0]; + m_data->m_lastServerStatus = serverCmd; + m_data->m_lastServerStatus.m_dataStream = m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor; + + for (int i = 0; i < m_data->m_lastServerStatus.m_numDataStreamBytes; i++) + { + bufferServerToClient[i] = m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[i]; + } + + m_data->m_testBlock1->m_numProcessedServerCommands++; + // we don't have more than 1 command outstanding (in total, either server or client) + b3Assert(m_data->m_testBlock1->m_numProcessedServerCommands == + m_data->m_testBlock1->m_numServerCommands); + + if (m_data->m_testBlock1->m_numServerCommands == + m_data->m_testBlock1->m_numProcessedServerCommands) { + m_data->m_waitingForServer = false; + } + else { + m_data->m_waitingForServer = true; + } + + serverStatusOut = m_data->m_lastServerStatus; + + return true; + } + return false; +} + +void SharedMemoryCommandProcessor::renderScene() +{ +} + +void SharedMemoryCommandProcessor::physicsDebugDraw(int debugDrawFlags) +{ +} + +void SharedMemoryCommandProcessor::setGuiHelper(struct GUIHelperInterface* guiHelper) +{ +} + +void SharedMemoryCommandProcessor::setSharedMemoryInterface(class SharedMemoryInterface* sharedMem) +{ + if (m_data->m_sharedMemory && m_data->m_ownsSharedMemory) + { + delete m_data->m_sharedMemory; + } + m_data->m_ownsSharedMemory = false; + m_data->m_sharedMemory = sharedMem; + +} + + +void SharedMemoryCommandProcessor::setSharedMemoryKey(int key) +{ + m_data->m_sharedMemoryKey = key; +} + + diff --git a/examples/SharedMemory/SharedMemoryCommandProcessor.h b/examples/SharedMemory/SharedMemoryCommandProcessor.h new file mode 100644 index 000000000..bec9e614f --- /dev/null +++ b/examples/SharedMemory/SharedMemoryCommandProcessor.h @@ -0,0 +1,37 @@ +#ifndef SHARED_MEMORY_COMMAND_PROCESSOR_H +#define SHARED_MEMORY_COMMAND_PROCESSOR_H + +#include "PhysicsCommandProcessorInterface.h" + +class SharedMemoryCommandProcessor : public PhysicsCommandProcessorInterface +{ + + struct SharedMemoryCommandProcessorInternalData* m_data; + +public: + SharedMemoryCommandProcessor(); + + virtual ~SharedMemoryCommandProcessor(); + + virtual bool connect(); + + virtual void disconnect(); + + virtual bool isConnected() const; + + virtual bool processCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); + + virtual bool receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); + + virtual void renderScene(); + virtual void physicsDebugDraw(int debugDrawFlags); + virtual void setGuiHelper(struct GUIHelperInterface* guiHelper); + + void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem); + void setSharedMemoryKey(int key); + + +}; + +#endif //SHARED_MEMORY_COMMAND_PROCESSOR_H + diff --git a/examples/SharedMemory/SharedMemoryCommands.h b/examples/SharedMemory/SharedMemoryCommands.h index 0b7f325f8..3d58789bc 100644 --- a/examples/SharedMemory/SharedMemoryCommands.h +++ b/examples/SharedMemory/SharedMemoryCommands.h @@ -90,7 +90,6 @@ struct UrdfArgs struct BulletDataStreamArgs { char m_bulletFileName[MAX_FILENAME_LENGTH]; - int m_streamChunkLength; int m_bodyUniqueId; }; @@ -508,6 +507,10 @@ struct SharedMemoryStatus smUint64_t m_timeStamp; int m_sequenceNumber; + //m_streamBytes is only for internal purposes + int m_numDataStreamBytes; + char* m_dataStream; + union { struct BulletDataStreamArgs m_dataStreamArguments; diff --git a/examples/SharedMemory/premake4.lua b/examples/SharedMemory/premake4.lua index 2215cfbe0..2bbf3b569 100644 --- a/examples/SharedMemory/premake4.lua +++ b/examples/SharedMemory/premake4.lua @@ -42,6 +42,14 @@ myfiles = "PhysicsLoopBack.h", "PhysicsLoopBackC_API.cpp", "PhysicsLoopBackC_API.h", + "PhysicsClientSharedMemory_C_API.cpp", + "PhysicsClientSharedMemory_C_API.h", + "PhysicsClientSharedMemory2_C_API.cpp", + "PhysicsClientSharedMemory2_C_API.h", + "PhysicsClientSharedMemory2.cpp", + "PhysicsClientSharedMemory2.h", + "SharedMemoryCommandProcessor.cpp", + "SharedMemoryCommandProcessor.h", "PhysicsServerCommandProcessor.cpp", "PhysicsServerCommandProcessor.h", "TinyRendererVisualShapeConverter.cpp", @@ -288,4 +296,7 @@ if os.is("Windows") then end -end \ No newline at end of file +end + + +include "udp" diff --git a/examples/SharedMemory/udp/main.cpp b/examples/SharedMemory/udp/main.cpp new file mode 100644 index 000000000..d653b34fd --- /dev/null +++ b/examples/SharedMemory/udp/main.cpp @@ -0,0 +1,187 @@ +/* server.cpp */ +#include +#include +#include "SharedMemoryCommandProcessor.h" +#include "SharedMemoryCommands.h" +#include "Bullet3Common/b3AlignedObjectArray.h" +#include "PhysicsServerCommandProcessor.h" + +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; +} + + + +int main(int argc, char *argv[]) +{ + unsigned char buf[4]; + + + SharedMemoryCommandProcessor* sm = new SharedMemoryCommandProcessor; + +// PhysicsDirect* sm = new PhysicsDirect(sdk); + + //PhysicsClientSharedMemory* sm = new PhysicsClientSharedMemory(); + + bool isPhysicsClientConnected = sm->connect(); + + if (isPhysicsClientConnected) + { + + ENetAddress address; + ENetHost *server; + ENetEvent event; + int serviceResult; + + puts("Starting server"); + + if (enet_initialize() != 0) + { + puts("Error initialising enet"); + exit(EXIT_FAILURE); + } + + + /* Bind the server to the default localhost. */ + /* A specific host address can be specified by */ + /* enet_address_set_host (& address, "x.x.x.x"); */ + address.host = ENET_HOST_ANY; + /* Bind the server to port 1234. */ + address.port = 1234; + + server = enet_host_create(&address, + 32, /* number of clients */ + 2, /* number of channels */ + 0, /* Any incoming bandwith */ + 0); /* Any outgoing bandwith */ + + if (server == NULL) + { + puts("Could not create server host"); + exit(EXIT_FAILURE); + } + + + while (true) + { + serviceResult = 1; + + /* Keep doing host_service until no events are left */ + while (serviceResult > 0) + { + /* Wait up to 1000 milliseconds for an event. */ + serviceResult = enet_host_service(server, &event, 0); + if (serviceResult > 0) + { + + switch (event.type) + { + case ENET_EVENT_TYPE_CONNECT: + printf("A new client connected from %x:%u.\n", + event.peer->address.host, + event.peer->address.port); + + /* Store any relevant client information here. */ + event.peer->data = (void*)"Client information"; + + break; + + case ENET_EVENT_TYPE_RECEIVE: + printf("A packet of length %u containing '%s' was " + "received from %s on channel %u.\n", + event.packet->dataLength, + event.packet->data, + event.peer->data, + event.channelID); + + if (event.packet->dataLength == sizeof(SharedMemoryCommand)) + { + SharedMemoryCommand* cmdPtr = (SharedMemoryCommand*)event.packet->data; + SharedMemoryStatus serverStatus; + b3AlignedObjectArray buffer; + buffer.resize(SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); + + bool hasStatus = sm->processCommand(*cmdPtr,serverStatus, &buffer[0], buffer.size()); + + int timeout = 1024 * 1024 * 1024; + while ((!hasStatus) && (timeout-- > 0)) + { + hasStatus = sm->receiveStatus(serverStatus, &buffer[0], buffer.size()); + + } + printf("buffer.size = %d\n", buffer.size()); + printf("serverStatus.m_numDataStreamBytes = %d\n", serverStatus.m_numDataStreamBytes); + if (hasStatus) + { + //create packetData with [int packetSizeInBytes, status, streamBytes) + unsigned char* statBytes = (unsigned char*)&serverStatus; + b3AlignedObjectArray packetData; + packetData.resize(4 + sizeof(SharedMemoryStatus) + serverStatus.m_numDataStreamBytes); + int sz = packetData.size(); + int curPos = 0; + + MySerializeInt(sz, &packetData[curPos]); + curPos += 4; + for (int i = 0; i < sizeof(SharedMemoryStatus); i++) + { + packetData[i + curPos] = statBytes[i]; + } + curPos += sizeof(SharedMemoryStatus); + + for (int i = 0; i < serverStatus.m_numDataStreamBytes; i++) + { + packetData[i + curPos] = serverStatus.m_dataStream[i]; + } + + ENetPacket *packet = enet_packet_create(&packetData[0], packetData.size() , ENET_PACKET_FLAG_RELIABLE); + //enet_peer_send(peer, 0, packet); + + enet_host_broadcast(server, 0, packet); + } + } + else + { + printf("received packet with unknown contents\n"); + } + + + /* Tell all clients about this message */ + //enet_host_broadcast(server, 0, event.packet); + + break; + + case ENET_EVENT_TYPE_DISCONNECT: + printf("%s disconnected.\n", event.peer->data); + + /* Reset the peer's client information. */ + + event.peer->data = NULL; + + break; + } + } + else if (serviceResult > 0) + { + puts("Error with servicing the server"); + exit(EXIT_FAILURE); + } + } + + } + + enet_host_destroy(server); + enet_deinitialize(); + } + delete sm; + + return 0; + +} diff --git a/examples/SharedMemory/udp/premake4.lua b/examples/SharedMemory/udp/premake4.lua new file mode 100644 index 000000000..852dfc638 --- /dev/null +++ b/examples/SharedMemory/udp/premake4.lua @@ -0,0 +1,46 @@ + +project ("App_PhysicsServerUDP") + + language "C++" + + kind "ConsoleApp" + + includedirs {"../../ThirdPartyLibs/enet/include","../../../src",".."} + + if os.is("Windows") then + defines { "WIN32" } + + links {"Ws2_32","Winmm"} + end + if os.is("Linux") then + end + if os.is("MacOSX") then + end + + + links { + "enet", + "BulletFileLoader", + "Bullet3Common", + "LinearMath" + } + + files { + "main.cpp", + "../PhysicsClient.cpp", + "../PhysicsClient.h", + "../PhysicsDirect.cpp", + "../PhysicsDirect.h", + "../PhysicsCommandProcessorInterface.h", + "../SharedMemoryCommandProcessor.cpp", + "../SharedMemoryCommandProcessor.h", + "../PhysicsClientC_API.cpp", + "../PhysicsClientC_API.h", + "../Win32SharedMemory.cpp", + "../Win32SharedMemory.h", + "../PosixSharedMemory.cpp", + "../PosixSharedMemory.h", + "../../Utils/b3ResourcePath.cpp", + "../../Utils/b3ResourcePath.h", + } + diff --git a/examples/StandaloneMain/hellovr_opengl_main.cpp b/examples/StandaloneMain/hellovr_opengl_main.cpp index 89b8cfe29..52b1574f3 100644 --- a/examples/StandaloneMain/hellovr_opengl_main.cpp +++ b/examples/StandaloneMain/hellovr_opengl_main.cpp @@ -844,13 +844,13 @@ void CMainApplication::RenderFrame() // happen right before and after the vsync causing all kinds of jittering issues. This glFinish() // appears to clear that up. Temporary fix while I try to get nvidia to investigate this problem. // 1/29/2014 mikesart - glFinish(); + //glFinish(); } // SwapWindow { B3_PROFILE("m_app->swapBuffer"); - m_app->swapBuffer(); +// m_app->swapBuffer(); //SDL_GL_SwapWindow( m_pWindow ); } diff --git a/examples/ThirdPartyLibs/enet/premake4.lua b/examples/ThirdPartyLibs/enet/premake4.lua index 522db3431..05390e766 100644 --- a/examples/ThirdPartyLibs/enet/premake4.lua +++ b/examples/ThirdPartyLibs/enet/premake4.lua @@ -14,8 +14,7 @@ files{"unix.c"} end - targetdir "../../../lib" - + includedirs { ".","include" } diff --git a/examples/pybullet/CMakeLists.txt b/examples/pybullet/CMakeLists.txt index dbac56750..ccde6a85e 100644 --- a/examples/pybullet/CMakeLists.txt +++ b/examples/pybullet/CMakeLists.txt @@ -3,6 +3,7 @@ INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/examples ${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs + ${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/enet/include ${PYTHON_INCLUDE_DIRS} ) IF(BUILD_PYBULLET_NUMPY) @@ -16,7 +17,7 @@ SET(pybullet_SRCS ../../examples/SharedMemory/IKTrajectoryHelper.cpp ../../examples/SharedMemory/IKTrajectoryHelper.h ../../examples/ExampleBrowser/InProcessExampleBrowser.cpp - ../../examples/SharedMemory/TinyRendererVisualShapeConverter.cpp + ../../examples/SharedMemory/TinyRendererVisualShapeConverter.cpp ../../examples/SharedMemory/TinyRendererVisualShapeConverter.h ../../examples/OpenGLWindow/SimpleCamera.cpp ../../examples/OpenGLWindow/SimpleCamera.h @@ -42,6 +43,9 @@ SET(pybullet_SRCS ../../examples/SharedMemory/PhysicsServerCommandProcessor.h ../../examples/SharedMemory/PhysicsClientSharedMemory.cpp ../../examples/SharedMemory/PhysicsClientSharedMemory.h + ../../examples/SharedMemory/PhysicsClientSharedMemory_C_API.cpp + ../../examples/SharedMemory/PhysicsClientSharedMemory_C_API.h + ../../examples/SharedMemory/PhysicsClientC_API.cpp ../../examples/SharedMemory/PhysicsClientC_API.h ../../examples/SharedMemory/Win32SharedMemory.cpp @@ -69,20 +73,55 @@ SET(pybullet_SRCS ../../examples/MultiThreading/b3PosixThreadSupport.cpp ../../examples/MultiThreading/b3Win32ThreadSupport.cpp ../../examples/MultiThreading/b3ThreadSupportInterface.cpp + ) IF(WIN32) -LINK_LIBRARIES( + LINK_LIBRARIES( ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ) - + IF(BUILD_PYBULLET_ENET) + ADD_DEFINITIONS(-DWIN32 -DBT_ENABLE_ENET) + ENDIF(BUILD_PYBULLET_ENET) ENDIF(WIN32) -ADD_LIBRARY(pybullet SHARED ${pybullet_SRCS}) + +IF(BUILD_PYBULLET_ENET) + ADD_LIBRARY(pybullet SHARED ${pybullet_SRCS} + ../../examples/SharedMemory/PhysicsClientUDP.cpp + ../../examples/SharedMemory/PhysicsClientUDP_C_API.cpp + ../../examples/SharedMemory/PhysicsClientUDP.h + ../../examples/SharedMemory/PhysicsClientUDP_C_API.h + ../../examples/ThirdPartyLibs/enet/win32.c + ../../examples/ThirdPartyLibs/enet/unix.c + ../../examples/ThirdPartyLibs/enet/callbacks.c + ../../examples/ThirdPartyLibs/enet/compress.c + ../../examples/ThirdPartyLibs/enet/host.c + ../../examples/ThirdPartyLibs/enet/list.c + ../../examples/ThirdPartyLibs/enet/packet.c + ../../examples/ThirdPartyLibs/enet/peer.c + ../../examples/ThirdPartyLibs/enet/protocol.c + ) +ELSE(BUILD_PYBULLET_ENET) + ADD_LIBRARY(pybullet SHARED ${pybullet_SRCS}) +ENDIF(BUILD_PYBULLET_ENET) SET_TARGET_PROPERTIES(pybullet PROPERTIES VERSION ${BULLET_VERSION}) SET_TARGET_PROPERTIES(pybullet PROPERTIES SOVERSION ${BULLET_VERSION}) - -TARGET_LINK_LIBRARIES(pybullet BulletExampleBrowserLib BulletFileLoader BulletWorldImporter BulletSoftBody BulletDynamics BulletCollision BulletInverseDynamicsUtils BulletInverseDynamics LinearMath OpenGLWindow gwen BussIK Bullet3Common ${PYTHON_LIBRARIES}) +SET_TARGET_PROPERTIES(pybullet PROPERTIES DEBUG_POSTFIX "_d") + + +IF(WIN32) + IF(BUILD_PYBULLET_ENET) + TARGET_LINK_LIBRARIES(pybullet ws2_32 ) + ENDIF(BUILD_PYBULLET_ENET) + + SET_TARGET_PROPERTIES(pybullet PROPERTIES SUFFIX ".pyd" ) +ENDIF(WIN32) + + + + +TARGET_LINK_LIBRARIES(pybullet ws2_32 BulletExampleBrowserLib BulletFileLoader BulletWorldImporter BulletSoftBody BulletDynamics BulletCollision BulletInverseDynamicsUtils BulletInverseDynamics LinearMath OpenGLWindow gwen BussIK Bullet3Common ${PYTHON_LIBRARIES}) diff --git a/examples/pybullet/premake4.lua b/examples/pybullet/premake4.lua index 6f684a331..86ed39611 100644 --- a/examples/pybullet/premake4.lua +++ b/examples/pybullet/premake4.lua @@ -33,12 +33,37 @@ project ("pybullet") } end +if not _OPTIONS["no-enet"] then + + includedirs {"../../examples/ThirdPartyLibs/enet/include"} + + if os.is("Windows") then + defines { "WIN32" } + links {"Ws2_32","Winmm"} + end + if os.is("Linux") then + end + if os.is("MacOSX") then + end + + links {"enet"} + + files { + "../../examples/SharedMemory/PhysicsClientUDP.cpp", + "../../examples/SharedMemory/PhysicsClientUDP.h", + "../../examples/SharedMemory/PhysicsClientUDP_C_API.cpp", + "../../examples/SharedMemory/PhysicsClientUDP_C_API.h", + } + defines {"BT_ENABLE_ENET"} + end + + files { "pybullet.c", "../../examples/SharedMemory/IKTrajectoryHelper.cpp", "../../examples/SharedMemory/IKTrajectoryHelper.h", "../../examples/ExampleBrowser/InProcessExampleBrowser.cpp", - "../../examples/SharedMemory/TinyRendererVisualShapeConverter.cpp", + "../../examples/SharedMemory/TinyRendererVisualShapeConverter.cpp", "../../examples/SharedMemory/TinyRendererVisualShapeConverter.h", "../../examples/OpenGLWindow/SimpleCamera.cpp", "../../examples/OpenGLWindow/SimpleCamera.h", @@ -64,6 +89,8 @@ project ("pybullet") "../../examples/SharedMemory/PhysicsServerCommandProcessor.h", "../../examples/SharedMemory/PhysicsClientSharedMemory.cpp", "../../examples/SharedMemory/PhysicsClientSharedMemory.h", + "../../examples/SharedMemory/PhysicsClientSharedMemory_C_API.cpp", + "../../examples/SharedMemory/PhysicsClientSharedMemory_C_API.h", "../../examples/SharedMemory/PhysicsClientC_API.cpp", "../../examples/SharedMemory/PhysicsClientC_API.h", "../../examples/SharedMemory/Win32SharedMemory.cpp", diff --git a/examples/pybullet/pybullet.c b/examples/pybullet/pybullet.c index 744340f1e..394ddc6a3 100644 --- a/examples/pybullet/pybullet.c +++ b/examples/pybullet/pybullet.c @@ -1,7 +1,9 @@ #include "../SharedMemory/PhysicsClientC_API.h" #include "../SharedMemory/PhysicsDirectC_API.h" #include "../SharedMemory/SharedMemoryInProcessPhysicsC_API.h" - +#ifdef BT_ENABLE_ENET +#include "../SharedMemory/PhysicsClientUDP_C_API.h" +#endif //BT_ENABLE_ENET #ifdef __APPLE__ #include @@ -22,6 +24,7 @@ enum eCONNECT_METHOD { eCONNECT_GUI = 1, eCONNECT_DIRECT = 2, eCONNECT_SHARED_MEMORY = 3, + eCONNECT_UDP = 4, }; static PyObject* SpamError; @@ -60,8 +63,8 @@ static PyObject* pybullet_connectPhysicsServer(PyObject* self, PyObject* args) { int method = eCONNECT_GUI; if (!PyArg_ParseTuple(args, "i", &method)) { PyErr_SetString(SpamError, - "connectPhysicsServer expected argument eCONNECT_GUI, " - "eCONNECT_DIRECT or eCONNECT_SHARED_MEMORY"); + "connectPhysicsServer expected argument GUI, " + "DIRECT, SHARED_MEMORY or UDP"); return NULL; } @@ -85,6 +88,18 @@ static PyObject* pybullet_connectPhysicsServer(PyObject* self, PyObject* args) { sm = b3ConnectSharedMemory(SHARED_MEMORY_KEY); break; } + case eCONNECT_UDP: + { +#ifdef BT_ENABLE_ENET + + sm = b3ConnectPhysicsUDP("localhost", 1234); +#else + PyErr_SetString(SpamError, "UDP is not enabled in this pybullet build"); + return NULL; +#endif //BT_ENABLE_ENET + + break; + } default: { PyErr_SetString(SpamError, "connectPhysicsServer unexpected argument"); @@ -2401,6 +2416,8 @@ initpybullet(void) eCONNECT_SHARED_MEMORY); // user read PyModule_AddIntConstant(m, "DIRECT", eCONNECT_DIRECT); // user read PyModule_AddIntConstant(m, "GUI", eCONNECT_GUI); // user read + PyModule_AddIntConstant(m, "UDP", eCONNECT_UDP); // user read + PyModule_AddIntConstant(m, "TORQUE_CONTROL", CONTROL_MODE_TORQUE); PyModule_AddIntConstant(m, "VELOCITY_CONTROL", diff --git a/test/SharedMemory/CMakeLists.txt b/test/SharedMemory/CMakeLists.txt index 8ece789cc..52297594c 100644 --- a/test/SharedMemory/CMakeLists.txt +++ b/test/SharedMemory/CMakeLists.txt @@ -41,7 +41,10 @@ ENDIF() ../../examples/SharedMemory/PhysicsServerCommandProcessor.h ../../examples/SharedMemory/PhysicsClientSharedMemory.cpp ../../examples/SharedMemory/PhysicsClientSharedMemory.h - ../../examples/SharedMemory/PhysicsClientC_API.cpp + ../../examples/SharedMemory/PhysicsClientSharedMemory_C_API.cpp + ../../examples/SharedMemory/PhysicsClientSharedMemory_C_API.h + + ../../examples/SharedMemory/PhysicsClientC_API.cpp ../../examples/SharedMemory/PhysicsClientC_API.h ../../examples/SharedMemory/PhysicsLoopBack.cpp ../../examples/SharedMemory/PhysicsLoopBack.h diff --git a/test/SharedMemory/premake4.lua b/test/SharedMemory/premake4.lua index 1974ba471..ca48cfea0 100644 --- a/test/SharedMemory/premake4.lua +++ b/test/SharedMemory/premake4.lua @@ -17,6 +17,8 @@ project ("Test_SharedMemoryPhysicsClient") "../../examples/SharedMemory/PhysicsClient.h", "../../examples/SharedMemory/PhysicsClientSharedMemory.cpp", "../../examples/SharedMemory/PhysicsClientSharedMemory.h", + "../../examples/SharedMemory/PhysicsClientSharedMemory_C_API.cpp", + "../../examples/SharedMemory/PhysicsClientSharedMemory_C_API.h", "../../examples/SharedMemory/PhysicsClientC_API.cpp", "../../examples/SharedMemory/PhysicsClientC_API.h", "../../examples/SharedMemory/Win32SharedMemory.cpp", diff --git a/test/SharedMemory/test.c b/test/SharedMemory/test.c index c366ab3a5..a1a6591d8 100644 --- a/test/SharedMemory/test.c +++ b/test/SharedMemory/test.c @@ -3,6 +3,10 @@ #include "SharedMemory/PhysicsClientC_API.h" #endif //PHYSICS_SHARED_MEMORY +#ifdef PHYSICS_UDP +#include "SharedMemory/PhysicsClientUDP_C_API.h" +#endif//PHYSICS_UDP + #ifdef PHYSICS_LOOP_BACK #include "SharedMemory/PhysicsLoopBackC_API.h" #endif //PHYSICS_LOOP_BACK @@ -224,7 +228,7 @@ void testSharedMemory(b3PhysicsClientHandle sm) #endif } ///perform some simulation steps for testing - for ( i=0;i<100;i++) + for ( i=0;i<10000;i++) { b3SharedMemoryStatusHandle statusHandle; int statusType; @@ -319,11 +323,17 @@ int main(int argc, char* argv[]) b3PhysicsClientHandle sm = b3CreateInProcessPhysicsServerAndConnect(argc,argv); #endif //__APPLE__ #endif + #ifdef PHYSICS_SHARED_MEMORY b3PhysicsClientHandle sm = b3ConnectSharedMemory(SHARED_MEMORY_KEY); #endif //PHYSICS_SHARED_MEMORY +#ifdef PHYSICS_UDP + b3PhysicsClientHandle sm = b3ConnectPhysicsUDP("localhost",1234); +#endif //PHYSICS_UDP + testSharedMemory(sm); } #endif + diff --git a/test/enet/chat/client/main.cpp b/test/enet/chat/client/main.cpp new file mode 100644 index 000000000..59565f464 --- /dev/null +++ b/test/enet/chat/client/main.cpp @@ -0,0 +1,165 @@ + +/* client.cpp */ +#include +#include +#include + + +int main(int argc, char* argv[]) { + ENetHost *client; + ENetAddress address; + ENetPeer *peer; + ENetEvent event; + char message[1024]; + int serviceResult; + + puts("Starting client"); + + if (enet_initialize() != 0) { + fprintf(stderr, "Error initialising enet"); + exit(EXIT_FAILURE); + + } + + client = enet_host_create(NULL, /* create a client host */ + 1, /* number of clients */ + 2, /* number of channels */ + 57600 / 8, /* incoming bandwith */ + 14400 / 8); /* outgoing bandwith */ + + if (client == NULL) { + fprintf(stderr, "Could not create client host"); + exit(EXIT_FAILURE); + + } + + + enet_address_set_host(&address, "localhost"); + address.port = 1234; + + peer = enet_host_connect(client, + &address, /* address to connect to */ + 2, /* number of channels */ + 0); /* user data supplied to + the receiving host */ + + if (peer == NULL) { + fprintf(stderr, "No available peers for initiating an ENet " + "connection.\n"); + exit(EXIT_FAILURE); + + } + + + /* Try to connect to server within 5 seconds */ + if (enet_host_service(client, &event, 5000) > 0 && + event.type == ENET_EVENT_TYPE_CONNECT) + { + puts("Connection to server succeeded."); + } + else + { + /* Either the 5 seconds are up or a disconnect event was */ + /* received. Reset the peer in the event the 5 seconds */ + /* had run out without any significant event. */ + enet_peer_reset(peer); + + fprintf(stderr, "Connection to server failed."); + exit(EXIT_FAILURE); + } + + while (true) + { + serviceResult = 1; + + /* Keep doing host_service until no events are left */ + while (serviceResult > 0) + { + serviceResult = enet_host_service(client, &event, 0); + + if (serviceResult > 0) + { + switch (event.type) + { + case ENET_EVENT_TYPE_CONNECT: + printf("A new client connected from %x:%u.\n", + event.peer->address.host, + event.peer->address.port); + + event.peer->data = (void*)"New User"; + break; + + case ENET_EVENT_TYPE_RECEIVE: + printf("A packet of length %u containing '%s' was " + "received from %s on channel %u.\n", + event.packet->dataLength, + event.packet->data, + event.peer->data, + event.channelID); + + /* Clean up the packet now that we're done using it. + > */ + enet_packet_destroy(event.packet); + + break; + + case ENET_EVENT_TYPE_DISCONNECT: + printf("%s disconected.\n", event.peer->data); + + break; + } + } + else if (serviceResult > 0) + { + puts("Error with servicing the client"); + exit(EXIT_FAILURE); + } + + } + + + printf("Say> "); + gets_s(message, 1024); + + if (strcmp(message, "exit") == 0 || + strcmp(message, "quit") == 0) { + break; + + } + + if (strlen(message) > 0) { + ENetPacket *packet = enet_packet_create(message, strlen + (message) + 1, ENET_PACKET_FLAG_RELIABLE); + enet_peer_send(peer, 0, packet); + + } + + } + + enet_peer_disconnect(peer, 0); + + /* Allow up to 3 seconds for the disconnect to succeed */ + /* and drop any packets received packets */ + while (enet_host_service(client, &event, 3000) > 0) + { + + switch (event.type) + { + case ENET_EVENT_TYPE_RECEIVE: + enet_packet_destroy(event.packet); + break; + + case ENET_EVENT_TYPE_DISCONNECT: + puts("Disconnection succeeded."); + break; + } + } + + + enet_host_destroy(client); + enet_deinitialize(); + + return 0; + + +} diff --git a/test/enet/client/premake4.lua b/test/enet/chat/client/premake4.lua similarity index 70% rename from test/enet/client/premake4.lua rename to test/enet/chat/client/premake4.lua index 2a2327f24..24a71d6df 100644 --- a/test/enet/client/premake4.lua +++ b/test/enet/chat/client/premake4.lua @@ -1,12 +1,12 @@ -project ("Test_enet_client") +project ("Test_enet_chat_client") language "C++" kind "ConsoleApp" - includedirs {"../../../examples/ThirdPartyLibs/enet/include"} + includedirs {"../../../../examples/ThirdPartyLibs/enet/include"} if os.is("Windows") then defines { "WIN32" } diff --git a/test/enet/chat/server/main.cpp b/test/enet/chat/server/main.cpp new file mode 100644 index 000000000..cc15bd6a6 --- /dev/null +++ b/test/enet/chat/server/main.cpp @@ -0,0 +1,103 @@ +/* server.cpp */ +#include +#include + +int main(int argc, char *argv[]) +{ + ENetAddress address; + ENetHost *server; + ENetEvent event; + int serviceResult; + + puts("Starting server"); + + if (enet_initialize() != 0) + { + puts("Error initialising enet"); + exit(EXIT_FAILURE); + } + + + /* Bind the server to the default localhost. */ + /* A specific host address can be specified by */ + /* enet_address_set_host (& address, "x.x.x.x"); */ + address.host = ENET_HOST_ANY; + /* Bind the server to port 1234. */ + address.port = 1234; + + server = enet_host_create(&address, + 32, /* number of clients */ + 2, /* number of channels */ + 0, /* Any incoming bandwith */ + 0); /* Any outgoing bandwith */ + + if (server == NULL) + { + puts("Could not create server host"); + exit(EXIT_FAILURE); + } + + + while (true) + { + serviceResult = 1; + + /* Keep doing host_service until no events are left */ + while (serviceResult > 0) + { + /* Wait up to 1000 milliseconds for an event. */ + serviceResult = enet_host_service(server, &event, 1000); + + if (serviceResult > 0) + { + + switch (event.type) + { + case ENET_EVENT_TYPE_CONNECT: + printf("A new client connected from %x:%u.\n", + event.peer->address.host, + event.peer->address.port); + + /* Store any relevant client information here. */ + event.peer->data = (void*)"Client information"; + + break; + + case ENET_EVENT_TYPE_RECEIVE: + printf("A packet of length %u containing '%s' was " + "received from %s on channel %u.\n", + event.packet->dataLength, + event.packet->data, + event.peer->data, + event.channelID); + + /* Tell all clients about this message */ + enet_host_broadcast(server, 0, event.packet); + + break; + + case ENET_EVENT_TYPE_DISCONNECT: + printf("%s disconected.\n", event.peer->data); + + /* Reset the peer's client information. */ + + event.peer->data = NULL; + + break; + } + } + else if (serviceResult > 0) + { + puts("Error with servicing the server"); + exit(EXIT_FAILURE); + } + } + + } + + enet_host_destroy(server); + enet_deinitialize(); + + return 0; + +} diff --git a/test/enet/server/premake4.lua b/test/enet/chat/server/premake4.lua similarity index 70% rename from test/enet/server/premake4.lua rename to test/enet/chat/server/premake4.lua index 50f1c9b16..2069c2f01 100644 --- a/test/enet/server/premake4.lua +++ b/test/enet/chat/server/premake4.lua @@ -1,12 +1,12 @@ -project ("Test_enet_server") +project ("Test_enet_chat_server") language "C++" kind "ConsoleApp" - includedirs {"../../../examples/ThirdPartyLibs/enet/include"} + includedirs {"../../../../examples/ThirdPartyLibs/enet/include"} if os.is("Windows") then defines { "WIN32" } diff --git a/test/enet/client/main.cpp b/test/enet/nat_punchthrough/client/main.cpp similarity index 100% rename from test/enet/client/main.cpp rename to test/enet/nat_punchthrough/client/main.cpp diff --git a/test/enet/nat_punchthrough/client/premake4.lua b/test/enet/nat_punchthrough/client/premake4.lua new file mode 100644 index 000000000..feabb3429 --- /dev/null +++ b/test/enet/nat_punchthrough/client/premake4.lua @@ -0,0 +1,25 @@ + + +project ("Test_enet_nat_punchthrough_client") + + language "C++" + + kind "ConsoleApp" + + includedirs {"../../../../examples/ThirdPartyLibs/enet/include"} + + if os.is("Windows") then + defines { "WIN32" } + links {"Ws2_32","Winmm"} + end + if os.is("Linux") then + end + if os.is("MacOSX") then + end + + links {"enet"} + + files { + "main.cpp", + } + diff --git a/test/enet/server/main.cpp b/test/enet/nat_punchthrough/server/main.cpp similarity index 100% rename from test/enet/server/main.cpp rename to test/enet/nat_punchthrough/server/main.cpp diff --git a/test/enet/nat_punchthrough/server/premake4.lua b/test/enet/nat_punchthrough/server/premake4.lua new file mode 100644 index 000000000..2d8f4b7a8 --- /dev/null +++ b/test/enet/nat_punchthrough/server/premake4.lua @@ -0,0 +1,26 @@ + + +project ("Test_enet_nat_punchthrough_server") + + language "C++" + + kind "ConsoleApp" + + includedirs {"../../../../examples/ThirdPartyLibs/enet/include"} + + if os.is("Windows") then + defines { "WIN32" } + + links {"Ws2_32","Winmm"} + end + if os.is("Linux") then + end + if os.is("MacOSX") then + end + + links {"enet"} + + files { + "main.cpp", + } + From d62ac01d14fc9d6276b0ba1967491d05f844d194 Mon Sep 17 00:00:00 2001 From: erwincoumans Date: Fri, 4 Nov 2016 13:16:25 -0700 Subject: [PATCH 02/10] work-in-progress add UDP network connection for physics client <-> server. also set spinning friction in rolling friction demo (otherwise objects may keep on spinning forever) --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index acc474da3..d34ff9ab2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -211,7 +211,8 @@ IF(BUILD_PYBULLET) FIND_PACKAGE(PythonLibs) OPTION(BUILD_PYBULLET_NUMPY "Set when you want to build pybullet with NumPy support" OFF) - + OPTION(BUILD_PYBULLET_ENET "Set when you want to build pybullet with enet UDP networking support" ON) + IF(BUILD_PYBULLET_NUMPY) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/build3/cmake) #include(FindNumPy) From 0ffd68ac32deaa1e9a05bde06ecff9ad391543f8 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Fri, 4 Nov 2016 13:36:45 -0700 Subject: [PATCH 03/10] fixes in Linux build if pybullet with enet/UDP --- examples/pybullet/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/pybullet/CMakeLists.txt b/examples/pybullet/CMakeLists.txt index ccde6a85e..8d95cc67e 100644 --- a/examples/pybullet/CMakeLists.txt +++ b/examples/pybullet/CMakeLists.txt @@ -83,6 +83,10 @@ IF(WIN32) IF(BUILD_PYBULLET_ENET) ADD_DEFINITIONS(-DWIN32 -DBT_ENABLE_ENET) ENDIF(BUILD_PYBULLET_ENET) +ELSE(WIN32) + IF(BUILD_PYBULLET_ENET) + ADD_DEFINITIONS(-DHAS_SOCKLEN_T -DBT_ENABLE_ENET) + ENDIF(BUILD_PYBULLET_ENET) ENDIF(WIN32) @@ -122,6 +126,6 @@ ENDIF(WIN32) -TARGET_LINK_LIBRARIES(pybullet ws2_32 BulletExampleBrowserLib BulletFileLoader BulletWorldImporter BulletSoftBody BulletDynamics BulletCollision BulletInverseDynamicsUtils BulletInverseDynamics LinearMath OpenGLWindow gwen BussIK Bullet3Common ${PYTHON_LIBRARIES}) +TARGET_LINK_LIBRARIES(pybullet BulletExampleBrowserLib BulletFileLoader BulletWorldImporter BulletSoftBody BulletDynamics BulletCollision BulletInverseDynamicsUtils BulletInverseDynamics LinearMath OpenGLWindow gwen BussIK Bullet3Common ${PYTHON_LIBRARIES}) From 5d66ce20e0d8dfec2ad03aa331155347405205f0 Mon Sep 17 00:00:00 2001 From: erwincoumans Date: Fri, 4 Nov 2016 17:06:55 -0700 Subject: [PATCH 04/10] network UDP: transmit structural DNA to deal with version/platform differences. pybullet: allow to specify shared memory key and hostname/port for UDP. --- examples/SharedMemory/PhysicsDirect.cpp | 51 ++++++++++++++++++- .../PhysicsServerCommandProcessor.cpp | 22 ++++++++ examples/SharedMemory/SharedMemoryPublic.h | 3 ++ examples/pybullet/pybullet.c | 49 +++++++++++++++--- src/LinearMath/btSerializer.h | 20 ++++++++ 5 files changed, 135 insertions(+), 10 deletions(-) diff --git a/examples/SharedMemory/PhysicsDirect.cpp b/examples/SharedMemory/PhysicsDirect.cpp index 8b21eeaa3..f513aaeaa 100644 --- a/examples/SharedMemory/PhysicsDirect.cpp +++ b/examples/SharedMemory/PhysicsDirect.cpp @@ -23,6 +23,7 @@ struct PhysicsDirectInternalData { DummyGUIHelper m_noGfx; + btAlignedObjectArray m_serverDNA; SharedMemoryCommand m_command; SharedMemoryStatus m_serverStatus; bool m_hasStatus; @@ -83,6 +84,31 @@ bool PhysicsDirect::connect() { bool connected = m_data->m_commandProcessor->connect(); m_data->m_commandProcessor->setGuiHelper(&m_data->m_noGfx); + + + //also request serialization data + { + SharedMemoryCommand command; + command.m_type = CMD_REQUEST_INTERNAL_DATA; + bool hasStatus = m_data->m_commandProcessor->processCommand(command, m_data->m_serverStatus, &m_data->m_bulletStreamDataServerToClient[0], SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); + if (hasStatus) + { + postProcessStatus(m_data->m_serverStatus); + } + else + { + int timeout = 1024 * 1024 * 1024; + while ((!hasStatus) && (timeout-- > 0)) + { + const SharedMemoryStatus* stat = processServerStatus(); + if (stat) + { + hasStatus = true; + } + } + } + } + return connected; } @@ -444,7 +470,14 @@ void PhysicsDirect::processBodyJointInfo(int bodyUniqueId, const SharedMemorySta bParse::btBulletFile bf( &m_data->m_bulletStreamDataServerToClient[0], serverCmd.m_numDataStreamBytes); - bf.setFileDNAisMemoryDNA(); + if (m_data->m_serverDNA.size()) + { + bf.setFileDNA(false, &m_data->m_serverDNA[0], m_data->m_serverDNA.size()); + } + else + { + bf.setFileDNAisMemoryDNA(); + } bf.parse(false); BodyJointInfoCache2* bodyJoints = new BodyJointInfoCache2; @@ -469,7 +502,8 @@ void PhysicsDirect::processBodyJointInfo(int bodyUniqueId, const SharedMemorySta addJointInfoFromMultiBodyData(mb,bodyJoints, m_data->m_verboseOutput); } } - if (bf.ok()) { + if (bf.ok()) + { if (m_data->m_verboseOutput) { b3Printf("Received robot description ok!\n"); @@ -484,6 +518,19 @@ void PhysicsDirect::postProcessStatus(const struct SharedMemoryStatus& serverCmd { switch (serverCmd.m_type) { + case CMD_REQUEST_INTERNAL_DATA_COMPLETED: + { + if (serverCmd.m_numDataStreamBytes) + { + int numStreamBytes = serverCmd.m_numDataStreamBytes; + m_data->m_serverDNA.resize(numStreamBytes); + for (int i = 0; i < numStreamBytes; i++) + { + m_data->m_serverDNA[i] = m_data->m_bulletStreamDataServerToClient[i]; + } + } + break; + } case CMD_RESET_SIMULATION_COMPLETED: { m_data->m_debugLinesFrom.clear(); diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp index c6f0cf2cb..4df28832c 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp @@ -2178,6 +2178,28 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm break; } + case CMD_REQUEST_INTERNAL_DATA: + { + //todo: also check version etc? + + SharedMemoryStatus& serverCmd = serverStatusOut; + serverCmd.m_type = CMD_REQUEST_INTERNAL_DATA_FAILED; + hasStatus = true; + + int sz = btDefaultSerializer::getMemoryDnaSizeInBytes(); + const char* memDna = btDefaultSerializer::getMemoryDna(); + if (sz < bufferSizeInBytes) + { + for (int i = 0; i < bufferSizeInBytes; i++) + { + bufferServerToClient[i] = memDna[i]; + } + serverCmd.m_type = CMD_REQUEST_INTERNAL_DATA_COMPLETED; + serverCmd.m_numDataStreamBytes = bufferSizeInBytes; + } + + break; + }; case CMD_SEND_PHYSICS_SIMULATION_PARAMETERS: { if (clientCmd.m_updateFlags&SIM_PARAM_UPDATE_DELTA_TIME) diff --git a/examples/SharedMemory/SharedMemoryPublic.h b/examples/SharedMemory/SharedMemoryPublic.h index b435a38a5..7b0a967bc 100644 --- a/examples/SharedMemory/SharedMemoryPublic.h +++ b/examples/SharedMemory/SharedMemoryPublic.h @@ -21,6 +21,7 @@ enum EnumSharedMemoryClientCommand CMD_REQUEST_ACTUAL_STATE, CMD_REQUEST_DEBUG_LINES, CMD_REQUEST_BODY_INFO, + CMD_REQUEST_INTERNAL_DATA, CMD_STEP_FORWARD_SIMULATION, CMD_RESET_SIMULATION, CMD_PICK_BODY, @@ -54,6 +55,8 @@ enum EnumSharedMemoryServerStatus CMD_SDF_LOADING_FAILED, CMD_URDF_LOADING_COMPLETED, CMD_URDF_LOADING_FAILED, + CMD_REQUEST_INTERNAL_DATA_COMPLETED, + CMD_REQUEST_INTERNAL_DATA_FAILED, CMD_BULLET_DATA_STREAM_RECEIVED_COMPLETED, CMD_BULLET_DATA_STREAM_RECEIVED_FAILED, CMD_BOX_COLLISION_SHAPE_CREATION_COMPLETED, diff --git a/examples/pybullet/pybullet.c b/examples/pybullet/pybullet.c index ec69952a6..af8eacdf7 100644 --- a/examples/pybullet/pybullet.c +++ b/examples/pybullet/pybullet.c @@ -61,12 +61,45 @@ static PyObject* pybullet_connectPhysicsServer(PyObject* self, PyObject* args) { { int method = eCONNECT_GUI; - if (!PyArg_ParseTuple(args, "i", &method)) { - PyErr_SetString(SpamError, - "connectPhysicsServer expected argument GUI, " - "DIRECT, SHARED_MEMORY or UDP"); - return NULL; - } + int key = SHARED_MEMORY_KEY; + int port = 1234; + const char* hostName = "localhost"; + + int size = PySequence_Size(args); + if (size == 1) + { + if (!PyArg_ParseTuple(args, "i", &method)) { + PyErr_SetString(SpamError, + "connectPhysicsServer expected argument GUI, " + "DIRECT, SHARED_MEMORY or UDP"); + return NULL; + } + } + + if (size == 2) + { + if (!PyArg_ParseTuple(args, "ii", &method, &key)) + { + if (!PyArg_ParseTuple(args, "is", &method, &hostName)) + { + PyErr_SetString(SpamError, + "connectPhysicsServer cannot parse second argument (either integer or string)"); + return NULL; + + } + } + } + + if (size == 3) + { + if (!PyArg_ParseTuple(args, "isi", &method, &hostName, &port)) + { + PyErr_SetString(SpamError, + "connectPhysicsServer 3 arguments: method, hostname, port"); + return NULL; + } + } + switch (method) { case eCONNECT_GUI: { @@ -85,14 +118,14 @@ static PyObject* pybullet_connectPhysicsServer(PyObject* self, PyObject* args) { break; } case eCONNECT_SHARED_MEMORY: { - sm = b3ConnectSharedMemory(SHARED_MEMORY_KEY); + sm = b3ConnectSharedMemory(key); break; } case eCONNECT_UDP: { #ifdef BT_ENABLE_ENET - sm = b3ConnectPhysicsUDP("localhost", 1234); + sm = b3ConnectPhysicsUDP(hostName, port); #else PyErr_SetString(SpamError, "UDP is not enabled in this pybullet build"); return NULL; diff --git a/src/LinearMath/btSerializer.h b/src/LinearMath/btSerializer.h index 454068d6a..424e0b99c 100644 --- a/src/LinearMath/btSerializer.h +++ b/src/LinearMath/btSerializer.h @@ -446,6 +446,26 @@ public: btAlignedFree(m_dna); } + static int getMemoryDnaSizeInBytes() + { + const bool VOID_IS_8 = ((sizeof(void*) == 8)); + + if (VOID_IS_8) + { + return sBulletDNAlen64; + } + return sBulletDNAlen; + } + static const char* getMemoryDna() + { + const bool VOID_IS_8 = ((sizeof(void*) == 8)); + if (VOID_IS_8) + { + return (const char*)sBulletDNAstr64; + } + return (const char*)sBulletDNAstr; + } + void insertHeader() { writeHeader(m_buffer); From cf21da4c9d42448841948f41fbbdab069a57df38 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Fri, 4 Nov 2016 17:44:16 -0700 Subject: [PATCH 05/10] fix a few issues in UDP networking --- examples/SharedMemory/PhysicsServerCommandProcessor.cpp | 2 +- examples/SharedMemory/SharedMemoryCommands.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp index 4df28832c..763156d86 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp @@ -2195,7 +2195,7 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm bufferServerToClient[i] = memDna[i]; } serverCmd.m_type = CMD_REQUEST_INTERNAL_DATA_COMPLETED; - serverCmd.m_numDataStreamBytes = bufferSizeInBytes; + serverCmd.m_numDataStreamBytes = sz; } break; diff --git a/examples/SharedMemory/SharedMemoryCommands.h b/examples/SharedMemory/SharedMemoryCommands.h index 2cfadeaa7..8680acd18 100644 --- a/examples/SharedMemory/SharedMemoryCommands.h +++ b/examples/SharedMemory/SharedMemoryCommands.h @@ -24,7 +24,7 @@ typedef unsigned long long int smUint64_t; #endif -#define SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE (256*1024) +#define SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE (512*1024) #define SHARED_MEMORY_SERVER_TEST_C #define MAX_DEGREE_OF_FREEDOM 128 From 6ce6157c8a7e5544a6b825fc9c1e3eb1f5e5de20 Mon Sep 17 00:00:00 2001 From: erwincoumans Date: Fri, 4 Nov 2016 20:53:57 -0700 Subject: [PATCH 06/10] fix issue in DNA copy, reduce number of test iterations. --- examples/SharedMemory/PhysicsServerCommandProcessor.cpp | 2 +- test/SharedMemory/test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp index 763156d86..cff5acbd1 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp @@ -2190,7 +2190,7 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm const char* memDna = btDefaultSerializer::getMemoryDna(); if (sz < bufferSizeInBytes) { - for (int i = 0; i < bufferSizeInBytes; i++) + for (int i = 0; i < sz; i++) { bufferServerToClient[i] = memDna[i]; } diff --git a/test/SharedMemory/test.c b/test/SharedMemory/test.c index a1a6591d8..6037b693e 100644 --- a/test/SharedMemory/test.c +++ b/test/SharedMemory/test.c @@ -228,7 +228,7 @@ void testSharedMemory(b3PhysicsClientHandle sm) #endif } ///perform some simulation steps for testing - for ( i=0;i<10000;i++) + for ( i=0;i<1000;i++) { b3SharedMemoryStatusHandle statusHandle; int statusType; From 17f3c40317d793a0fc01ac91ea1bc42866dc37b9 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Fri, 4 Nov 2016 22:30:41 -0700 Subject: [PATCH 07/10] check for basename --- examples/SharedMemory/PhysicsDirect.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/SharedMemory/PhysicsDirect.cpp b/examples/SharedMemory/PhysicsDirect.cpp index f513aaeaa..db408e529 100644 --- a/examples/SharedMemory/PhysicsDirect.cpp +++ b/examples/SharedMemory/PhysicsDirect.cpp @@ -490,15 +490,22 @@ void PhysicsDirect::processBodyJointInfo(int bodyUniqueId, const SharedMemorySta { Bullet::btMultiBodyDoubleData* mb = (Bullet::btMultiBodyDoubleData*)bf.m_multiBodies[i]; - bodyJoints->m_baseName = mb->m_baseName; - + + if (mb->m_baseName) + { + bodyJoints->m_baseName = mb->m_baseName; + } addJointInfoFromMultiBodyData(mb,bodyJoints, m_data->m_verboseOutput); } else { Bullet::btMultiBodyFloatData* mb = (Bullet::btMultiBodyFloatData*)bf.m_multiBodies[i]; - bodyJoints->m_baseName = mb->m_baseName; + + if (mb->m_baseName) + { + bodyJoints->m_baseName = mb->m_baseName; + } addJointInfoFromMultiBodyData(mb,bodyJoints, m_data->m_verboseOutput); } } From 502f4b7d401b78884afc1240238322a623904f41 Mon Sep 17 00:00:00 2001 From: erwincoumans Date: Sat, 5 Nov 2016 11:32:31 -0700 Subject: [PATCH 08/10] update .bullet file --- data/multibody.bullet | Bin 16444 -> 16496 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/multibody.bullet b/data/multibody.bullet index 084ee5a8a525c540e7bc81dce8134f419082cc59..c96db53b5cb53cb6128258c7b04bb07a1ebec1dd 100644 GIT binary patch delta 3991 zcmd^=S#VTU5Qh6CL(a{Fdy}w;ECr^>fG8kYXOc`HfrOoqg?$ZT0#OKHf}#SGDjuv- zRN$f_YLyR&8zLA)P|61Z7Zw41RzY7?;sUs!_?=mbge^t!K#5cJ<(|{se|MjrlRNvG zR7;cE@sdh88vVqHh*`SZ)W%TEc$1!K?bdZq#@+EB=<=2LqU-LG?;-qYcLvdbcH&bn z%d>vx?N&T0<8aedZ+E+A_;q)AS=Jjf{NL-xo9|+2Lf~f4q5D<8MssUC(Oc78ty`4G zgt{5tt?qWahdU%LA^faP>FpMIH@iQ0v(rsL)#&2#Y-AcbgM!#6oS-BrJ(6irQm@Ej zZBlw0sh9XGN(qc8&L{O6Xp)IE4Z8?8{K)vB>@UPH`$*A_TWKd%y6{(Q33BtwyWSYP84vz8Z~IUqhQCagrtL#gPq?%Q~C2&Dt+r>DZN2 z*~tD`cn+S2O|Su8fX(ot*zWW|pFAyFsPrmbZIu8WWuWea+ClB0c2GO0O(h4lgW5su zxH|)VLKbQ(sy5TgqZg072Cqv#Rs8Y>yvcd{VtWg=!P~H%s_(!K);r-{*3CS3NddYb zx?uadP#a+(jRg<}t|GK3XtgS6MGK0&CqpHk!n-N`KJ1ZU>>c(+QGaY-OjLn% z-Ys2ZFML2FAHqKIxTo^ErD@sEc@D_%aM*6%zHnBhSw z5pSDFOFqH(DSQSWLnPMR$5KfOA1PK_6RU~U#A;$=J(~L`+?$b-*e2eV&*}b9h(Cwn z2**1LU&tr|Tes^F=*S^B3>V`@O9zr3Lvx&BC*Vu?O2%Lx6}4N~E$kNdu`=Ka4X8uz zf&yQETfU}=Z|L+}I0>iVJNO_S4V;Kf^EZE6w~S<0y261GvdS zUw?->&Nb>p59!Vf`a%wMoNLq>f5}8OgVGF2Gbr6^P!ld0s70JboJE|~Dz1#d<%cin z8P0dsyf)5pD4$H^SdrU$hK9}}Iw$4WwEPZ#z@O|UN(I-aT>e6Q9{z@Z-~x!!@-lHs zc_a>Uq!NXR^+-HE54H}fik*p#*eeroXf+9$EmqW+h|LR0&@r57vLx_6vXza^7Dojo z8GB0DKSg?wGL>~F2#I^VuqdRZFPn6Ne9#a2!=11~rb!?*t|S*c<1-zpD&B}Y{-dfa(Vh80C|v4Yyp~Jh(#d`g<%+qpqTY=7{R&(N?|07 zg3&Mr-&hz25q~+XVNMnJE3sAaoCK3$3gpNPS~PF&sS=vXD5t3k znXW2j1~Z?@h-azEGFwfPIV7Kppc+hr^Wa{X5BEV0)T$}6K+WWJk|GP0BXw{;JOGPe zv9hF|xFukUFNI~;9)t#Eg`|A ztrBYz@_Po2;R5`Evc8xzGn#WYv+5#`(b!6Au2KP!)pS3DqM>k6b4qi|=P*Fyn}shE NUuQ%%B8|wz{0pH7v(f+n delta 3747 zcma)-3vg7`8G!$rEV-8?yX1jFB*ijGKy5_wBAXXCfdnuT9zh^Hw1|S(`ap^Z#IT_= z^#Q3Ry`X?Xf)lY~G|-5EXg4540zwfxBdsG~olaW@G%Y@`V$<*J-n-qbFzwEK`=9f_ z&wtO}?XK6}s@HZruO*26iL#~Ds;z76aNWBoCfd+?&Y0Do=Dl1n@OS>ZMlINRY1cu& zVsD*|`k_x1jc_uubf2A21Jmbgg+9 zecMNCKJ5C-8&1K<1DTNrvg7@Byh;2JmB5T>!0FNqblDtT>f=};r{?m@V~%$o3T5yA z`sT00j%}*3Ih7e($j>PfF*Z|;&GA={#m?_{bmUJ|1wswXZ)}|3xO1QuZLLbU#oFWY z`c5$n$NlfMl}&%>JQNy=qj%({jq1}CvZpPm%-iuov;V&FM}PhlPtg^1HuH~R@ey`2 z(*8;Ea^L);ox9A{yPt|*&3Q-vV)6T@!V=)1?0(zsx9y?hTqyqQs+m=-{)OvK_M9ND zreW)mBVkX~wwt!ywC$nzb1lAxS8J+T&Gk1uI7cNoGxp^2V_{GATuZ?2x9z5F4^1HA zTB&Q%>sm!z8|T`E8kiToL5^FCV!S@}`0V34<8Y1}sunR0XI!Cd+b+#2eQEbze~~7I zUB{9oq2vL5!_Cn~^@p=dJK~VRU#)5XYQwKrO5kU0-!IetSqAPG*TrzzH=up4-mSUR zEw!>@w^^q(!`hOVWQ~Z539aWQ47N&RH(BRnbJNwhr;ab1oJ+V4$)MS(lqku~8g7-x zrMt35dULJ&<5FEYxtU9>hPd=}Wp+YiSzj>}$6)B?xYSG)AyUtw97K-2H(^vzAN+Rq zR(X62UA9_ljqB{rR|d{#c|9$S9fo&Bc6Zk|=MRK_8F$yc9h>vrXQnjGyKu1K#gN`k z-eJqq#+|9veLaUly;vgP)E|4Qrn3^SHl$Pvw@cKHq0rtBj$& z8_P^+@u?wrzzu4xWPf`dgS^IGE2;dhg#j?oUMrbsuT_UB_F75hcO49ZRC}$YdTvTj zol)`wd!wXs9BfOqS8FAs;ds8ovA1% zmQ_`(Y%fU~s<%IpvM;6I2~D&OQX_k0q5Ms2wx;Ba(OTQr=Ufx5rC6_wtVnaoBjS>! z@F*;U<*)*3Ntq$pl41?YuQ30YUk=kUTJB z;1hXA$|bg!ry&P9(jn-C4%iO|piU|zF3_S=TgO+&SI1Y!SI1Y!SKUnYei+NoQXR?h zcgwqUe;B&ph??Lwcy=q0SS<89bRQ*O?G8QJq2Q3`%EEdf1?xqG`HBp^Mh0vQxf6y$gLG?RKfwQO0ONrH;~oz7QKo zG)-c7Q^jd+bZ&{)ip7oI6R=O`|HCEySSNsbLnb1VH0yFnDKC{Y9Md5KhQd;rA@L*| zrX|V^a3cwCf*%o-iT!364!6JvbOthye~3X`>MZ=TA;*r%Mdras$OkXJ1;i90i=f!Y zR|$$yV6rZSGS;JE43t9!jD>O7#>1^psm-LxzH*z^S0<3S3j0J@#pxztpNwt_vKpqs z?T{z4Xi>e>XUH@rIbE9~z8PAz)G+gz%y^bIO=fE~GKb`M5O60H!;fJu+y(RCZn#IA zF7vh7yiO8if##8WVIkZHKY^cWhTM%0A4%OLb(7RhQa4H6Bvpy@u*5nE`KN=$fdV>7^{|}TcFsGPRexDdV=E|JOP$AP izD667C3S(K>Xhp5`c4L@jB_w%V@oE;O^{BI^7#)8YKDaX From e7cfb656c4b2152f802d6b7e03d0b7ff079f3d15 Mon Sep 17 00:00:00 2001 From: erwincoumans Date: Sat, 5 Nov 2016 11:36:52 -0700 Subject: [PATCH 09/10] update bullet.h serialization header, matching the dna in Bullet/src/LinearMath/btSerialize.cpp --- Extras/Serialize/BulletFileLoader/autogenerated/bullet.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Extras/Serialize/BulletFileLoader/autogenerated/bullet.h b/Extras/Serialize/BulletFileLoader/autogenerated/bullet.h index 49fb0dee0..2e2e8e322 100644 --- a/Extras/Serialize/BulletFileLoader/autogenerated/bullet.h +++ b/Extras/Serialize/BulletFileLoader/autogenerated/bullet.h @@ -553,6 +553,8 @@ typedef struct bInvalidHandle { double m_deactivationTime; double m_friction; double m_rollingFriction; + double m_contactDamping; + double m_contactStiffness; double m_restitution; double m_hitFraction; double m_ccdSweptSphereRadius; @@ -585,6 +587,8 @@ typedef struct bInvalidHandle { float m_deactivationTime; float m_friction; float m_rollingFriction; + float m_contactDamping; + float m_contactStiffness; float m_restitution; float m_hitFraction; float m_ccdSweptSphereRadius; From 214930922d08895f472df539f7f3481e3cf57535 Mon Sep 17 00:00:00 2001 From: erwincoumans Date: Sat, 5 Nov 2016 12:53:40 -0700 Subject: [PATCH 10/10] make sure m_uniqueIdGenerator in btSerializer is initialized to zero, it can cause issues if not. --- .../PhysicsServerCommandProcessor.cpp | 17 +++++++++++++---- src/LinearMath/btSerializer.h | 4 +++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp index cff5acbd1..c6346a554 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp @@ -1036,10 +1036,17 @@ bool PhysicsServerCommandProcessor::loadUrdf(const char* fileName, const btVecto UrdfLinkNameMapUtil* util = new UrdfLinkNameMapUtil; m_data->m_urdfLinkNameMapper.push_back(util); util->m_mb = mb; + for (int i = 0; i < bufferSizeInBytes; i++) + { + bufferServerToClient[i] = 0xcc; + } util->m_memSerializer = new btDefaultSerializer(bufferSizeInBytes ,(unsigned char*)bufferServerToClient); //disable serialization of the collision objects (they are too big, and the client likely doesn't need them); util->m_memSerializer->m_skipPointers.insert(mb->getBaseCollider(),0); + util->m_memSerializer->startSerialization(); + + bodyHandle->m_linkLocalInertialFrames.reserve(mb->getNumLinks()); for (int i=0;igetNumLinks();i++) { @@ -1066,18 +1073,19 @@ bool PhysicsServerCommandProcessor::loadUrdf(const char* fileName, const btVecto std::string* baseName = new std::string(u2b.getLinkName(u2b.getRootLinkIndex())); m_data->m_strings.push_back(baseName); - - util->m_memSerializer->registerNameForPointer(baseName->c_str(),baseName->c_str()); mb->setBaseName(baseName->c_str()); + util->m_memSerializer->registerNameForPointer(baseName->c_str(),baseName->c_str()); - util->m_memSerializer->insertHeader(); + int len = mb->calculateSerializeBufferSize(); btChunk* chunk = util->m_memSerializer->allocate(len,1); const char* structType = mb->serialize(chunk->m_oldPtr, util->m_memSerializer); util->m_memSerializer->finalizeChunk(chunk,structType,BT_MULTIBODY_CODE,mb); + + return true; } else { @@ -1129,6 +1137,8 @@ int PhysicsServerCommandProcessor::createBodyInfoStream(int bodyUniqueId, char* m_data->m_urdfLinkNameMapper.push_back(util); util->m_mb = mb; util->m_memSerializer = new btDefaultSerializer(bufferSizeInBytes ,(unsigned char*)bufferServerToClient); + util->m_memSerializer->startSerialization(); + //disable serialization of the collision objects (they are too big, and the client likely doesn't need them); util->m_memSerializer->m_skipPointers.insert(mb->getBaseCollider(),0); if (mb->getBaseName()) @@ -1147,7 +1157,6 @@ int PhysicsServerCommandProcessor::createBodyInfoStream(int bodyUniqueId, char* util->m_memSerializer->registerNameForPointer(mb->getBaseName(),mb->getBaseName()); - util->m_memSerializer->insertHeader(); int len = mb->calculateSerializeBufferSize(); btChunk* chunk = util->m_memSerializer->allocate(len,1); diff --git a/src/LinearMath/btSerializer.h b/src/LinearMath/btSerializer.h index 424e0b99c..6f03df158 100644 --- a/src/LinearMath/btSerializer.h +++ b/src/LinearMath/btSerializer.h @@ -391,7 +391,8 @@ public: btDefaultSerializer(int totalSize=0, unsigned char* buffer=0) - :m_totalSize(totalSize), + :m_uniqueIdGenerator(0), + m_totalSize(totalSize), m_currentSize(0), m_dna(0), m_dnaLength(0), @@ -561,6 +562,7 @@ public: virtual void* getUniquePointer(void*oldPtr) { + btAssert(m_uniqueIdGenerator >= 0); if (!oldPtr) return 0;