* Adjustment: Update Bullet version to 3.24.

This commit is contained in:
Robert MacGregor 2022-06-27 10:01:08 -04:00
parent 35de012ee7
commit 4a3f31df2a
6148 changed files with 2112532 additions and 56873 deletions

View file

@ -0,0 +1,121 @@
#ifndef BODY_JOINT_INFO_UTILITY_H
#define BODY_JOINT_INFO_UTILITY_H
#include "Bullet3Common/b3Logging.h"
namespace Bullet
{
class btMultiBodyDoubleData;
class btMultiBodyFloatData;
}; // namespace Bullet
inline char* strDup(const char* const str)
{
#ifdef _WIN32
return _strdup(str);
#else
return strdup(str);
#endif
}
template <typename T, typename U>
void addJointInfoFromMultiBodyData(const T* mb, U* bodyJoints, bool verboseOutput)
{
int numDofs = 0;
if (mb->m_baseMass>0)
{
numDofs = 6;
}
if (mb->m_baseName)
{
if (verboseOutput)
{
b3Printf("mb->m_baseName = %s\n", mb->m_baseName);
}
}
int qOffset = 7;
int uOffset = 6;
for (int link = 0; link < mb->m_numLinks; link++)
{
{
b3JointInfo info;
info.m_jointName[0] = 0;
info.m_linkName[0] = 0;
info.m_flags = 0;
info.m_jointIndex = link;
info.m_qIndex =
(0 < mb->m_links[link].m_posVarCount) ? qOffset : -1;
info.m_uIndex =
(0 < mb->m_links[link].m_dofCount) ? uOffset : -1;
if (mb->m_links[link].m_linkName)
{
if (verboseOutput)
{
b3Printf("mb->m_links[%d].m_linkName = %s\n", link,
mb->m_links[link].m_linkName);
}
strcpy(info.m_linkName, mb->m_links[link].m_linkName);
}
if (mb->m_links[link].m_jointName)
{
if (verboseOutput)
{
b3Printf("mb->m_links[%d].m_jointName = %s\n", link,
mb->m_links[link].m_jointName);
}
strcpy(info.m_jointName, mb->m_links[link].m_jointName);
//info.m_jointName = strDup(mb->m_links[link].m_jointName);
}
info.m_jointType = mb->m_links[link].m_jointType;
info.m_jointDamping = mb->m_links[link].m_jointDamping;
info.m_jointFriction = mb->m_links[link].m_jointFriction;
info.m_jointLowerLimit = mb->m_links[link].m_jointLowerLimit;
info.m_jointUpperLimit = mb->m_links[link].m_jointUpperLimit;
info.m_jointMaxForce = mb->m_links[link].m_jointMaxForce;
info.m_jointMaxVelocity = mb->m_links[link].m_jointMaxVelocity;
info.m_parentFrame[0] = mb->m_links[link].m_parentComToThisPivotOffset.m_floats[0];
info.m_parentFrame[1] = mb->m_links[link].m_parentComToThisPivotOffset.m_floats[1];
info.m_parentFrame[2] = mb->m_links[link].m_parentComToThisPivotOffset.m_floats[2];
info.m_parentFrame[3] = mb->m_links[link].m_zeroRotParentToThis.m_floats[0];
info.m_parentFrame[4] = mb->m_links[link].m_zeroRotParentToThis.m_floats[1];
info.m_parentFrame[5] = mb->m_links[link].m_zeroRotParentToThis.m_floats[2];
info.m_parentFrame[6] = mb->m_links[link].m_zeroRotParentToThis.m_floats[3];
info.m_jointAxis[0] = 0;
info.m_jointAxis[1] = 0;
info.m_jointAxis[2] = 0;
info.m_parentIndex = mb->m_links[link].m_parentIndex;
if (info.m_jointType == eRevoluteType)
{
info.m_jointAxis[0] = mb->m_links[link].m_jointAxisTop[0].m_floats[0];
info.m_jointAxis[1] = mb->m_links[link].m_jointAxisTop[0].m_floats[1];
info.m_jointAxis[2] = mb->m_links[link].m_jointAxisTop[0].m_floats[2];
}
if (info.m_jointType == ePrismaticType)
{
info.m_jointAxis[0] = mb->m_links[link].m_jointAxisBottom[0].m_floats[0];
info.m_jointAxis[1] = mb->m_links[link].m_jointAxisBottom[0].m_floats[1];
info.m_jointAxis[2] = mb->m_links[link].m_jointAxisBottom[0].m_floats[2];
}
if ((mb->m_links[link].m_jointType == eRevoluteType) ||
(mb->m_links[link].m_jointType == ePrismaticType))
{
info.m_flags |= JOINT_HAS_MOTORIZED_POWER;
}
bodyJoints->m_jointInfo.push_back(info);
}
qOffset += mb->m_links[link].m_posVarCount;
uOffset += mb->m_links[link].m_dofCount;
numDofs += mb->m_links[link].m_dofCount;
}
bodyJoints->m_numDofs = numDofs;
}
#endif //BODY_JOINT_INFO_UTILITY_H

View file

@ -0,0 +1,420 @@
SET(SharedMemory_SRCS
plugins/collisionFilterPlugin/collisionFilterPlugin.cpp
plugins/collisionFilterPlugin/collisionFilterPlugin.h
plugins/pdControlPlugin/pdControlPlugin.cpp
plugins/pdControlPlugin/pdControlPlugin.h
b3RobotSimulatorClientAPI_NoDirect.cpp
b3RobotSimulatorClientAPI_NoDirect.h
IKTrajectoryHelper.cpp
IKTrajectoryHelper.h
PhysicsClient.cpp
PhysicsClientSharedMemory.cpp
PhysicsClientExample.cpp
PhysicsServerExample.cpp
PhysicsServerExampleBullet2.cpp
PhysicsServerSharedMemory.cpp
PhysicsServerSharedMemory.h
PhysicsServer.cpp
PhysicsServer.h
PhysicsClientC_API.cpp
GraphicsClientExample.cpp
GraphicsClientExample.h
GraphicsServerExample.cpp
GraphicsServerExample.h
GraphicsSharedMemoryBlock.h
GraphicsSharedMemoryCommands.h
GraphicsSharedMemoryPublic.h
SharedMemoryCommands.h
SharedMemoryPublic.h
PhysicsServer.cpp
PosixSharedMemory.cpp
Win32SharedMemory.cpp
InProcessMemory.cpp
PhysicsDirect.cpp
PhysicsDirect.h
PhysicsDirectC_API.cpp
PhysicsDirectC_API.h
PhysicsLoopBack.cpp
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
plugins/tinyRendererPlugin/tinyRendererPlugin.cpp
plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp
SharedMemoryCommands.h
SharedMemoryPublic.h
b3PluginManager.cpp
../TinyRenderer/geometry.cpp
../TinyRenderer/model.cpp
../TinyRenderer/tgaimage.cpp
../TinyRenderer/our_gl.cpp
../TinyRenderer/TinyRenderer.cpp
../OpenGLWindow/SimpleCamera.cpp
../OpenGLWindow/SimpleCamera.h
../Importers/ImportURDFDemo/ConvertRigidBodies2MultiBody.h
../Importers/ImportURDFDemo/MultiBodyCreationInterface.h
../Importers/ImportURDFDemo/MyMultiBodyCreator.cpp
../Importers/ImportURDFDemo/MyMultiBodyCreator.h
../Importers/ImportURDFDemo/BulletUrdfImporter.cpp
../Importers/ImportURDFDemo/BulletUrdfImporter.h
../Importers/ImportURDFDemo/UrdfParser.cpp
../Importers/ImportURDFDemo/urdfStringSplit.cpp
../Importers/ImportURDFDemo/UrdfParser.cpp
../Importers/ImportURDFDemo/UrdfParser.h
../Importers/ImportURDFDemo/URDF2Bullet.cpp
../Importers/ImportURDFDemo/URDF2Bullet.h
../Importers/ImportMJCFDemo/BulletMJCFImporter.cpp
../Importers/ImportMJCFDemo/BulletMJCFImporter.h
../Utils/b3ResourcePath.cpp
../Utils/b3Clock.cpp
../Utils/RobotLoggingUtil.cpp
../Utils/RobotLoggingUtil.h
../Utils/ChromeTraceUtil.cpp
../Utils/ChromeTraceUtil.h
../Importers/ImportURDFDemo/URDFImporterInterface.h
../Importers/ImportURDFDemo/URDFJointTypes.h
../Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp
../Importers/ImportObjDemo/LoadMeshFromObj.cpp
../Importers/ImportSTLDemo/ImportSTLSetup.h
../Importers/ImportSTLDemo/LoadMeshFromSTL.h
../Importers/ImportColladaDemo/LoadMeshFromCollada.cpp
../Importers/ImportColladaDemo/ColladaGraphicsInstance.h
../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp
../ThirdPartyLibs/tinyxml2/tinyxml2.cpp
../Importers/ImportMeshUtility/b3ImportMeshUtility.cpp
../ThirdPartyLibs/stb_image/stb_image.cpp
../MultiThreading/b3ThreadSupportInterface.cpp
../MultiThreading/b3ThreadSupportInterface.h
)
INCLUDE_DIRECTORIES(
${BULLET_PHYSICS_SOURCE_DIR}/src
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs
)
IF (USE_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD)
LINK_LIBRARIES(BulletSoftBody)
ENDIF()
LINK_LIBRARIES(
Bullet3Common BulletWorldImporter BulletFileLoader BulletInverseDynamicsUtils BulletInverseDynamics BulletDynamics BulletCollision LinearMath BussIK
)
IF (WIN32)
ADD_EXECUTABLE(App_PhysicsServer_SharedMemory
${SharedMemory_SRCS}
main.cpp
../MultiThreading/b3Win32ThreadSupport.cpp
../MultiThreading/b3Win32ThreadSupport.h
${BULLET_PHYSICS_SOURCE_DIR}/build3/bullet.rc
)
ELSE(WIN32)
FIND_PACKAGE(Threads)
LINK_LIBRARIES( ${CMAKE_THREAD_LIBS_INIT} ${DL} )
IF(APPLE)
ADD_EXECUTABLE(App_PhysicsServer_SharedMemory
${SharedMemory_SRCS}
../MultiThreading/b3PosixThreadSupport.cpp
../MultiThreading/b3PosixThreadSupport.h
main.cpp
)
ELSE(APPLE)
ADD_EXECUTABLE(App_PhysicsServer_SharedMemory
${SharedMemory_SRCS}
../MultiThreading/b3PosixThreadSupport.cpp
../MultiThreading/b3PosixThreadSupport.h
main.cpp
)
ENDIF(APPLE)
ENDIF(WIN32)
IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
SET_TARGET_PROPERTIES(App_PhysicsServer_SharedMemory PROPERTIES DEBUG_POSTFIX "_Debug")
SET_TARGET_PROPERTIES(App_PhysicsServer_SharedMemory PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel")
SET_TARGET_PROPERTIES(App_PhysicsServer_SharedMemory PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo")
ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
INCLUDE_DIRECTORIES(
${BULLET_PHYSICS_SOURCE_DIR}/src
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/glad
)
ADD_DEFINITIONS(-DB3_USE_STANDALONE_EXAMPLE)
LINK_LIBRARIES(
BulletSoftBody Bullet3Common BulletWorldImporter BulletInverseDynamicsUtils BulletInverseDynamics BulletDynamics BulletCollision LinearMath BussIK OpenGLWindow
)
IF (WIN32)
ADD_DEFINITIONS(-DGLEW_STATIC)
LINK_LIBRARIES( ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} )
ADD_EXECUTABLE(App_PhysicsServer_SharedMemory_GUI
${SharedMemory_SRCS}
../StandaloneMain/main_opengl_single_example.cpp
../ExampleBrowser/OpenGLGuiHelper.cpp
../ExampleBrowser/GL_ShapeDrawer.cpp
../ExampleBrowser/CollisionShape2TriangleMesh.cpp
../MultiThreading/b3Win32ThreadSupport.cpp
../MultiThreading/b3Win32ThreadSupport.h
${BULLET_PHYSICS_SOURCE_DIR}/build3/bullet.rc
)
ELSE(WIN32)
FIND_PACKAGE(Threads)
LINK_LIBRARIES( ${CMAKE_THREAD_LIBS_INIT} ${DL} )
IF(APPLE)
FIND_LIBRARY(COCOA NAMES Cocoa)
MESSAGE(${COCOA})
LINK_LIBRARIES(${COCOA} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY})
ADD_EXECUTABLE(App_PhysicsServer_SharedMemory_GUI
${SharedMemory_SRCS}
../StandaloneMain/main_opengl_single_example.cpp
../ExampleBrowser/OpenGLGuiHelper.cpp
../ExampleBrowser/GL_ShapeDrawer.cpp
../ExampleBrowser/CollisionShape2TriangleMesh.cpp
../MultiThreading/b3PosixThreadSupport.cpp
../MultiThreading/b3PosixThreadSupport.h
)
ELSE(APPLE)
ADD_DEFINITIONS("-DGLEW_INIT_OPENGL11_FUNCTIONS=1")
ADD_DEFINITIONS("-DGLEW_STATIC")
ADD_DEFINITIONS("-DGLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS=1")
ADD_EXECUTABLE(App_PhysicsServer_SharedMemory_GUI
${SharedMemory_SRCS}
../StandaloneMain/main_opengl_single_example.cpp
../ExampleBrowser/OpenGLGuiHelper.cpp
../ExampleBrowser/GL_ShapeDrawer.cpp
../ExampleBrowser/CollisionShape2TriangleMesh.cpp
../MultiThreading/b3PosixThreadSupport.cpp
../MultiThreading/b3PosixThreadSupport.h
)
ENDIF(APPLE)
ENDIF(WIN32)
IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
SET_TARGET_PROPERTIES(App_PhysicsServer_SharedMemory_GUI PROPERTIES DEBUG_POSTFIX "_Debug")
SET_TARGET_PROPERTIES(App_PhysicsServer_SharedMemory_GUI PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel")
SET_TARGET_PROPERTIES(App_PhysicsServer_SharedMemory_GUI PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo")
ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
#VR/OpenVR on Windows and Mac OSX
IF(USE_OPENVR)
IF (WIN32 OR APPLE)
INCLUDE_DIRECTORIES(
${BULLET_PHYSICS_SOURCE_DIR}/src
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/glad
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/openvr/headers
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/openvr/samples/shared
)
LINK_LIBRARIES(
Bullet3Common BulletWorldImporter BulletInverseDynamicsUtils BulletInverseDynamics BulletDynamics BulletCollision LinearMath BussIK openvr_api OpenGLWindow
)
ADD_DEFINITIONS(-DGLEW_STATIC)
LINK_LIBRARIES( ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} )
IF(WIN32)
SET(Platform_SRCS
../MultiThreading/b3Win32ThreadSupport.cpp
../MultiThreading/b3Win32ThreadSupport.h
${BULLET_PHYSICS_SOURCE_DIR}/build3/bullet.rc
)
IF (CMAKE_CL_64)
LINK_DIRECTORIES(${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/openvr/lib/win64)
ELSE(CMAKE_CL_64)
LINK_DIRECTORIES(${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/openvr/lib/win32)
ENDIF(CMAKE_CL_64)
ELSE(WIN32)
set_source_files_properties(../ThirdPartyLibs/openvr/samples/shared/pathtools.cpp ../StandaloneMain/hellovr_opengl_main.cpp PROPERTIES COMPILE_FLAGS "-x objective-c++")
find_library(FOUNDATION_FRAMEWORK Foundation)
mark_as_advanced(FOUNDATION_FRAMEWORK)
set(EXTRA_LIBS ${EXTRA_LIBS} ${FOUNDATION_FRAMEWORK})
set(CMAKE_MACOSX_RPATH 0)
SET(Platform_SRCS
../MultiThreading/b3PosixThreadSupport.cpp
../MultiThreading/b3PosixThreadSupport.h
)
IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
MESSAGE("CL64")
LINK_DIRECTORIES(${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/openvr/bin/osx64)
ELSE()
MESSAGE("CL32")
set(ARCH_TARGET osx32)
LINK_DIRECTORIES(${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/openvr/bin/osx32)
ENDIF()
add_definitions(-DOSX -DPOSIX)
ENDIF(WIN32)
ADD_EXECUTABLE(App_PhysicsServer_SharedMemory_VR
${SharedMemory_SRCS}
${Platform_SRCS}
../StandaloneMain/hellovr_opengl_main.cpp
../ExampleBrowser/OpenGLGuiHelper.cpp
../ExampleBrowser/GL_ShapeDrawer.cpp
../ExampleBrowser/CollisionShape2TriangleMesh.cpp
../RenderingExamples/TinyVRGui.cpp
../RenderingExamples/TimeSeriesCanvas.cpp
../RenderingExamples/TimeSeriesFontData.cpp
../ThirdPartyLibs/openvr/samples/shared/lodepng.cpp
../ThirdPartyLibs/openvr/samples/shared/lodepng.h
../ThirdPartyLibs/openvr/samples/shared/Matrices.cpp
../ThirdPartyLibs/openvr/samples/shared/Matrices.h
../ThirdPartyLibs/openvr/samples/shared/pathtools.cpp
../ThirdPartyLibs/openvr/samples/shared/pathtools.h
../ThirdPartyLibs/openvr/samples/shared/strtools.cpp
../ThirdPartyLibs/openvr/samples/shared/strtools.h
../ThirdPartyLibs/openvr/samples/shared/Vectors.h
)
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
IF (CMAKE_CL_64)
ADD_CUSTOM_COMMAND(
TARGET App_PhysicsServer_SharedMemory_VR
POST_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/openvr/bin/win64/openvr_api.dll ${CMAKE_CURRENT_BINARY_DIR}/openvr64pi.dll
)
ELSE(CMAKE_CL_64)
ADD_CUSTOM_COMMAND(
TARGET App_PhysicsServer_SharedMemory_VR
POST_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/openvr/bin/win32/openvr_api.dll ${CMAKE_CURRENT_BINARY_DIR}/openvr_api.dll
)
ENDIF(CMAKE_CL_64)
ADD_CUSTOM_COMMAND(
TARGET App_PhysicsServer_SharedMemory_VR
POST_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_directory ${BULLET_PHYSICS_SOURCE_DIR}/data ${PROJECT_BINARY_DIR}/data
)
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
SET_TARGET_PROPERTIES(App_PhysicsServer_SharedMemory_VR PROPERTIES COMPILE_DEFINITIONS BT_ENABLE_VR )
IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
SET_TARGET_PROPERTIES(App_PhysicsServer_SharedMemory_VR PROPERTIES DEBUG_POSTFIX "_Debug")
SET_TARGET_PROPERTIES(App_PhysicsServer_SharedMemory_VR PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel")
SET_TARGET_PROPERTIES(App_PhysicsServer_SharedMemory_VR PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo")
ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
#VR/OpenVR on Linux
ELSE(WIN32 OR APPLE)
IF(CMAKE_SIZEOF_VOID_P MATCHES 8)
LINK_DIRECTORIES(${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/openvr/bin/linux64)
ELSE()
LINK_DIRECTORIES(${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/openvr/bin/linux32)
ENDIF()
ADD_EXECUTABLE(App_PhysicsServer_SharedMemory_VR
${SharedMemory_SRCS}
../StandaloneMain/hellovr_opengl_main.cpp
../ExampleBrowser/OpenGLGuiHelper.cpp
../ExampleBrowser/GL_ShapeDrawer.cpp
../ExampleBrowser/CollisionShape2TriangleMesh.cpp
../RenderingExamples/TinyVRGui.cpp
../RenderingExamples/TinyVRGui.h
../RenderingExamples/TimeSeriesCanvas.cpp
../RenderingExamples/TimeSeriesFontData.cpp
../MultiThreading/b3PosixThreadSupport.cpp
../MultiThreading/b3PosixThreadSupport.h
../ThirdPartyLibs/openvr/samples/shared/lodepng.cpp
../ThirdPartyLibs/openvr/samples/shared/lodepng.h
../ThirdPartyLibs/openvr/samples/shared/Matrices.cpp
../ThirdPartyLibs/openvr/samples/shared/Matrices.h
../ThirdPartyLibs/openvr/samples/shared/pathtools.cpp
../ThirdPartyLibs/openvr/samples/shared/pathtools.h
../ThirdPartyLibs/openvr/samples/shared/strtools.cpp
../ThirdPartyLibs/openvr/samples/shared/strtools.h
../ThirdPartyLibs/openvr/samples/shared/Vectors.h
)
target_include_directories(App_PhysicsServer_SharedMemory_VR PRIVATE
${BULLET_PHYSICS_SOURCE_DIR}/src
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/Glew
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/openvr/headers
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/openvr/samples
${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs/openvr/samples/shared
)
target_compile_definitions(App_PhysicsServer_SharedMemory_VR PRIVATE
POSIX
LINUX
BT_ENABLE_VR
GLEW_STATIC
GLEW_INIT_OPENGL11_FUNCTIONS=1
GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS=1
)
target_compile_options(App_PhysicsServer_SharedMemory_VR PRIVATE
-std=c++11
)
FIND_PACKAGE(Threads)
target_link_libraries(App_PhysicsServer_SharedMemory_VR PRIVATE
openvr_api
${CMAKE_THREAD_LIBS_INIT}
${DL}
Bullet3Common
BulletWorldImporter
BulletInverseDynamicsUtils
BulletInverseDynamics
BulletDynamics
BulletCollision
LinearMath
BussIK
OpenGLWindow
)
IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
SET_TARGET_PROPERTIES(App_PhysicsServer_SharedMemory_VR PROPERTIES DEBUG_POSTFIX "_Debug")
SET_TARGET_PROPERTIES(App_PhysicsServer_SharedMemory_VR PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel")
SET_TARGET_PROPERTIES(App_PhysicsServer_SharedMemory_VR PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo")
ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
ENDIF(WIN32 OR APPLE)
ENDIF(USE_OPENVR)

View file

@ -0,0 +1,287 @@
#include "GraphicsClientExample.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "Bullet3Common/b3Logging.h"
#include "GraphicsSharedMemoryCommands.h"
#include "PosixSharedMemory.h"
#include "Win32SharedMemory.h"
#include "GraphicsSharedMemoryBlock.h"
#include "Bullet3Common/b3Scalar.h"
class GraphicsClientExample : public CommonExampleInterface
{
protected:
GUIHelperInterface* m_guiHelper;
bool m_waitingForServer;
GraphicsSharedMemoryBlock* m_testBlock1;
SharedMemoryInterface* m_sharedMemory;
GraphicsSharedMemoryStatus m_lastServerStatus;
int m_sharedMemoryKey;
bool m_isConnected;
public:
GraphicsClientExample(GUIHelperInterface* helper, int options);
virtual ~GraphicsClientExample();
virtual void initPhysics();
virtual void stepSimulation(float deltaTime);
virtual void resetCamera()
{
float dist = 3.45;
float pitch = -16.2;
float yaw = 287;
float targetPos[3] = {2.05, 0.02, 0.53}; //-3,2.8,-2.5};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
virtual bool isConnected()
{
return m_isConnected;
}
bool canSubmitCommand() const
{
if (m_isConnected && !m_waitingForServer)
{
if (m_testBlock1->m_magicId == GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER)
{
return true;
}
else
{
return false;
}
}
return false;
}
struct GraphicsSharedMemoryCommand* getAvailableSharedMemoryCommand()
{
static int sequence = 0;
if (m_testBlock1)
{
m_testBlock1->m_clientCommands[0].m_sequenceNumber = sequence++;
return &m_testBlock1->m_clientCommands[0];
}
return 0;
}
bool submitClientCommand(const GraphicsSharedMemoryCommand& command)
{
/// at the moment we allow a maximum of 1 outstanding command, so we check for this
// once the server processed the command and returns a status, we clear the flag
// "m_data->m_waitingForServer" and allow submitting the next command
if (!m_waitingForServer)
{
//printf("submit command of type %d\n", command.m_type);
if (&m_testBlock1->m_clientCommands[0] != &command)
{
m_testBlock1->m_clientCommands[0] = command;
}
m_testBlock1->m_numClientCommands++;
m_waitingForServer = true;
return true;
}
return false;
}
const GraphicsSharedMemoryStatus* processServerStatus()
{
// SharedMemoryStatus* stat = 0;
if (!m_testBlock1)
{
m_lastServerStatus.m_type = GFX_CMD_SHARED_MEMORY_NOT_INITIALIZED;
return &m_lastServerStatus;
}
if (!m_waitingForServer)
{
return 0;
}
if (m_testBlock1->m_magicId != GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER)
{
m_lastServerStatus.m_type = GFX_CMD_SHARED_MEMORY_NOT_INITIALIZED;
return &m_lastServerStatus;
}
if (m_testBlock1->m_numServerCommands >
m_testBlock1->m_numProcessedServerCommands)
{
B3_PROFILE("processServerCMD");
b3Assert(m_testBlock1->m_numServerCommands ==
m_testBlock1->m_numProcessedServerCommands + 1);
const GraphicsSharedMemoryStatus& serverCmd = m_testBlock1->m_serverCommands[0];
m_lastServerStatus = serverCmd;
// EnumSharedMemoryServerStatus s = (EnumSharedMemoryServerStatus)serverCmd.m_type;
// consume the command
switch (serverCmd.m_type)
{
case GFX_CMD_CLIENT_COMMAND_COMPLETED:
{
B3_PROFILE("CMD_CLIENT_COMMAND_COMPLETED");
break;
}
default:
{
}
}
m_testBlock1->m_numProcessedServerCommands++;
// we don't have more than 1 command outstanding (in total, either server or client)
b3Assert(m_testBlock1->m_numProcessedServerCommands ==
m_testBlock1->m_numServerCommands);
if (m_testBlock1->m_numServerCommands ==
m_testBlock1->m_numProcessedServerCommands)
{
m_waitingForServer = false;
}
else
{
m_waitingForServer = true;
}
return &m_lastServerStatus;
}
return 0;
}
bool connect()
{
/// server always has to create and initialize shared memory
bool allowCreation = false;
m_testBlock1 = (GraphicsSharedMemoryBlock*)m_sharedMemory->allocateSharedMemory(
m_sharedMemoryKey, GRAPHICS_SHARED_MEMORY_SIZE, allowCreation);
if (m_testBlock1)
{
if (m_testBlock1->m_magicId != GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER)
{
b3Error("Error connecting to shared memory: please start server before client\n");
m_sharedMemory->releaseSharedMemory(m_sharedMemoryKey,
GRAPHICS_SHARED_MEMORY_SIZE);
m_testBlock1 = 0;
return false;
}
else
{
m_isConnected = true;
}
}
else
{
b3Warning("Cannot connect to shared memory");
return false;
}
return true;
}
void disconnect()
{
if (m_isConnected && m_sharedMemory)
{
m_sharedMemory->releaseSharedMemory(m_sharedMemoryKey, GRAPHICS_SHARED_MEMORY_SIZE);
}
m_isConnected = false;
}
virtual void exitPhysics(){};
virtual void physicsDebugDraw(int debugFlags)
{
}
virtual void renderScene()
{
}
virtual bool mouseMoveCallback(float x, float y)
{
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
return false;
}
virtual bool keyboardCallback(int key, int state)
{
return false;
}
};
GraphicsClientExample::GraphicsClientExample(GUIHelperInterface* helper, int options)
: m_guiHelper(helper),
m_waitingForServer(false),
m_testBlock1(0)
{
#ifdef _WIN32
m_sharedMemory = new Win32SharedMemoryClient();
#else
m_sharedMemory = new PosixSharedMemory();
#endif
m_sharedMemoryKey = GRAPHICS_SHARED_MEMORY_KEY;
m_isConnected = false;
b3Printf("Started GraphicsClientExample\n");
connect();
}
GraphicsClientExample::~GraphicsClientExample()
{
disconnect();
delete m_sharedMemory;
}
void GraphicsClientExample::initPhysics()
{
if (m_guiHelper && m_guiHelper->getParameterInterface())
{
int upAxis = 2;
m_guiHelper->setUpAxis(upAxis);
}
}
void GraphicsClientExample::stepSimulation(float deltaTime)
{
GraphicsSharedMemoryCommand* cmd = getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_updateFlags = 0;
cmd->m_type = GFX_CMD_0;
submitClientCommand(*cmd);
}
const GraphicsSharedMemoryStatus* status = processServerStatus();
if (status)
{
//handle it
}
}
class CommonExampleInterface* GraphicsClientCreateFunc(struct CommonExampleOptions& options)
{
GraphicsClientExample* example = new GraphicsClientExample(options.m_guiHelper, options.m_option);
return example;
}

View file

@ -0,0 +1,7 @@
#ifndef GRAPHICS_CLIENT_EXAMPLE_H
#define GRAPHICS_CLIENT_EXAMPLE_H
class CommonExampleInterface* GraphicsClientCreateFunc(struct CommonExampleOptions& options);
#endif //GRAPHICS_CLIENT_EXAMPLE_H

View file

@ -0,0 +1,982 @@
#include "GraphicsServerExample.h"
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
#include "PosixSharedMemory.h"
#include "Win32SharedMemory.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "LinearMath/btTransform.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "GraphicsSharedMemoryBlock.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "SharedMemoryPublic.h"
#include "../MultiThreading/b3ThreadSupportInterface.h"
#include "../Utils/b3Clock.h"
#ifdef BT_ENABLE_CLSOCKET
#include "PassiveSocket.h" // Include header for active socket object definition
#include <stdio.h>
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "Bullet3Common/b3CommandLineArgs.h"
#include "RemoteGUIHelper.h"
#include "GraphicsSharedMemoryPublic.h"
#include "GraphicsSharedMemoryCommands.h"
bool gVerboseNetworkMessagesServer = true;
void MySerializeInt(unsigned int sz, unsigned char* output)
{
unsigned int tmp = sz;
output[0] = tmp & 255;
tmp = tmp >> 8;
output[1] = tmp & 255;
tmp = tmp >> 8;
output[2] = tmp & 255;
tmp = tmp >> 8;
output[3] = tmp & 255;
}
void submitStatus(CActiveSocket* pClient, GraphicsSharedMemoryStatus& serverStatus, b3AlignedObjectArray<char>& buffer)
{
b3AlignedObjectArray<unsigned char> packetData;
unsigned char* statBytes = (unsigned char*)&serverStatus;
//create packetData with [int packetSizeInBytes, status, streamBytes)
packetData.resize(4 + sizeof(GraphicsSharedMemoryStatus) + serverStatus.m_numDataStreamBytes);
int sz = packetData.size();
int curPos = 0;
if (gVerboseNetworkMessagesServer)
{
printf("buffer.size = %d\n", buffer.size());
printf("serverStatus packed size = %d\n", sz);
}
MySerializeInt(sz, &packetData[curPos]);
curPos += 4;
for (int i = 0; i < sizeof(GraphicsSharedMemoryStatus); i++)
{
packetData[i + curPos] = statBytes[i];
}
curPos += sizeof(GraphicsSharedMemoryStatus);
if (gVerboseNetworkMessagesServer)
printf("serverStatus.m_numDataStreamBytes=%d\n", serverStatus.m_numDataStreamBytes);
for (int i = 0; i < serverStatus.m_numDataStreamBytes; i++)
{
packetData[i + curPos] = buffer[i];
}
pClient->Send(&packetData[0], packetData.size());
if (gVerboseNetworkMessagesServer)
printf("pClient->Send serverStatus: %d\n", packetData.size());
}
#endif //BT_ENABLE_CLSOCKET
#define MAX_GRAPHICS_SHARED_MEMORY_BLOCKS 1
struct TCPArgs
{
TCPArgs()
: m_cs(0),
m_port(6667),
m_numClientCommands(0),
m_numServerCommands(0),
m_cmdPtr(0)
{
m_dataSlots.resize(10);
}
void submitCommand()
{
m_cs->lock();
m_serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_FAILED;
m_serverStatus.m_numDataStreamBytes = 0;
btAssert(m_numServerCommands == m_numClientCommands);
m_numClientCommands++;
m_cs->unlock();
}
void processCommand()
{
m_cs->lock();
btAssert(m_numServerCommands == (m_numClientCommands - 1));
m_numServerCommands++;
m_cs->unlock();
}
bool isCommandOutstanding()
{
m_cs->lock();
bool result = m_numClientCommands > m_numServerCommands;
m_cs->unlock();
return result;
}
b3CriticalSection* m_cs;
int m_port;
b3AlignedObjectArray< b3AlignedObjectArray<unsigned char> > m_dataSlots;
int m_numClientCommands;
int m_numServerCommands;
GraphicsSharedMemoryCommand* m_cmdPtr;
GraphicsSharedMemoryStatus m_serverStatus;
};
struct TCPThreadLocalStorage
{
int threadId;
};
enum TCPCommunicationEnums
{
eTCPRequestTerminate = 11,
eTCPIsUnInitialized,
eTCPIsInitialized,
eTCPInitializationFailed,
eTCPHasTerminated
};
void TCPThreadFunc(void* userPtr, void* lsMemory)
{
printf("TCPThreadFunc thread started\n");
TCPArgs* args = (TCPArgs*)userPtr;
//int workLeft = true;
b3Clock clock;
clock.reset();
b3Clock sleepClock;
bool init = true;
if (init)
{
unsigned int cachedSharedParam = eTCPIsInitialized;
args->m_cs->lock();
args->m_cs->setSharedParam(0, eTCPIsInitialized);
args->m_cs->unlock();
double deltaTimeInSeconds = 0;
int numCmdSinceSleep1ms = 0;
unsigned long long int prevTime = clock.getTimeMicroseconds();
#ifdef BT_ENABLE_CLSOCKET
b3Clock clock;
double timeOutInSeconds = 10;
bool isPhysicsClientConnected = true;
bool exitRequested = false;
if (!isPhysicsClientConnected)
{
printf("TCP thread error connecting to shared memory. Machine needs a reboot?\n");
}
btAssert(isPhysicsClientConnected);
printf("Starting TCP server using port %d\n", args->m_port);
CPassiveSocket socket;
CActiveSocket* pClient = NULL;
//--------------------------------------------------------------------------
// Initialize our socket object
//--------------------------------------------------------------------------
socket.Initialize();
socket.Listen("localhost", args->m_port);
socket.SetBlocking();
int curNumErr = 0;
#endif
do
{
{
b3Clock::usleep(0);
}
///////////////////////////////
#ifdef BT_ENABLE_CLSOCKET
{
b3Clock::usleep(0);
if ((pClient = socket.Accept()) != NULL)
{
socket.SetReceiveTimeout(60, 0);// (1, 0);
socket.SetSendTimeout(60, 0);
b3AlignedObjectArray<char> bytesReceived;
int clientPort = socket.GetClientPort();
if (gVerboseNetworkMessagesServer)
printf("connected from %s:%d\n", socket.GetClientAddr(), clientPort);
if (pClient->Receive(4))
{
int clientKey = *(int*)pClient->GetData();
if (clientKey == GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER)
{
printf("Client version OK %d\n", clientKey);
}
else
{
printf("Server version (%d) mismatches Client Version (%d)\n", GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER, clientKey);
continue;
}
}
//----------------------------------------------------------------------
// Receive request from the client.
//----------------------------------------------------------------------
while (cachedSharedParam != eTCPRequestTerminate)
{
bool receivedData = false;
int maxLen = 4 + sizeof(GraphicsSharedMemoryCommand) + GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE;
if (pClient->Receive(maxLen))
{
//heuristic to detect disconnected clients
CSimpleSocket::CSocketError err = pClient->GetSocketError();
if (err != CSimpleSocket::SocketSuccess || !pClient->IsSocketValid())
{
b3Clock::usleep(100);
curNumErr++;
if (curNumErr > 100)
{
///printf("TCP Connection error = %d, curNumErr = %d\n", (int)err, curNumErr);
}
}
curNumErr = 0;
char* msg2 = (char*)pClient->GetData();
int numBytesRec2 = pClient->GetBytesReceived();
if (gVerboseNetworkMessagesServer)
printf("numBytesRec2=%d\n", numBytesRec2);
if (numBytesRec2 < 0)
{
numBytesRec2 = 0;
}
int curSize = bytesReceived.size();
bytesReceived.resize(bytesReceived.size() + numBytesRec2);
for (int i = 0; i < numBytesRec2; i++)
{
bytesReceived[curSize + i] = msg2[i];
}
if (bytesReceived.size() >= 4)
{
int numBytesRec = bytesReceived.size();
if (numBytesRec >= 10)
{
if (strncmp(&bytesReceived[0], "disconnect", 10) == 0)
{
printf("Disconnect request received\n");
bytesReceived.clear();
break;
}
}
if (gVerboseNetworkMessagesServer)
{
printf("received message length [%d]\n", numBytesRec);
}
receivedData = true;
args->m_cmdPtr = 0;
int type = *(int*)&bytesReceived[0];
if (numBytesRec == sizeof(GraphicsSharedMemoryCommand))
{
args->m_cmdPtr = (GraphicsSharedMemoryCommand*)&bytesReceived[0];
}
if (args->m_cmdPtr)
{
b3AlignedObjectArray<char> buffer;
buffer.resize(GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
bool hasStatus = true;
if (gVerboseNetworkMessagesServer)
printf("processing command:");
switch (args->m_cmdPtr->m_type)
{
case GFX_CMD_0:
{
int axis = args->m_cmdPtr->m_upAxisYCommand.m_enableUpAxisY ? 1 : 2;
args->submitCommand();
while (args->isCommandOutstanding())
{
clock.usleep(0);
}
bool done = false;
//guiHelper.setUpAxis(axis);
if (gVerboseNetworkMessagesServer)
printf("GFX_CMD_0\n");
break;
}
case GFX_CMD_SET_VISUALIZER_FLAG:
{
//disable single step rendering for GraphicsServer
if (args->m_cmdPtr->m_visualizerFlagCommand.m_visualizerFlag == COV_ENABLE_SINGLE_STEP_RENDERING)
{
args->m_cmdPtr->m_visualizerFlagCommand.m_visualizerFlag = 0;
}
args->submitCommand();
while (args->isCommandOutstanding())
{
clock.usleep(0);
}
//guiHelper.setVisualizerFlag(
// args->m_cmdPtr->m_visualizerFlagCommand.m_visualizerFlag,
// args->m_cmdPtr->m_visualizerFlagCommand.m_enable);
//serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_COMPLETED;
if (gVerboseNetworkMessagesServer)
printf("GFX_CMD_SET_VISUALIZER_FLAG\n");
break;
}
case GFX_CMD_UPLOAD_DATA:
{
int slot = args->m_cmdPtr->m_uploadDataCommand.m_dataSlot;
int numBytes = args->m_cmdPtr->m_uploadDataCommand.m_numBytes;
submitStatus(pClient, args->m_serverStatus, buffer);
//now receive numBytes
if (gVerboseNetworkMessagesServer)
printf("GFX_CMD_UPLOAD_DATA receiving data\n");
int received = 0;
int offset = 0;
args->m_dataSlots[slot].resize(numBytes);
while (received < numBytes)
{
if (pClient->Receive(args->m_cmdPtr->m_uploadDataCommand.m_numBytes))
{
//heuristic to detect disconnected clients
CSimpleSocket::CSocketError err = pClient->GetSocketError();
if (err != CSimpleSocket::SocketSuccess || !pClient->IsSocketValid())
{
curNumErr++;
//printf("TCP Connection error = %d, curNumErr = %d\n", (int)err, curNumErr);
}
char* msg2 = (char*)pClient->GetData();
int numBytesRec2 = pClient->GetBytesReceived();
if (gVerboseNetworkMessagesServer)
printf("received %d bytes (total=%d)\n", numBytesRec2, received);
for (int i = 0; i < numBytesRec2; i++)
{
args->m_dataSlots[slot][i+ offset] = msg2[i];
}
offset += numBytesRec2;
received += numBytesRec2;
}
}
if (gVerboseNetworkMessagesServer)
printf("received all bytes!\n");
args->m_serverStatus.m_type = GFX_CMD_CLIENT_COMMAND_COMPLETED;
if (gVerboseNetworkMessagesServer)
printf("GFX_CMD_UPLOAD_DATA\n");
break;
}
case GFX_CMD_REGISTER_TEXTURE:
{
args->submitCommand();
while (args->isCommandOutstanding())
{
clock.usleep(0);
}
//const unsigned char* texels = (const unsigned char*)&args->m_dataSlots[0][0];
//args->m_serverStatus.m_registerTextureStatus.m_textureId = guiHelper.registerTexture(texels, args->m_cmdPtr->m_registerTextureCommand.m_width,
// args->m_cmdPtr->m_registerTextureCommand.m_height);
//serverStatus.m_type = GFX_CMD_REGISTER_TEXTURE_COMPLETED;
if (gVerboseNetworkMessagesServer)
printf("GFX_CMD_REGISTER_TEXTURE\n");
break;
}
case GFX_CMD_REGISTER_GRAPHICS_SHAPE:
{
args->submitCommand();
while (args->isCommandOutstanding())
{
clock.usleep(0);
}
if (gVerboseNetworkMessagesServer)
printf("GFX_CMD_REGISTER_GRAPHICS_SHAPE\n");
break;
}
case GFX_CMD_REGISTER_GRAPHICS_INSTANCE:
{
args->submitCommand();
while (args->isCommandOutstanding())
{
clock.usleep(0);
}
if (gVerboseNetworkMessagesServer)
printf("GFX_CMD_REGISTER_GRAPHICS_INSTANCE\n");
break;
}
case GFX_CMD_SYNCHRONIZE_TRANSFORMS:
{
args->submitCommand();
while (args->isCommandOutstanding())
{
clock.usleep(0);
}
if (gVerboseNetworkMessagesServer)
printf("GFX_CMD_SYNCHRONIZE_TRANSFORMS\n");
break;
}
case GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES:
{
args->submitCommand();
while (args->isCommandOutstanding())
{
clock.usleep(0);
}
if (gVerboseNetworkMessagesServer)
printf("GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES\n");
break;
}
case GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE:
{
args->submitCommand();
while (args->isCommandOutstanding())
{
clock.usleep(0);
}
if (gVerboseNetworkMessagesServer)
printf("GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE\n");
break;
}
case GFX_CMD_CHANGE_RGBA_COLOR:
{
args->submitCommand();
while (args->isCommandOutstanding())
{
clock.usleep(0);
}
if (gVerboseNetworkMessagesServer)
printf("GFX_CMD_CHANGE_RGBA_COLOR\n");
break;
}
case GFX_CMD_CHANGE_SCALING:
{
args->submitCommand();
while (args->isCommandOutstanding())
{
clock.usleep(0);
}
if (gVerboseNetworkMessagesServer)
printf("GFX_CMD_CHANGE_SCALING\n");
break;
}
case GFX_CMD_GET_CAMERA_INFO:
{
args->submitCommand();
while (args->isCommandOutstanding())
{
clock.usleep(0);
}
//bool RemoteGUIHelper::getCameraInfo(int* width, int* height,
// float viewMatrix[16], float projectionMatrix[16],
// float camUp[3], float camForward[3], float hor[3], float vert[3],
// float* yaw, float* pitch, float* camDist, float camTarget[3]) const
#if 0
guiHelper.getCameraInfo(&serverStatus.m_getCameraInfoStatus.width,
&serverStatus.m_getCameraInfoStatus.height,
serverStatus.m_getCameraInfoStatus.viewMatrix,
serverStatus.m_getCameraInfoStatus.projectionMatrix,
serverStatus.m_getCameraInfoStatus.camUp,
serverStatus.m_getCameraInfoStatus.camForward,
serverStatus.m_getCameraInfoStatus.hor,
serverStatus.m_getCameraInfoStatus.vert,
&serverStatus.m_getCameraInfoStatus.yaw,
&serverStatus.m_getCameraInfoStatus.pitch,
&serverStatus.m_getCameraInfoStatus.camDist,
serverStatus.m_getCameraInfoStatus.camTarget);
serverStatus.m_type = GFX_CMD_GET_CAMERA_INFO_COMPLETED;
#endif
if (gVerboseNetworkMessagesServer)
printf("GFX_CMD_GET_CAMERA_INFO\n");
break;
}
case GFX_CMD_INVALID:
case GFX_CMD_MAX_CLIENT_COMMANDS:
default:
{
printf("UNKNOWN COMMAND!\n");
btAssert(0);
hasStatus = false;
}
}
double startTimeSeconds = clock.getTimeInSeconds();
double curTimeSeconds = clock.getTimeInSeconds();
if (gVerboseNetworkMessagesServer)
{
//printf("buffer.size = %d\n", buffer.size());
printf("serverStatus.m_numDataStreamBytes = %d\n", args->m_serverStatus.m_numDataStreamBytes);
}
if (hasStatus)
{
submitStatus(pClient, args->m_serverStatus, buffer);
}
bytesReceived.clear();
}
else
{
//likely an incomplete packet, let's append more bytes
//printf("received packet with unknown contents\n");
}
}
}
if (!receivedData)
{
//printf("Didn't receive data.\n");
}
}
printf("Disconnecting client.\n");
pClient->Close();
delete pClient;
}
}
#endif //BT_ENABLE_CLSOCKET
///////////////////////////////
args->m_cs->lock();
cachedSharedParam = args->m_cs->getSharedParam(0);
args->m_cs->unlock();
} while (cachedSharedParam != eTCPRequestTerminate);
#ifdef BT_ENABLE_CLSOCKET
socket.Close();
socket.Shutdown(CSimpleSocket::Both);
#endif
}
else
{
args->m_cs->lock();
args->m_cs->setSharedParam(0, eTCPInitializationFailed);
args->m_cs->unlock();
}
printf("TCPThreadFunc thread exit\n");
//do nothing
}
void* TCPlsMemoryFunc()
{
//don't create local store memory, just return 0
return new TCPThreadLocalStorage;
}
void TCPlsMemoryReleaseFunc(void* ptr)
{
TCPThreadLocalStorage* p = (TCPThreadLocalStorage*)ptr;
delete p;
}
#ifndef _WIN32
#include "../MultiThreading/b3PosixThreadSupport.h"
b3ThreadSupportInterface* createTCPThreadSupport(int numThreads)
{
b3PosixThreadSupport::ThreadConstructionInfo constructionInfo("TCPThreads",
TCPThreadFunc,
TCPlsMemoryFunc,
TCPlsMemoryReleaseFunc,
numThreads);
b3ThreadSupportInterface* threadSupport = new b3PosixThreadSupport(constructionInfo);
return threadSupport;
}
#elif defined(_WIN32)
#include "../MultiThreading/b3Win32ThreadSupport.h"
b3ThreadSupportInterface* createTCPThreadSupport(int numThreads)
{
b3Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("TCPThreads", TCPThreadFunc, TCPlsMemoryFunc, TCPlsMemoryReleaseFunc, numThreads);
b3Win32ThreadSupport* threadSupport = new b3Win32ThreadSupport(threadConstructionInfo);
return threadSupport;
}
#endif
class GraphicsServerExample : public CommonExampleInterface
{
CommonGraphicsApp* m_app;
GUIHelperInterface* m_guiHelper;
bool m_verboseOutput;
float m_x;
float m_y;
float m_z;
b3ThreadSupportInterface* m_threadSupport;
TCPArgs m_args;
public:
GraphicsServerExample(GUIHelperInterface* guiHelper)
: m_guiHelper(guiHelper),
m_x(0),
m_y(0),
m_z(0)
{
m_verboseOutput = true;
m_app = guiHelper->getAppInterface();
m_app->setUpAxis(2);
m_threadSupport = createTCPThreadSupport(1);
m_args.m_cs = m_threadSupport->createCriticalSection();
m_args.m_cs->setSharedParam(0, eTCPIsUnInitialized);
m_threadSupport->runTask(B3_THREAD_SCHEDULE_TASK, (void*)&this->m_args, 0);
bool isUninitialized = true;
while (isUninitialized)
{
m_args.m_cs->lock();
isUninitialized = (m_args.m_cs->getSharedParam(0) == eTCPIsUnInitialized);
m_args.m_cs->unlock();
#ifdef _WIN32
b3Clock::usleep(1000);
#endif
}
}
virtual ~GraphicsServerExample()
{
m_args.m_cs->setSharedParam(0, eTCPRequestTerminate);
int numActiveThreads = 1;
while (numActiveThreads)
{
int arg0, arg1;
if (m_threadSupport->isTaskCompleted(&arg0, &arg1, 0))
{
numActiveThreads--;
printf("numActiveThreads = %d\n", numActiveThreads);
}
else
{
b3Clock::usleep(0);
}
};
m_threadSupport->deleteCriticalSection(m_args.m_cs);
delete m_threadSupport;
m_threadSupport = 0;
}
virtual void initPhysics()
{
}
virtual void exitPhysics()
{
}
void submitServerStatus(GraphicsSharedMemoryStatus& status, int blockIndex)
{
}
bool processCommand(const struct GraphicsSharedMemoryCommand& clientCmd, struct GraphicsSharedMemoryStatus& serverStatusOut)
{
//printf("processed command of type:%d\n", clientCmd.m_type);
B3_PROFILE("processCommand");
switch (clientCmd.m_type)
{
case GFX_CMD_0:
{
//either Y or Z can be up axis
int upAxis = (clientCmd.m_upAxisYCommand.m_enableUpAxisY) ? 1 : 2;
m_guiHelper->setUpAxis(upAxis);
serverStatusOut.m_type = GFX_CMD_CLIENT_COMMAND_COMPLETED;
m_args.processCommand();
break;
}
case GFX_CMD_SET_VISUALIZER_FLAG:
{
if ((clientCmd.m_visualizerFlagCommand.m_visualizerFlag != COV_ENABLE_RENDERING) &&
(clientCmd.m_visualizerFlagCommand.m_visualizerFlag != COV_ENABLE_SINGLE_STEP_RENDERING))
{
//printf("clientCmd.m_visualizerFlag.m_visualizerFlag: %d, clientCmd.m_visualizerFlag.m_enable %d\n",
// clientCmd.m_visualizerFlagCommand.m_visualizerFlag, clientCmd.m_visualizerFlagCommand.m_enable);
this->m_guiHelper->setVisualizerFlag(clientCmd.m_visualizerFlagCommand.m_visualizerFlag, clientCmd.m_visualizerFlagCommand.m_enable);
}
m_args.processCommand();
break;
}
case GFX_CMD_UPLOAD_DATA:
{
#if 0
//printf("uploadData command: curSize=%d, offset=%d, slot=%d", clientCmd.m_uploadDataCommand.m_numBytes, clientCmd.m_uploadDataCommand.m_dataOffset, clientCmd.m_uploadDataCommand.m_dataSlot);
int dataSlot = clientCmd.m_uploadDataCommand.m_dataSlot;
int dataOffset = clientCmd.m_uploadDataCommand.m_dataOffset;
m_dataSlots.resize(dataSlot + 1);
btAssert(m_dataSlots[dataSlot].size() >= dataOffset);
m_dataSlots[dataSlot].resize(clientCmd.m_uploadDataCommand.m_numBytes + clientCmd.m_uploadDataCommand.m_dataOffset);
for (int i = 0; i < clientCmd.m_uploadDataCommand.m_numBytes; i++)
{
m_dataSlots[dataSlot][dataOffset + i] = bufferServerToClient[i];
}
#endif
break;
}
case GFX_CMD_REGISTER_TEXTURE:
{
int dataSlot = 0;
int sizeData = m_args.m_dataSlots[dataSlot].size();
btAssert(sizeData > 0);
serverStatusOut.m_type = GFX_CMD_REGISTER_TEXTURE_FAILED;
if (sizeData)
{
unsigned char* texels = &m_args.m_dataSlots[dataSlot][0];
int textureId = this->m_guiHelper->registerTexture(texels, clientCmd.m_registerTextureCommand.m_width, clientCmd.m_registerTextureCommand.m_height);
serverStatusOut.m_type = GFX_CMD_REGISTER_TEXTURE_COMPLETED;
serverStatusOut.m_registerTextureStatus.m_textureId = textureId;
}
m_args.processCommand();
break;
}
case GFX_CMD_REGISTER_GRAPHICS_SHAPE:
{
int verticesSlot = 0;
int indicesSlot = 1;
serverStatusOut.m_type = GFX_CMD_REGISTER_GRAPHICS_SHAPE_FAILED;
const float* vertices = (const float*)&m_args.m_dataSlots[verticesSlot][0];
const int* indices = (const int*)&m_args.m_dataSlots[indicesSlot][0];
int numVertices = clientCmd.m_registerGraphicsShapeCommand.m_numVertices;
int numIndices = clientCmd.m_registerGraphicsShapeCommand.m_numIndices;
int primitiveType = clientCmd.m_registerGraphicsShapeCommand.m_primitiveType;
int textureId = clientCmd.m_registerGraphicsShapeCommand.m_textureId;
int shapeId = this->m_guiHelper->registerGraphicsShape(vertices, numVertices, indices, numIndices, primitiveType, textureId);
serverStatusOut.m_registerGraphicsShapeStatus.m_shapeId = shapeId;
serverStatusOut.m_type = GFX_CMD_REGISTER_GRAPHICS_SHAPE_COMPLETED;
m_args.processCommand();
break;
}
case GFX_CMD_REGISTER_GRAPHICS_INSTANCE:
{
int graphicsInstanceId = m_guiHelper->registerGraphicsInstance(clientCmd.m_registerGraphicsInstanceCommand.m_shapeIndex,
clientCmd.m_registerGraphicsInstanceCommand.m_position,
clientCmd.m_registerGraphicsInstanceCommand.m_quaternion,
clientCmd.m_registerGraphicsInstanceCommand.m_color,
clientCmd.m_registerGraphicsInstanceCommand.m_scaling);
serverStatusOut.m_registerGraphicsInstanceStatus.m_graphicsInstanceId = graphicsInstanceId;
serverStatusOut.m_type = GFX_CMD_REGISTER_GRAPHICS_INSTANCE_COMPLETED;
m_args.processCommand();
break;
}
case GFX_CMD_SYNCHRONIZE_TRANSFORMS:
{
GUISyncPosition* positions = (GUISyncPosition*)&m_args.m_dataSlots[0][0];
for (int i = 0; i < clientCmd.m_syncTransformsCommand.m_numPositions; i++)
{
m_app->m_renderer->writeSingleInstanceTransformToCPU(positions[i].m_pos, positions[i].m_orn, positions[i].m_graphicsInstanceId);
}
m_args.processCommand();
break;
}
case GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES:
{
m_guiHelper->removeAllGraphicsInstances();
m_args.processCommand();
break;
}
case GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE:
{
m_app->m_renderer->removeGraphicsInstance(clientCmd.m_removeGraphicsInstanceCommand.m_graphicsUid);
m_args.processCommand();
break;
}
case GFX_CMD_CHANGE_RGBA_COLOR:
{
m_guiHelper->changeRGBAColor(clientCmd.m_changeRGBAColorCommand.m_graphicsUid, clientCmd.m_changeRGBAColorCommand.m_rgbaColor);
m_args.processCommand();
break;
}
case GFX_CMD_CHANGE_SCALING:
{
m_guiHelper->changeScaling(clientCmd.m_changeScalingCommand.m_graphicsUid, clientCmd.m_changeScalingCommand.m_scaling);
m_args.processCommand();
break;
}
case GFX_CMD_GET_CAMERA_INFO:
{
serverStatusOut.m_type = GFX_CMD_GET_CAMERA_INFO_FAILED;
if (m_guiHelper->getCameraInfo(
&serverStatusOut.m_getCameraInfoStatus.width,
&serverStatusOut.m_getCameraInfoStatus.height,
serverStatusOut.m_getCameraInfoStatus.viewMatrix,
serverStatusOut.m_getCameraInfoStatus.projectionMatrix,
serverStatusOut.m_getCameraInfoStatus.camUp,
serverStatusOut.m_getCameraInfoStatus.camForward,
serverStatusOut.m_getCameraInfoStatus.hor,
serverStatusOut.m_getCameraInfoStatus.vert,
&serverStatusOut.m_getCameraInfoStatus.yaw,
&serverStatusOut.m_getCameraInfoStatus.pitch,
&serverStatusOut.m_getCameraInfoStatus.camDist,
serverStatusOut.m_getCameraInfoStatus.camTarget))
{
serverStatusOut.m_type = GFX_CMD_GET_CAMERA_INFO_COMPLETED;
}
m_args.processCommand();
break;
}
default:
{
printf("unsupported command:%d\n", clientCmd.m_type);
}
}
return true;
}
void processClientCommands()
{
int timeStamp = 0;
bool hasStatus = false;
if (m_args.isCommandOutstanding())
{
processCommand(*m_args.m_cmdPtr, m_args.m_serverStatus);
}
//serverStatusOut.m_type = GFX_CMD_CLIENT_COMMAND_FAILED;
//bool hasStatus = processCommand(clientCmd, serverStatusOut);
if (hasStatus)
{
//submitServerStatus(serverStatusOut);
}
}
virtual void stepSimulation(float deltaTime)
{
B3_PROFILE("stepSimulation");
processClientCommands();
m_x += 0.01f;
m_y += 0.01f;
m_z += 0.01f;
}
virtual void renderScene()
{
B3_PROFILE("renderScene");
{
B3_PROFILE("writeTransforms");
m_app->m_renderer->writeTransforms();
}
{
B3_PROFILE("m_renderer->renderScene");
m_app->m_renderer->renderScene();
}
}
virtual void physicsDebugDraw(int debugDrawFlags)
{
}
virtual bool mouseMoveCallback(float x, float y)
{
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
return false;
}
virtual bool keyboardCallback(int key, int state)
{
return false;
}
virtual void resetCamera()
{
float dist = 3.5;
float pitch = -32;
float yaw = 136;
float targetPos[3] = {0, 0, 0};
if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
{
m_app->m_renderer->getActiveCamera()->setCameraDistance(dist);
m_app->m_renderer->getActiveCamera()->setCameraPitch(pitch);
m_app->m_renderer->getActiveCamera()->setCameraYaw(yaw);
m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0], targetPos[1], targetPos[2]);
}
}
};
CommonExampleInterface* GraphicsServerCreateFuncBullet(struct CommonExampleOptions& options)
{
return new GraphicsServerExample(options.m_guiHelper);
}

View file

@ -0,0 +1,6 @@
#ifndef GRAPHICS_SERVER_EXAMPLE_H
#define GRAPHICS_SERVER_EXAMPLE_H
class CommonExampleInterface* GraphicsServerCreateFuncBullet(struct CommonExampleOptions& options);
#endif //GRAPHICS_SERVER_EXAMPLE_H

View file

@ -0,0 +1,41 @@
#ifndef GRAPHICS_SHARED_MEMORY_BLOCK_H
#define GRAPHICS_SHARED_MEMORY_BLOCK_H
#define GRAPHICS_SHARED_MEMORY_MAX_COMMANDS 1
#include "GraphicsSharedMemoryCommands.h"
struct GraphicsSharedMemoryBlock
{
int m_magicId;
struct GraphicsSharedMemoryCommand m_clientCommands[GRAPHICS_SHARED_MEMORY_MAX_COMMANDS];
struct GraphicsSharedMemoryStatus m_serverCommands[GRAPHICS_SHARED_MEMORY_MAX_COMMANDS];
int m_numClientCommands;
int m_numProcessedClientCommands;
int m_numServerCommands;
int m_numProcessedServerCommands;
char m_bulletStreamData[GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE];
};
//http://stackoverflow.com/questions/24736304/unable-to-use-inline-in-declaration-get-error-c2054
#ifdef _WIN32
__inline
#else
inline
#endif
void
InitSharedMemoryBlock(struct GraphicsSharedMemoryBlock* sharedMemoryBlock)
{
sharedMemoryBlock->m_numClientCommands = 0;
sharedMemoryBlock->m_numServerCommands = 0;
sharedMemoryBlock->m_numProcessedClientCommands = 0;
sharedMemoryBlock->m_numProcessedServerCommands = 0;
sharedMemoryBlock->m_magicId = GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER;
}
#define GRAPHICS_SHARED_MEMORY_SIZE sizeof(GraphicsSharedMemoryBlock)
#endif //GRAPHICS_SHARED_MEMORY_BLOCK_H

View file

@ -0,0 +1,192 @@
#ifndef GRAPHICS_SHARED_MEMORY_COMMANDS_H
#define GRAPHICS_SHARED_MEMORY_COMMANDS_H
//this is a very experimental draft of commands. We will iterate on this API (commands, arguments etc)
#include "GraphicsSharedMemoryPublic.h"
#ifdef __GNUC__
#include <stdint.h>
typedef int32_t smInt32a_t;
typedef int64_t smInt64a_t;
typedef uint32_t smUint32a_t;
typedef uint64_t smUint64a_t;
#elif defined(_MSC_VER)
typedef __int32 smInt32a_t;
typedef __int64 smInt64a_t;
typedef unsigned __int32 smUint32a_t;
typedef unsigned __int64 smUint64a_t;
#else
typedef int smInt32a_t;
typedef long long int smInt64a_t;
typedef unsigned int smUint32a_t;
typedef unsigned long long int smUint64a_t;
#endif
#ifdef __APPLE__
#define GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE (512 * 1024)
#else
#define GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE (4 * 1024 * 1024)
#endif
struct GraphicsCommand0
{
int bla;
};
struct GraphicsUpAxisCommand
{
int m_enableUpAxisY;
};
struct GraphicsStatus0
{
int bla;
};
struct GraphicsVisualizerFlagCommand
{
int m_visualizerFlag;
int m_enable;
};
struct GraphicsUploadDataCommand
{
int m_numBytes;
int m_dataOffset;
int m_dataSlot;
};
struct GraphicRegisterTextureCommand
{
int m_width;
int m_height;
};
struct GraphicsRegisterTextureStatus
{
int m_textureId;
};
struct GraphicsRegisterGraphicsShapeCommand
{
int m_numVertices;
int m_numIndices;
int m_primitiveType;
int m_textureId;
};
struct GraphicsRegisterGraphicsShapeStatus
{
int m_shapeId;
};
struct GraphicsRegisterGraphicsInstanceCommand
{
int m_shapeIndex;
float m_position[4];
float m_quaternion[4];
float m_color[4];
float m_scaling[4];
};
struct GraphicsRegisterGraphicsInstanceStatus
{
int m_graphicsInstanceId;
};
struct GraphicsSyncTransformsCommand
{
int m_numPositions;
};
struct GraphicsRemoveInstanceCommand
{
int m_graphicsUid;
};
struct GraphicsChangeRGBAColorCommand
{
int m_graphicsUid;
double m_rgbaColor[4];
};
struct GraphicsChangeScalingCommand
{
int m_graphicsUid;
double m_scaling[3];
};
struct GraphicsGetCameraInfoStatus
{
int width;
int height;
float viewMatrix[16];
float projectionMatrix[16];
float camUp[3];
float camForward[3];
float hor[3];
float vert[3];
float yaw;
float pitch;
float camDist;
float camTarget[3];
};
struct GraphicsSharedMemoryCommand
{
int m_type;
smUint64a_t m_timeStamp;
int m_sequenceNumber;
//m_updateFlags is a bit fields to tell which parameters need updating
//for example m_updateFlags = SIM_PARAM_UPDATE_DELTA_TIME | SIM_PARAM_UPDATE_NUM_SOLVER_ITERATIONS;
int m_updateFlags;
union {
struct GraphicsCommand0 m_graphicsCommand0;
struct GraphicsUpAxisCommand m_upAxisYCommand;
struct GraphicsVisualizerFlagCommand m_visualizerFlagCommand;
struct GraphicsUploadDataCommand m_uploadDataCommand;
struct GraphicRegisterTextureCommand m_registerTextureCommand;
struct GraphicsRegisterGraphicsShapeCommand m_registerGraphicsShapeCommand;
struct GraphicsRegisterGraphicsInstanceCommand m_registerGraphicsInstanceCommand;
struct GraphicsSyncTransformsCommand m_syncTransformsCommand;
struct GraphicsRemoveInstanceCommand m_removeGraphicsInstanceCommand;
struct GraphicsChangeRGBAColorCommand m_changeRGBAColorCommand;
struct GraphicsChangeScalingCommand m_changeScalingCommand;
};
};
struct GraphicsSharedMemoryStatus
{
int m_type;
smUint64a_t m_timeStamp;
int m_sequenceNumber;
//m_streamBytes is only for internal purposes
int m_numDataStreamBytes;
char* m_dataStream;
//m_updateFlags is a bit fields to tell which parameters were updated,
//m_updateFlags is ignored for most status messages
int m_updateFlags;
union {
struct GraphicsStatus0 m_graphicsStatus0;
struct GraphicsRegisterTextureStatus m_registerTextureStatus;
struct GraphicsRegisterGraphicsShapeStatus m_registerGraphicsShapeStatus;
struct GraphicsRegisterGraphicsInstanceStatus m_registerGraphicsInstanceStatus;
struct GraphicsGetCameraInfoStatus m_getCameraInfoStatus;
};
};
typedef struct GraphicsSharedMemoryStatus GraphicsSharedMemoryStatus_t;
#endif //GRAPHICS_SHARED_MEMORY_COMMANDS_H

View file

@ -0,0 +1,52 @@
#ifndef GRAPHICS_SHARED_MEMORY_PUBLIC_H
#define GRAPHICS_SHARED_MEMORY_PUBLIC_H
#define GRAPHICS_SHARED_MEMORY_KEY 11347
///increase the SHARED_MEMORY_MAGIC_NUMBER whenever incompatible changes are made in the structures
///my convention is year/month/day/rev
//Please don't replace an existing magic number:
//instead, only ADD a new one at the top, comment-out previous one
#define GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER 201904030
enum EnumGraphicsSharedMemoryClientCommand
{
GFX_CMD_INVALID = 0,
GFX_CMD_0,
GFX_CMD_SET_VISUALIZER_FLAG,
GFX_CMD_UPLOAD_DATA,
GFX_CMD_REGISTER_TEXTURE,
GFX_CMD_REGISTER_GRAPHICS_SHAPE,
GFX_CMD_REGISTER_GRAPHICS_INSTANCE,
GFX_CMD_SYNCHRONIZE_TRANSFORMS,
GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES,
GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE,
GFX_CMD_CHANGE_RGBA_COLOR,
GFX_CMD_GET_CAMERA_INFO,
GFX_CMD_CHANGE_SCALING,
//don't go beyond this command!
GFX_CMD_MAX_CLIENT_COMMANDS,
};
enum EnumGraphicsSharedMemoryServerStatus
{
GFX_CMD_SHARED_MEMORY_NOT_INITIALIZED = 0,
//GFX_CMD_CLIENT_COMMAND_COMPLETED is a generic 'completed' status that doesn't need special handling on the client
GFX_CMD_CLIENT_COMMAND_COMPLETED,
GFX_CMD_CLIENT_COMMAND_FAILED,
GFX_CMD_REGISTER_TEXTURE_COMPLETED,
GFX_CMD_REGISTER_TEXTURE_FAILED,
GFX_CMD_REGISTER_GRAPHICS_SHAPE_COMPLETED,
GFX_CMD_REGISTER_GRAPHICS_SHAPE_FAILED,
GFX_CMD_REGISTER_GRAPHICS_INSTANCE_COMPLETED,
GFX_CMD_REGISTER_GRAPHICS_INSTANCE_FAILED,
GFX_CMD_GET_CAMERA_INFO_COMPLETED,
GFX_CMD_GET_CAMERA_INFO_FAILED,
//don't go beyond 'CMD_MAX_SERVER_COMMANDS!
GFX_CMD_MAX_SERVER_COMMANDS
};
#endif //GRAPHICS_SHARED_MEMORY_PUBLIC_H

View file

@ -0,0 +1,338 @@
#include "IKTrajectoryHelper.h"
#include "BussIK/Node.h"
#include "BussIK/Tree.h"
#include "BussIK/Jacobian.h"
#include "BussIK/VectorRn.h"
#include "BussIK/MatrixRmn.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "BulletDynamics/Featherstone/btMultiBody.h"
#define RADIAN(X) ((X)*RadiansToDegrees)
//use BussIK and Reflexxes to convert from Cartesian endeffector future target to
//joint space positions at each real-time (simulation) step
struct IKTrajectoryHelperInternalData
{
VectorR3 m_endEffectorTargetPosition;
VectorRn m_nullSpaceVelocity;
VectorRn m_dampingCoeff;
b3AlignedObjectArray<Node*> m_ikNodes;
IKTrajectoryHelperInternalData()
{
m_endEffectorTargetPosition.SetZero();
m_nullSpaceVelocity.SetZero();
m_dampingCoeff.SetZero();
}
};
IKTrajectoryHelper::IKTrajectoryHelper()
{
m_data = new IKTrajectoryHelperInternalData;
}
IKTrajectoryHelper::~IKTrajectoryHelper()
{
delete m_data;
}
bool IKTrajectoryHelper::computeIK(const double endEffectorTargetPosition[3],
const double endEffectorTargetOrientation[4],
const double endEffectorWorldPosition[3],
const double endEffectorWorldOrientation[4],
const double* q_current, int numQ, int endEffectorIndex,
double* q_new, int ikMethod, const double* linear_jacobian, const double* angular_jacobian, int jacobian_size, const double dampIk[6])
{
MatrixRmn AugMat;
bool useAngularPart = (ikMethod == IK2_VEL_DLS_WITH_ORIENTATION || ikMethod == IK2_VEL_DLS_WITH_ORIENTATION_NULLSPACE || ikMethod == IK2_VEL_SDLS_WITH_ORIENTATION) ? true : false;
Jacobian ikJacobian(useAngularPart, numQ, 1);
ikJacobian.Reset();
bool UseJacobianTargets1 = false;
if (UseJacobianTargets1)
{
ikJacobian.SetJtargetActive();
}
else
{
ikJacobian.SetJendActive();
}
VectorR3 targets;
targets.Set(endEffectorTargetPosition[0], endEffectorTargetPosition[1], endEffectorTargetPosition[2]);
ikJacobian.ComputeJacobian(&targets); // Set up Jacobian and deltaS vectors
// Set one end effector world position from Bullet
VectorRn deltaS(3);
for (int i = 0; i < 3; ++i)
{
deltaS.Set(i, dampIk[i] * (endEffectorTargetPosition[i] - endEffectorWorldPosition[i]));
}
// Set one end effector world orientation from Bullet
VectorRn deltaR(3);
if (useAngularPart)
{
btQuaternion startQ(endEffectorWorldOrientation[0], endEffectorWorldOrientation[1], endEffectorWorldOrientation[2], endEffectorWorldOrientation[3]);
btQuaternion endQ(endEffectorTargetOrientation[0], endEffectorTargetOrientation[1], endEffectorTargetOrientation[2], endEffectorTargetOrientation[3]);
btQuaternion deltaQ = endQ * startQ.inverse();
float angle = deltaQ.getAngle();
btVector3 axis = deltaQ.getAxis();
if (angle > PI)
{
angle -= 2.0 * PI;
}
else if (angle < -PI)
{
angle += 2.0 * PI;
}
float angleDot = angle;
btVector3 angularVel = angleDot * axis.normalize();
for (int i = 0; i < 3; ++i)
{
deltaR.Set(i, dampIk[i + 3] * angularVel[i]);
}
}
{
if (useAngularPart)
{
VectorRn deltaC(6);
MatrixRmn completeJacobian(6, numQ);
for (int i = 0; i < 3; ++i)
{
deltaC.Set(i, deltaS[i]);
deltaC.Set(i + 3, deltaR[i]);
for (int j = 0; j < numQ; ++j)
{
completeJacobian.Set(i, j, linear_jacobian[i * numQ + j]);
completeJacobian.Set(i + 3, j, angular_jacobian[i * numQ + j]);
}
}
ikJacobian.SetDeltaS(deltaC);
ikJacobian.SetJendTrans(completeJacobian);
}
else
{
VectorRn deltaC(3);
MatrixRmn completeJacobian(3, numQ);
for (int i = 0; i < 3; ++i)
{
deltaC.Set(i, deltaS[i]);
for (int j = 0; j < numQ; ++j)
{
completeJacobian.Set(i, j, linear_jacobian[i * numQ + j]);
}
}
ikJacobian.SetDeltaS(deltaC);
ikJacobian.SetJendTrans(completeJacobian);
}
}
// Calculate the change in theta values
switch (ikMethod)
{
case IK2_JACOB_TRANS:
ikJacobian.CalcDeltaThetasTranspose(); // Jacobian transpose method
break;
case IK2_DLS:
case IK2_VEL_DLS_WITH_ORIENTATION:
case IK2_VEL_DLS:
//ikJacobian.CalcDeltaThetasDLS(); // Damped least squares method
assert(m_data->m_dampingCoeff.GetLength() == numQ);
ikJacobian.CalcDeltaThetasDLS2(m_data->m_dampingCoeff, AugMat);
break;
case IK2_VEL_DLS_WITH_NULLSPACE:
case IK2_VEL_DLS_WITH_ORIENTATION_NULLSPACE:
assert(m_data->m_nullSpaceVelocity.GetLength() == numQ);
ikJacobian.CalcDeltaThetasDLSwithNullspace(m_data->m_nullSpaceVelocity, AugMat);
break;
case IK2_DLS_SVD:
ikJacobian.CalcDeltaThetasDLSwithSVD();
break;
case IK2_PURE_PSEUDO:
ikJacobian.CalcDeltaThetasPseudoinverse(); // Pure pseudoinverse method
break;
case IK2_SDLS:
case IK2_VEL_SDLS:
case IK2_VEL_SDLS_WITH_ORIENTATION:
ikJacobian.CalcDeltaThetasSDLS(); // Selectively damped least squares method
break;
default:
ikJacobian.ZeroDeltaThetas();
break;
}
// Use for velocity IK, update theta dot
//ikJacobian.UpdateThetaDot();
// Use for position IK, incrementally update theta
//ikJacobian.UpdateThetas();
// Apply the change in the theta values
//ikJacobian.UpdatedSClampValue(&targets);
for (int i = 0; i < numQ; i++)
{
// Use for velocity IK
q_new[i] = ikJacobian.dTheta[i] + q_current[i];
// Use for position IK
//q_new[i] = m_data->m_ikNodes[i]->GetTheta();
}
return true;
}
bool IKTrajectoryHelper::computeIK2(
const double* endEffectorTargetPositions,
const double* endEffectorCurrentPositions,
int numEndEffectors,
const double* q_current, int numQ,
double* q_new, int ikMethod, const double* linear_jacobians, const double dampIk[6])
{
MatrixRmn AugMat;
bool useAngularPart = false;//for now (ikMethod == IK2_VEL_DLS_WITH_ORIENTATION || ikMethod == IK2_VEL_DLS_WITH_ORIENTATION_NULLSPACE || ikMethod == IK2_VEL_SDLS_WITH_ORIENTATION) ? true : false;
Jacobian ikJacobian(useAngularPart, numQ, numEndEffectors);
ikJacobian.Reset();
bool UseJacobianTargets1 = false;
if (UseJacobianTargets1)
{
ikJacobian.SetJtargetActive();
}
else
{
ikJacobian.SetJendActive();
}
VectorRn deltaC(numEndEffectors *3);
MatrixRmn completeJacobian(numEndEffectors*3, numQ);
for (int ne = 0; ne < numEndEffectors; ne++)
{
VectorR3 targets;
targets.Set(endEffectorTargetPositions[ne*3+0], endEffectorTargetPositions[ne * 3 + 1], endEffectorTargetPositions[ne * 3 + 2]);
// Set one end effector world position from Bullet
VectorRn deltaS(3);
for (int i = 0; i < 3; ++i)
{
deltaS.Set(i, dampIk[i] * (endEffectorTargetPositions[ne*3+i] - endEffectorCurrentPositions[ne*3+i]));
}
{
for (int i = 0; i < 3; ++i)
{
deltaC.Set(ne*3+i, deltaS[i]);
for (int j = 0; j < numQ; ++j)
{
completeJacobian.Set(ne * 3 + i, j, linear_jacobians[((ne*3+i) * numQ) + j]);
}
}
}
}
ikJacobian.SetDeltaS(deltaC);
ikJacobian.SetJendTrans(completeJacobian);
// Calculate the change in theta values
switch (ikMethod)
{
case IK2_JACOB_TRANS:
ikJacobian.CalcDeltaThetasTranspose(); // Jacobian transpose method
break;
case IK2_DLS:
case IK2_VEL_DLS_WITH_ORIENTATION:
case IK2_VEL_DLS:
//ikJacobian.CalcDeltaThetasDLS(); // Damped least squares method
assert(m_data->m_dampingCoeff.GetLength() == numQ);
ikJacobian.CalcDeltaThetasDLS2(m_data->m_dampingCoeff, AugMat);
break;
case IK2_VEL_DLS_WITH_NULLSPACE:
case IK2_VEL_DLS_WITH_ORIENTATION_NULLSPACE:
assert(m_data->m_nullSpaceVelocity.GetLength() == numQ);
ikJacobian.CalcDeltaThetasDLSwithNullspace(m_data->m_nullSpaceVelocity, AugMat);
break;
case IK2_DLS_SVD:
ikJacobian.CalcDeltaThetasDLSwithSVD();
break;
case IK2_PURE_PSEUDO:
ikJacobian.CalcDeltaThetasPseudoinverse(); // Pure pseudoinverse method
break;
case IK2_SDLS:
case IK2_VEL_SDLS:
case IK2_VEL_SDLS_WITH_ORIENTATION:
ikJacobian.CalcDeltaThetasSDLS(); // Selectively damped least squares method
break;
default:
ikJacobian.ZeroDeltaThetas();
break;
}
// Use for velocity IK, update theta dot
//ikJacobian.UpdateThetaDot();
// Use for position IK, incrementally update theta
//ikJacobian.UpdateThetas();
// Apply the change in the theta values
//ikJacobian.UpdatedSClampValue(&targets);
for (int i = 0; i < numQ; i++)
{
// Use for velocity IK
q_new[i] = ikJacobian.dTheta[i] + q_current[i];
// Use for position IK
//q_new[i] = m_data->m_ikNodes[i]->GetTheta();
}
return true;
}
bool IKTrajectoryHelper::computeNullspaceVel(int numQ, const double* q_current, const double* lower_limit, const double* upper_limit, const double* joint_range, const double* rest_pose)
{
m_data->m_nullSpaceVelocity.SetLength(numQ);
m_data->m_nullSpaceVelocity.SetZero();
// TODO: Expose the coefficents of the null space term so that the user can choose to balance the null space task and the IK target task.
// Can also adaptively adjust the coefficients based on the residual of the null space velocity in the IK target task space.
double stayCloseToZeroGain = 0.001;
double stayAwayFromLimitsGain = 10.0;
// Stay close to zero
for (int i = 0; i < numQ; ++i)
{
m_data->m_nullSpaceVelocity[i] = stayCloseToZeroGain * (rest_pose[i] - q_current[i]);
}
// Stay away from joint limits
for (int i = 0; i < numQ; ++i)
{
if (q_current[i] > upper_limit[i])
{
m_data->m_nullSpaceVelocity[i] += stayAwayFromLimitsGain * (upper_limit[i] - q_current[i]) / joint_range[i];
}
if (q_current[i] < lower_limit[i])
{
m_data->m_nullSpaceVelocity[i] += stayAwayFromLimitsGain * (lower_limit[i] - q_current[i]) / joint_range[i];
}
}
return true;
}
bool IKTrajectoryHelper::setDampingCoeff(int numQ, const double* coeff)
{
m_data->m_dampingCoeff.SetLength(numQ);
m_data->m_dampingCoeff.SetZero();
for (int i = 0; i < numQ; ++i)
{
m_data->m_dampingCoeff[i] = coeff[i];
}
return true;
}

View file

@ -0,0 +1,44 @@
#ifndef IK_TRAJECTORY_HELPER_H
#define IK_TRAJECTORY_HELPER_H
enum IK2_Method
{
IK2_JACOB_TRANS = 0,
IK2_PURE_PSEUDO,
IK2_DLS,
IK2_SDLS,
IK2_DLS_SVD,
IK2_VEL_DLS,
IK2_VEL_DLS_WITH_ORIENTATION,
IK2_VEL_DLS_WITH_NULLSPACE,
IK2_VEL_DLS_WITH_ORIENTATION_NULLSPACE,
IK2_VEL_SDLS,
IK2_VEL_SDLS_WITH_ORIENTATION,
};
class IKTrajectoryHelper
{
struct IKTrajectoryHelperInternalData* m_data;
public:
IKTrajectoryHelper();
virtual ~IKTrajectoryHelper();
bool computeIK(const double endEffectorTargetPosition[3],
const double endEffectorTargetOrientation[4],
const double endEffectorWorldPosition[3],
const double endEffectorWorldOrientation[4],
const double* q_old, int numQ, int endEffectorIndex,
double* q_new, int ikMethod, const double* linear_jacobian, const double* angular_jacobian, int jacobian_size, const double dampIk[6]);
bool computeIK2(
const double* endEffectorTargetPositions,
const double* endEffectorCurrentPositions,
int numEndEffectors,
const double* q_current, int numQ,
double* q_new, int ikMethod, const double* linear_jacobians, const double dampIk[6]);
bool computeNullspaceVel(int numQ, const double* q_current, const double* lower_limit, const double* upper_limit, const double* joint_range, const double* rest_pose);
bool setDampingCoeff(int numQ, const double* coeff);
};
#endif //IK_TRAJECTORY_HELPER_H

View file

@ -0,0 +1,46 @@
#include "InProcessMemory.h"
#include "LinearMath/btHashMap.h"
struct InProcessMemoryInternalData
{
btHashMap<btHashInt, void*> m_memoryPointers;
};
InProcessMemory::InProcessMemory()
{
m_data = new InProcessMemoryInternalData;
}
InProcessMemory::~InProcessMemory()
{
for (int i = 0; i < m_data->m_memoryPointers.size(); i++)
{
void** ptrptr = m_data->m_memoryPointers.getAtIndex(i);
if (ptrptr)
{
void* ptr = *ptrptr;
free(ptr);
}
}
delete m_data;
}
void* InProcessMemory::allocateSharedMemory(int key, int size, bool allowCreation)
{
void** ptrptr = m_data->m_memoryPointers[key];
if (ptrptr)
{
return *ptrptr;
}
void* ptr = malloc(size);
m_data->m_memoryPointers.insert(key, ptr);
return ptr;
}
void InProcessMemory::releaseSharedMemory(int /*key*/, int /*size*/)
{
//we don't release the memory here, but in the destructor instead,
//so multiple users could 'share' the memory given some key
}

View file

@ -0,0 +1,18 @@
#ifndef IN_PROCESS_MEMORY_H
#define IN_PROCESS_MEMORY_H
#include "SharedMemoryInterface.h"
class InProcessMemory : public SharedMemoryInterface
{
struct InProcessMemoryInternalData* m_data;
public:
InProcessMemory();
virtual ~InProcessMemory();
virtual void* allocateSharedMemory(int key, int size, bool allowCreation);
virtual void releaseSharedMemory(int key, int size);
};
#endif

View file

@ -0,0 +1,5 @@
#include "PhysicsClient.h"
PhysicsClient::~PhysicsClient()
{
}

View file

@ -0,0 +1,94 @@
#ifndef BT_PHYSICS_CLIENT_API_H
#define BT_PHYSICS_CLIENT_API_H
//#include "SharedMemoryCommands.h"
#include "LinearMath/btVector3.h"
class PhysicsClient
{
public:
virtual ~PhysicsClient();
// return true if connection succesfull, can also check 'isConnected'
virtual bool connect() = 0;
virtual void disconnectSharedMemory() = 0;
virtual bool isConnected() const = 0;
// return non-null if there is a status, nullptr otherwise
virtual const struct SharedMemoryStatus* processServerStatus() = 0;
virtual struct SharedMemoryCommand* getAvailableSharedMemoryCommand() = 0;
virtual bool canSubmitCommand() const = 0;
virtual bool submitClientCommand(const struct SharedMemoryCommand& command) = 0;
virtual int getNumBodies() const = 0;
virtual int getBodyUniqueId(int serialIndex) const = 0;
virtual bool getBodyInfo(int bodyUniqueId, struct b3BodyInfo& info) const = 0;
virtual int getNumJoints(int bodyUniqueId) const = 0;
virtual int getNumDofs(int bodyUniqueId) const = 0;
virtual bool getJointInfo(int bodyUniqueId, int jointIndex, struct b3JointInfo& info) const = 0;
virtual int getNumUserConstraints() const = 0;
virtual int getUserConstraintInfo(int constraintUniqueId, struct b3UserConstraint& info) const = 0;
virtual int getUserConstraintId(int serialIndex) const = 0;
virtual void setSharedMemoryKey(int key) = 0;
virtual void uploadBulletFileToSharedMemory(const char* data, int len) = 0;
virtual void uploadRaysToSharedMemory(struct SharedMemoryCommand& command, const double* rayFromWorldArray, const double* rayToWorldArray, int numRays) = 0;
virtual int getNumDebugLines() const = 0;
virtual const float* getDebugLinesFrom() const = 0;
virtual const float* getDebugLinesTo() const = 0;
virtual const float* getDebugLinesColor() const = 0;
virtual void getCachedCameraImage(struct b3CameraImageData* cameraData) = 0;
virtual void getCachedContactPointInformation(struct b3ContactInformation* contactPointData) = 0;
virtual void getCachedOverlappingObjects(struct b3AABBOverlapData* overlappingObjects) = 0;
virtual void getCachedVisualShapeInformation(struct b3VisualShapeInformation* visualShapesInfo) = 0;
virtual void getCachedCollisionShapeInformation(struct b3CollisionShapeInformation* collisionShapesInfo) = 0;
virtual void getCachedMeshData(struct b3MeshData* meshData) = 0;
virtual void getCachedVREvents(struct b3VREventsData* vrEventsData) = 0;
virtual void getCachedKeyboardEvents(struct b3KeyboardEventsData* keyboardEventsData) = 0;
virtual void getCachedMouseEvents(struct b3MouseEventsData* mouseEventsData) = 0;
virtual void getCachedRaycastHits(struct b3RaycastInformation* raycastHits) = 0;
virtual void getCachedMassMatrix(int dofCountCheck, double* massMatrix) = 0;
virtual bool getCachedReturnData(struct b3UserDataValue* returnData) = 0;
virtual void setTimeOut(double timeOutInSeconds) = 0;
virtual double getTimeOut() const = 0;
virtual bool getCachedUserData(int userDataId, struct b3UserDataValue& valueOut) const = 0;
virtual int getCachedUserDataId(int bodyUniqueId, int linkIndex, int visualShapeIndex, const char* key) const = 0;
virtual int getNumUserData(int bodyUniqueId) const = 0;
virtual void getUserDataInfo(int bodyUniqueId, int userDataIndex, const char** keyOut, int* userDataIdOut, int* linkIndexOut, int* visualShapeIndexOut) const = 0;
virtual void pushProfileTiming(const char* timingName) = 0;
virtual void popProfileTiming() = 0;
};
#endif // BT_PHYSICS_CLIENT_API_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,758 @@
#ifndef PHYSICS_CLIENT_C_API_H
#define PHYSICS_CLIENT_C_API_H
//#include "SharedMemoryBlock.h"
#include "SharedMemoryPublic.h"
#define B3_DECLARE_HANDLE(name) \
typedef struct name##__ \
{ \
int unused; \
} * name
B3_DECLARE_HANDLE(b3PhysicsClientHandle);
B3_DECLARE_HANDLE(b3SharedMemoryCommandHandle);
B3_DECLARE_HANDLE(b3SharedMemoryStatusHandle);
#ifdef _WIN32
#define B3_SHARED_API __declspec(dllexport)
#elif defined(__GNUC__)
#define B3_SHARED_API __attribute__((visibility("default")))
#else
#define B3_SHARED_API
#endif
///There are several connection methods, see following header files:
#include "PhysicsClientSharedMemory_C_API.h"
#include "PhysicsClientSharedMemory2_C_API.h"
#include "PhysicsDirectC_API.h"
#ifdef BT_ENABLE_ENET
#include "PhysicsClientUDP_C_API.h"
#endif
#ifdef BT_ENABLE_CLSOCKET
#include "PhysicsClientTCP_C_API.h"
#endif
#ifdef __cplusplus
extern "C"
{
#endif
///b3DisconnectSharedMemory will disconnect the client from the server and cleanup memory.
B3_SHARED_API void b3DisconnectSharedMemory(b3PhysicsClientHandle physClient);
///There can only be 1 outstanding command. Check if a command can be send.
B3_SHARED_API int b3CanSubmitCommand(b3PhysicsClientHandle physClient);
///blocking submit command and wait for status
B3_SHARED_API b3SharedMemoryStatusHandle b3SubmitClientCommandAndWaitStatus(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle);
///In general it is better to use b3SubmitClientCommandAndWaitStatus. b3SubmitClientCommand is a non-blocking submit
///command, which requires checking for the status manually, using b3ProcessServerStatus. Also, before sending the
///next command, make sure to check if you can send a command using 'b3CanSubmitCommand'.
B3_SHARED_API int b3SubmitClientCommand(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle);
///non-blocking check status
B3_SHARED_API b3SharedMemoryStatusHandle b3ProcessServerStatus(b3PhysicsClientHandle physClient);
/// Get the physics server return status type. See EnumSharedMemoryServerStatus in SharedMemoryPublic.h for error codes.
B3_SHARED_API int b3GetStatusType(b3SharedMemoryStatusHandle statusHandle);
///Plugin system, load and unload a plugin, execute a command
B3_SHARED_API b3SharedMemoryCommandHandle b3CreateCustomCommand(b3PhysicsClientHandle physClient);
B3_SHARED_API void b3CustomCommandLoadPlugin(b3SharedMemoryCommandHandle commandHandle, const char* pluginPath);
B3_SHARED_API void b3CustomCommandLoadPluginSetPostFix(b3SharedMemoryCommandHandle commandHandle, const char* postFix);
B3_SHARED_API int b3GetStatusPluginUniqueId(b3SharedMemoryStatusHandle statusHandle);
B3_SHARED_API int b3GetStatusPluginCommandResult(b3SharedMemoryStatusHandle statusHandle);
B3_SHARED_API int b3GetStatusPluginCommandReturnData(b3PhysicsClientHandle physClient, struct b3UserDataValue* valueOut);
B3_SHARED_API void b3CustomCommandUnloadPlugin(b3SharedMemoryCommandHandle commandHandle, int pluginUniqueId);
B3_SHARED_API void b3CustomCommandExecutePluginCommand(b3SharedMemoryCommandHandle commandHandle, int pluginUniqueId, const char* textArguments);
B3_SHARED_API void b3CustomCommandExecuteAddIntArgument(b3SharedMemoryCommandHandle commandHandle, int intVal);
B3_SHARED_API void b3CustomCommandExecuteAddFloatArgument(b3SharedMemoryCommandHandle commandHandle, float floatVal);
B3_SHARED_API int b3GetStatusBodyIndices(b3SharedMemoryStatusHandle statusHandle, int* bodyIndicesOut, int bodyIndicesCapacity);
B3_SHARED_API int b3GetStatusBodyIndex(b3SharedMemoryStatusHandle statusHandle);
B3_SHARED_API int b3GetStatusActualState(b3SharedMemoryStatusHandle statusHandle,
int* bodyUniqueId,
int* numDegreeOfFreedomQ,
int* numDegreeOfFreedomU,
const double* rootLocalInertialFrame[],
const double* actualStateQ[],
const double* actualStateQdot[],
const double* jointReactionForces[]);
B3_SHARED_API int b3GetStatusActualState2(b3SharedMemoryStatusHandle statusHandle,
int* bodyUniqueId,
int* numLinks,
int* numDegreeOfFreedomQ,
int* numDegreeOfFreedomU,
const double* rootLocalInertialFrame[],
const double* actualStateQ[],
const double* actualStateQdot[],
const double* jointReactionForces[],
const double* linkLocalInertialFrames[],
const double* jointMotorForces[],
const double* linkStates[],
const double* linkWorldVelocities[]);
B3_SHARED_API b3SharedMemoryCommandHandle b3RequestCollisionInfoCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId);
B3_SHARED_API int b3GetStatusAABB(b3SharedMemoryStatusHandle statusHandle, int linkIndex, double aabbMin[/*3*/], double aabbMax[/*3*/]);
///If you re-connected to an existing server, or server changed otherwise, sync the body info and user constraints etc.
B3_SHARED_API b3SharedMemoryCommandHandle b3InitSyncBodyInfoCommand(b3PhysicsClientHandle physClient);
// Sync the body info of a single body. Useful when a new body has been added by a different client (e,g, when detecting through a body added notification).
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRequestBodyInfoCommand(b3PhysicsClientHandle physClient, int bodyUniqueId);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRemoveBodyCommand(b3PhysicsClientHandle physClient, int bodyUniqueId);
///return the total number of bodies in the simulation
B3_SHARED_API int b3GetNumBodies(b3PhysicsClientHandle physClient);
/// return the body unique id, given the index in range [0 , b3GetNumBodies() )
B3_SHARED_API int b3GetBodyUniqueId(b3PhysicsClientHandle physClient, int serialIndex);
///given a body unique id, return the body information. See b3BodyInfo in SharedMemoryPublic.h
B3_SHARED_API int b3GetBodyInfo(b3PhysicsClientHandle physClient, int bodyUniqueId, struct b3BodyInfo* info);
///give a unique body index (after loading the body) return the number of joints.
B3_SHARED_API int b3GetNumJoints(b3PhysicsClientHandle physClient, int bodyUniqueId);
///give a unique body index (after loading the body) return the number of degrees of freedom (DoF).
B3_SHARED_API int b3GetNumDofs(b3PhysicsClientHandle physClient, int bodyUniqueId);
///compute the number of degrees of freedom for this body.
///Return -1 for unsupported spherical joint, -2 for unsupported planar joint.
B3_SHARED_API int b3ComputeDofCount(b3PhysicsClientHandle physClient, int bodyUniqueId);
///given a body and joint index, return the joint information. See b3JointInfo in SharedMemoryPublic.h
B3_SHARED_API int b3GetJointInfo(b3PhysicsClientHandle physClient, int bodyUniqueId, int jointIndex, struct b3JointInfo* info);
///user data handling
B3_SHARED_API b3SharedMemoryCommandHandle b3InitSyncUserDataCommand(b3PhysicsClientHandle physClient);
B3_SHARED_API void b3AddBodyToSyncUserDataRequest(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitAddUserDataCommand(b3PhysicsClientHandle physClient, int bodyUniqueId, int linkIndex, int visualShapeIndex, const char* key, enum UserDataValueType valueType, int valueLength, const void* valueData);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRemoveUserDataCommand(b3PhysicsClientHandle physClient, int userDataId);
B3_SHARED_API int b3GetUserData(b3PhysicsClientHandle physClient, int userDataId, struct b3UserDataValue* valueOut);
B3_SHARED_API int b3GetUserDataId(b3PhysicsClientHandle physClient, int bodyUniqueId, int linkIndex, int visualShapeIndex, const char* key);
B3_SHARED_API int b3GetUserDataIdFromStatus(b3SharedMemoryStatusHandle statusHandle);
B3_SHARED_API int b3GetNumUserData(b3PhysicsClientHandle physClient, int bodyUniqueId);
B3_SHARED_API void b3GetUserDataInfo(b3PhysicsClientHandle physClient, int bodyUniqueId, int userDataIndex, const char** keyOut, int* userDataIdOut, int* linkIndexOut, int* visualShapeIndexOut);
B3_SHARED_API b3SharedMemoryCommandHandle b3GetDynamicsInfoCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId, int linkIndex);
B3_SHARED_API b3SharedMemoryCommandHandle b3GetDynamicsInfoCommandInit2(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex);
///given a body unique id and link index, return the dynamics information. See b3DynamicsInfo in SharedMemoryPublic.h
B3_SHARED_API int b3GetDynamicsInfo(b3SharedMemoryStatusHandle statusHandle, struct b3DynamicsInfo* info);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitChangeDynamicsInfo(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitChangeDynamicsInfo2(b3SharedMemoryCommandHandle commandHandle);
B3_SHARED_API int b3ChangeDynamicsInfoSetMass(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, double mass);
B3_SHARED_API int b3ChangeDynamicsInfoSetLocalInertiaDiagonal(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, const double localInertiaDiagonal[]);
B3_SHARED_API int b3ChangeDynamicsInfoSetAnisotropicFriction(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, const double anisotropicFriction[]);
B3_SHARED_API int b3ChangeDynamicsInfoSetJointLimit(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, double jointLowerLimit, double jointUpperLimit);
B3_SHARED_API int b3ChangeDynamicsInfoSetJointLimitForce(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, double jointLimitForce);
B3_SHARED_API int b3ChangeDynamicsInfoSetDynamicType(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, int dynamicType);
B3_SHARED_API int b3ChangeDynamicsInfoSetSleepThreshold(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, double sleepThreshold);
B3_SHARED_API int b3ChangeDynamicsInfoSetLateralFriction(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, double lateralFriction);
B3_SHARED_API int b3ChangeDynamicsInfoSetSpinningFriction(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, double friction);
B3_SHARED_API int b3ChangeDynamicsInfoSetRollingFriction(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, double friction);
B3_SHARED_API int b3ChangeDynamicsInfoSetRestitution(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, double restitution);
B3_SHARED_API int b3ChangeDynamicsInfoSetLinearDamping(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, double linearDamping);
B3_SHARED_API int b3ChangeDynamicsInfoSetAngularDamping(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, double angularDamping);
B3_SHARED_API int b3ChangeDynamicsInfoSetJointDamping(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, double jointDamping);
B3_SHARED_API int b3ChangeDynamicsInfoSetContactStiffnessAndDamping(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, double contactStiffness, double contactDamping);
B3_SHARED_API int b3ChangeDynamicsInfoSetFrictionAnchor(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, int frictionAnchor);
B3_SHARED_API int b3ChangeDynamicsInfoSetCcdSweptSphereRadius(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, double ccdSweptSphereRadius);
B3_SHARED_API int b3ChangeDynamicsInfoSetContactProcessingThreshold(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkIndex, double contactProcessingThreshold);
B3_SHARED_API int b3ChangeDynamicsInfoSetActivationState(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int activationState);
B3_SHARED_API int b3ChangeDynamicsInfoSetMaxJointVelocity(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, double maxJointVelocity);
B3_SHARED_API int b3ChangeDynamicsInfoSetCollisionMargin(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, double collisionMargin);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitCreateUserConstraintCommand(b3PhysicsClientHandle physClient, int parentBodyUniqueId, int parentJointIndex, int childBodyUniqueId, int childJointIndex, struct b3JointInfo* info);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitCreateUserConstraintCommand2(b3SharedMemoryCommandHandle commandHandle, int parentBodyUniqueId, int parentJointIndex, int childBodyUniqueId, int childJointIndex, struct b3JointInfo* info);
///return a unique id for the user constraint, after successful creation, or -1 for an invalid constraint id
B3_SHARED_API int b3GetStatusUserConstraintUniqueId(b3SharedMemoryStatusHandle statusHandle);
///change parameters of an existing user constraint
B3_SHARED_API b3SharedMemoryCommandHandle b3InitChangeUserConstraintCommand(b3PhysicsClientHandle physClient, int userConstraintUniqueId);
B3_SHARED_API int b3InitChangeUserConstraintSetPivotInB(b3SharedMemoryCommandHandle commandHandle, const double jointChildPivot[/*3*/]);
B3_SHARED_API int b3InitChangeUserConstraintSetFrameInB(b3SharedMemoryCommandHandle commandHandle, const double jointChildFrameOrn[/*4*/]);
B3_SHARED_API int b3InitChangeUserConstraintSetMaxForce(b3SharedMemoryCommandHandle commandHandle, double maxAppliedForce);
B3_SHARED_API int b3InitChangeUserConstraintSetGearRatio(b3SharedMemoryCommandHandle commandHandle, double gearRatio);
B3_SHARED_API int b3InitChangeUserConstraintSetGearAuxLink(b3SharedMemoryCommandHandle commandHandle, int gearAuxLink);
B3_SHARED_API int b3InitChangeUserConstraintSetRelativePositionTarget(b3SharedMemoryCommandHandle commandHandle, double relativePositionTarget);
B3_SHARED_API int b3InitChangeUserConstraintSetERP(b3SharedMemoryCommandHandle commandHandle, double erp);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRemoveUserConstraintCommand(b3PhysicsClientHandle physClient, int userConstraintUniqueId);
B3_SHARED_API int b3GetNumUserConstraints(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitGetUserConstraintStateCommand(b3PhysicsClientHandle physClient, int constraintUniqueId);
B3_SHARED_API int b3GetStatusUserConstraintState(b3SharedMemoryStatusHandle statusHandle, struct b3UserConstraintState* constraintState);
B3_SHARED_API int b3GetUserConstraintInfo(b3PhysicsClientHandle physClient, int constraintUniqueId, struct b3UserConstraint* info);
/// return the user constraint id, given the index in range [0 , b3GetNumUserConstraints() )
B3_SHARED_API int b3GetUserConstraintId(b3PhysicsClientHandle physClient, int serialIndex);
///Request physics debug lines for debug visualization. The flags in debugMode are the same as used in Bullet
///See btIDebugDraw::DebugDrawModes in Bullet/src/LinearMath/btIDebugDraw.h
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRequestDebugLinesCommand(b3PhysicsClientHandle physClient, int debugMode);
///Get the pointers to the physics debug line information, after b3InitRequestDebugLinesCommand returns
///status CMD_DEBUG_LINES_COMPLETED
B3_SHARED_API void b3GetDebugLines(b3PhysicsClientHandle physClient, struct b3DebugLines* lines);
///configure the 3D OpenGL debug visualizer (enable/disable GUI widgets, shadows, position camera etc)
B3_SHARED_API b3SharedMemoryCommandHandle b3InitConfigureOpenGLVisualizer(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitConfigureOpenGLVisualizer2(b3SharedMemoryCommandHandle commandHandle);
B3_SHARED_API void b3ConfigureOpenGLVisualizerSetVisualizationFlags(b3SharedMemoryCommandHandle commandHandle, int flag, int enabled);
B3_SHARED_API void b3ConfigureOpenGLVisualizerSetLightPosition(b3SharedMemoryCommandHandle commandHandle, const float lightPosition[3]);
B3_SHARED_API void b3ConfigureOpenGLVisualizerSetShadowMapResolution(b3SharedMemoryCommandHandle commandHandle, int shadowMapResolution);
B3_SHARED_API void b3ConfigureOpenGLVisualizerSetShadowMapIntensity(b3SharedMemoryCommandHandle commandHandle, double shadowMapIntensity);
B3_SHARED_API void b3ConfigureOpenGLVisualizerSetLightRgbBackground(b3SharedMemoryCommandHandle commandHandle, const float rgbBackground[3]);
B3_SHARED_API void b3ConfigureOpenGLVisualizerSetShadowMapWorldSize(b3SharedMemoryCommandHandle commandHandle, int shadowMapWorldSize);
B3_SHARED_API void b3ConfigureOpenGLVisualizerSetRemoteSyncTransformInterval(b3SharedMemoryCommandHandle commandHandle, double remoteSyncTransformInterval);
B3_SHARED_API void b3ConfigureOpenGLVisualizerSetViewMatrix(b3SharedMemoryCommandHandle commandHandle, float cameraDistance, float cameraPitch, float cameraYaw, const float cameraTargetPosition[/*3*/]);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRequestOpenGLVisualizerCameraCommand(b3PhysicsClientHandle physClient);
B3_SHARED_API int b3GetStatusOpenGLVisualizerCamera(b3SharedMemoryStatusHandle statusHandle, struct b3OpenGLVisualizerCameraInfo* camera);
/// Add/remove user-specific debug lines and debug text messages
B3_SHARED_API b3SharedMemoryCommandHandle b3InitUserDebugDrawAddLine3D(b3PhysicsClientHandle physClient, const double fromXYZ[/*3*/], const double toXYZ[/*3*/], const double colorRGB[/*3*/], double lineWidth, double lifeTime);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitUserDebugDrawAddPoints3D(b3PhysicsClientHandle physClient, const double positionsXYZ[/*3n*/], const double colorsRGB[/*3*/], double pointSize, double lifeTime, int pointNum);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitUserDebugDrawAddText3D(b3PhysicsClientHandle physClient, const char* txt, const double positionXYZ[/*3*/], const double colorRGB[/*3*/], double textSize, double lifeTime);
B3_SHARED_API void b3UserDebugTextSetOptionFlags(b3SharedMemoryCommandHandle commandHandle, int optionFlags);
B3_SHARED_API void b3UserDebugTextSetOrientation(b3SharedMemoryCommandHandle commandHandle, const double orientation[/*4*/]);
B3_SHARED_API void b3UserDebugItemSetReplaceItemUniqueId(b3SharedMemoryCommandHandle commandHandle, int replaceItem);
B3_SHARED_API void b3UserDebugItemSetParentObject(b3SharedMemoryCommandHandle commandHandle, int objectUniqueId, int linkIndex);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitUserDebugAddParameter(b3PhysicsClientHandle physClient, const char* txt, double rangeMin, double rangeMax, double startValue);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitUserDebugReadParameter(b3PhysicsClientHandle physClient, int debugItemUniqueId);
B3_SHARED_API int b3GetStatusDebugParameterValue(b3SharedMemoryStatusHandle statusHandle, double* paramValue);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitUserDebugDrawRemove(b3PhysicsClientHandle physClient, int debugItemUniqueId);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitUserDebugDrawRemoveAll(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitUserRemoveAllParameters(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitDebugDrawingCommand(b3PhysicsClientHandle physClient);
B3_SHARED_API void b3SetDebugObjectColor(b3SharedMemoryCommandHandle commandHandle, int objectUniqueId, int linkIndex, const double objectColorRGB[/*3*/]);
B3_SHARED_API void b3RemoveDebugObjectColor(b3SharedMemoryCommandHandle commandHandle, int objectUniqueId, int linkIndex);
///All debug items unique Ids are positive: a negative unique Id means failure.
B3_SHARED_API int b3GetDebugItemUniqueId(b3SharedMemoryStatusHandle statusHandle);
///request an image from a simulated camera, using a software renderer.
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRequestCameraImage(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRequestCameraImage2(b3SharedMemoryCommandHandle commandHandle);
B3_SHARED_API void b3RequestCameraImageSetCameraMatrices(b3SharedMemoryCommandHandle commandHandle, float viewMatrix[/*16*/], float projectionMatrix[/*16*/]);
B3_SHARED_API void b3RequestCameraImageSetPixelResolution(b3SharedMemoryCommandHandle commandHandle, int width, int height);
B3_SHARED_API void b3RequestCameraImageSetLightDirection(b3SharedMemoryCommandHandle commandHandle, const float lightDirection[/*3*/]);
B3_SHARED_API void b3RequestCameraImageSetLightColor(b3SharedMemoryCommandHandle commandHandle, const float lightColor[/*3*/]);
B3_SHARED_API void b3RequestCameraImageSetLightDistance(b3SharedMemoryCommandHandle commandHandle, float lightDistance);
B3_SHARED_API void b3RequestCameraImageSetLightAmbientCoeff(b3SharedMemoryCommandHandle commandHandle, float lightAmbientCoeff);
B3_SHARED_API void b3RequestCameraImageSetLightDiffuseCoeff(b3SharedMemoryCommandHandle commandHandle, float lightDiffuseCoeff);
B3_SHARED_API void b3RequestCameraImageSetLightSpecularCoeff(b3SharedMemoryCommandHandle commandHandle, float lightSpecularCoeff);
B3_SHARED_API void b3RequestCameraImageSetShadow(b3SharedMemoryCommandHandle commandHandle, int hasShadow);
B3_SHARED_API void b3RequestCameraImageSelectRenderer(b3SharedMemoryCommandHandle commandHandle, int renderer);
B3_SHARED_API void b3RequestCameraImageSetFlags(b3SharedMemoryCommandHandle commandHandle, int flags);
B3_SHARED_API void b3GetCameraImageData(b3PhysicsClientHandle physClient, struct b3CameraImageData* imageData);
///set projective texture camera matrices.
B3_SHARED_API void b3RequestCameraImageSetProjectiveTextureMatrices(b3SharedMemoryCommandHandle commandHandle, float viewMatrix[/*16*/], float projectionMatrix[/*16*/]);
///compute a view matrix, helper function for b3RequestCameraImageSetCameraMatrices
B3_SHARED_API void b3ComputeViewMatrixFromPositions(const float cameraPosition[/*3*/], const float cameraTargetPosition[/*3*/], const float cameraUp[/*3*/], float viewMatrix[/*16*/]);
B3_SHARED_API void b3ComputeViewMatrixFromYawPitchRoll(const float cameraTargetPosition[/*3*/], float distance, float yaw, float pitch, float roll, int upAxis, float viewMatrix[/*16*/]);
B3_SHARED_API void b3ComputePositionFromViewMatrix(const float viewMatrix[/*16*/], float cameraPosition[/*3*/], float cameraTargetPosition[/*3*/], float cameraUp[/*3*/]);
///compute a projection matrix, helper function for b3RequestCameraImageSetCameraMatrices
B3_SHARED_API void b3ComputeProjectionMatrix(float left, float right, float bottom, float top, float nearVal, float farVal, float projectionMatrix[/*16*/]);
B3_SHARED_API void b3ComputeProjectionMatrixFOV(float fov, float aspect, float nearVal, float farVal, float projectionMatrix[/*16*/]);
/* obsolete, please use b3ComputeViewProjectionMatrices */
B3_SHARED_API void b3RequestCameraImageSetViewMatrix(b3SharedMemoryCommandHandle commandHandle, const float cameraPosition[/*3*/], const float cameraTargetPosition[/*3*/], const float cameraUp[/*3*/]);
/* obsolete, please use b3ComputeViewProjectionMatrices */
B3_SHARED_API void b3RequestCameraImageSetViewMatrix2(b3SharedMemoryCommandHandle commandHandle, const float cameraTargetPosition[/*3*/], float distance, float yaw, float pitch, float roll, int upAxis);
/* obsolete, please use b3ComputeViewProjectionMatrices */
B3_SHARED_API void b3RequestCameraImageSetProjectionMatrix(b3SharedMemoryCommandHandle commandHandle, float left, float right, float bottom, float top, float nearVal, float farVal);
/* obsolete, please use b3ComputeViewProjectionMatrices */
B3_SHARED_API void b3RequestCameraImageSetFOVProjectionMatrix(b3SharedMemoryCommandHandle commandHandle, float fov, float aspect, float nearVal, float farVal);
///request an contact point information
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRequestContactPointInformation(b3PhysicsClientHandle physClient);
B3_SHARED_API void b3SetContactFilterBodyA(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueIdA);
B3_SHARED_API void b3SetContactFilterBodyB(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueIdB);
B3_SHARED_API void b3SetContactFilterLinkA(b3SharedMemoryCommandHandle commandHandle, int linkIndexA);
B3_SHARED_API void b3SetContactFilterLinkB(b3SharedMemoryCommandHandle commandHandle, int linkIndexB);
B3_SHARED_API void b3GetContactPointInformation(b3PhysicsClientHandle physClient, struct b3ContactInformation* contactPointData);
///compute the closest points between two bodies
B3_SHARED_API b3SharedMemoryCommandHandle b3InitClosestDistanceQuery(b3PhysicsClientHandle physClient);
B3_SHARED_API void b3SetClosestDistanceFilterBodyA(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueIdA);
B3_SHARED_API void b3SetClosestDistanceFilterLinkA(b3SharedMemoryCommandHandle commandHandle, int linkIndexA);
B3_SHARED_API void b3SetClosestDistanceFilterBodyB(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueIdB);
B3_SHARED_API void b3SetClosestDistanceFilterLinkB(b3SharedMemoryCommandHandle commandHandle, int linkIndexB);
B3_SHARED_API void b3SetClosestDistanceThreshold(b3SharedMemoryCommandHandle commandHandle, double distance);
B3_SHARED_API void b3SetClosestDistanceFilterCollisionShapeA(b3SharedMemoryCommandHandle commandHandle, int collisionShapeA);
B3_SHARED_API void b3SetClosestDistanceFilterCollisionShapeB(b3SharedMemoryCommandHandle commandHandle, int collisionShapeB);
B3_SHARED_API void b3SetClosestDistanceFilterCollisionShapePositionA(b3SharedMemoryCommandHandle commandHandle, const double collisionShapePositionA[/*3*/]);
B3_SHARED_API void b3SetClosestDistanceFilterCollisionShapePositionB(b3SharedMemoryCommandHandle commandHandle, const double collisionShapePositionB[/*3*/]);
B3_SHARED_API void b3SetClosestDistanceFilterCollisionShapeOrientationA(b3SharedMemoryCommandHandle commandHandle, const double collisionShapeOrientationA[/*4*/]);
B3_SHARED_API void b3SetClosestDistanceFilterCollisionShapeOrientationB(b3SharedMemoryCommandHandle commandHandle, const double collisionShapeOrientationB[/*4*/]);
B3_SHARED_API void b3GetClosestPointInformation(b3PhysicsClientHandle physClient, struct b3ContactInformation* contactPointInfo);
///get all the bodies that touch a given axis aligned bounding box specified in world space (min and max coordinates)
B3_SHARED_API b3SharedMemoryCommandHandle b3InitAABBOverlapQuery(b3PhysicsClientHandle physClient, const double aabbMin[/*3*/], const double aabbMax[/*3*/]);
B3_SHARED_API void b3GetAABBOverlapResults(b3PhysicsClientHandle physClient, struct b3AABBOverlapData* data);
//request visual shape information
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRequestVisualShapeInformation(b3PhysicsClientHandle physClient, int bodyUniqueIdA);
B3_SHARED_API void b3GetVisualShapeInformation(b3PhysicsClientHandle physClient, struct b3VisualShapeInformation* visualShapeInfo);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRequestCollisionShapeInformation(b3PhysicsClientHandle physClient, int bodyUniqueId, int linkIndex);
B3_SHARED_API void b3GetCollisionShapeInformation(b3PhysicsClientHandle physClient, struct b3CollisionShapeInformation* collisionShapeInfo);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitLoadTexture(b3PhysicsClientHandle physClient, const char* filename);
B3_SHARED_API int b3GetStatusTextureUniqueId(b3SharedMemoryStatusHandle statusHandle);
B3_SHARED_API b3SharedMemoryCommandHandle b3CreateChangeTextureCommandInit(b3PhysicsClientHandle physClient, int textureUniqueId, int width, int height, const char* rgbPixels);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitUpdateVisualShape(b3PhysicsClientHandle physClient, int bodyUniqueId, int jointIndex, int shapeIndex, int textureUniqueId);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitUpdateVisualShape2(b3PhysicsClientHandle physClient, int bodyUniqueId, int jointIndex, int shapeIndex);
B3_SHARED_API void b3UpdateVisualShapeTexture(b3SharedMemoryCommandHandle commandHandle, int textureUniqueId);
B3_SHARED_API void b3UpdateVisualShapeRGBAColor(b3SharedMemoryCommandHandle commandHandle, const double rgbaColor[/*4*/]);
B3_SHARED_API void b3UpdateVisualShapeFlags(b3SharedMemoryCommandHandle commandHandle, int flags);
B3_SHARED_API void b3UpdateVisualShapeSpecularColor(b3SharedMemoryCommandHandle commandHandle, const double specularColor[/*3*/]);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitPhysicsParamCommand(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitPhysicsParamCommand2(b3SharedMemoryCommandHandle commandHandle);
B3_SHARED_API int b3PhysicsParamSetGravity(b3SharedMemoryCommandHandle commandHandle, double gravx, double gravy, double gravz);
B3_SHARED_API int b3PhysicsParamSetTimeStep(b3SharedMemoryCommandHandle commandHandle, double timeStep);
B3_SHARED_API int b3PhysicsParamSetDefaultContactERP(b3SharedMemoryCommandHandle commandHandle, double defaultContactERP);
B3_SHARED_API int b3PhysicsParamSetDefaultNonContactERP(b3SharedMemoryCommandHandle commandHandle, double defaultNonContactERP);
B3_SHARED_API int b3PhysicsParamSetDefaultFrictionERP(b3SharedMemoryCommandHandle commandHandle, double frictionERP);
B3_SHARED_API int b3PhysicsParamSetDefaultGlobalCFM(b3SharedMemoryCommandHandle commandHandle, double defaultGlobalCFM);
B3_SHARED_API int b3PhysicsParamSetDefaultFrictionCFM(b3SharedMemoryCommandHandle commandHandle, double frictionCFM);
B3_SHARED_API int b3PhysicsParamSetNumSubSteps(b3SharedMemoryCommandHandle commandHandle, int numSubSteps);
B3_SHARED_API int b3PhysicsParamSetRealTimeSimulation(b3SharedMemoryCommandHandle commandHandle, int enableRealTimeSimulation);
B3_SHARED_API int b3PhysicsParamSetNumSolverIterations(b3SharedMemoryCommandHandle commandHandle, int numSolverIterations);
B3_SHARED_API int b3PhysicsParamSetNumNonContactInnerIterations(b3SharedMemoryCommandHandle commandHandle, int numMotorIterations);
B3_SHARED_API int b3PhysicsParamSetWarmStartingFactor(b3SharedMemoryCommandHandle commandHandle, double warmStartingFactor);
B3_SHARED_API int b3PhysicsParamSetArticulatedWarmStartingFactor(b3SharedMemoryCommandHandle commandHandle, double warmStartingFactor);
B3_SHARED_API int b3PhysicsParamSetCollisionFilterMode(b3SharedMemoryCommandHandle commandHandle, int filterMode);
B3_SHARED_API int b3PhysicsParamSetUseSplitImpulse(b3SharedMemoryCommandHandle commandHandle, int useSplitImpulse);
B3_SHARED_API int b3PhysicsParamSetSplitImpulsePenetrationThreshold(b3SharedMemoryCommandHandle commandHandle, double splitImpulsePenetrationThreshold);
B3_SHARED_API int b3PhysicsParamSetContactBreakingThreshold(b3SharedMemoryCommandHandle commandHandle, double contactBreakingThreshold);
B3_SHARED_API int b3PhysicsParamSetMaxNumCommandsPer1ms(b3SharedMemoryCommandHandle commandHandle, int maxNumCmdPer1ms);
B3_SHARED_API int b3PhysicsParamSetEnableFileCaching(b3SharedMemoryCommandHandle commandHandle, int enableFileCaching);
B3_SHARED_API int b3PhysicsParamSetRestitutionVelocityThreshold(b3SharedMemoryCommandHandle commandHandle, double restitutionVelocityThreshold);
B3_SHARED_API int b3PhysicsParamSetEnableConeFriction(b3SharedMemoryCommandHandle commandHandle, int enableConeFriction);
B3_SHARED_API int b3PhysicsParameterSetDeterministicOverlappingPairs(b3SharedMemoryCommandHandle commandHandle, int deterministicOverlappingPairs);
B3_SHARED_API int b3PhysicsParameterSetAllowedCcdPenetration(b3SharedMemoryCommandHandle commandHandle, double allowedCcdPenetration);
B3_SHARED_API int b3PhysicsParameterSetJointFeedbackMode(b3SharedMemoryCommandHandle commandHandle, int jointFeedbackMode);
B3_SHARED_API int b3PhysicsParamSetSolverResidualThreshold(b3SharedMemoryCommandHandle commandHandle, double solverResidualThreshold);
B3_SHARED_API int b3PhysicsParamSetContactSlop(b3SharedMemoryCommandHandle commandHandle, double contactSlop);
B3_SHARED_API int b3PhysicsParameterSetEnableSAT(b3SharedMemoryCommandHandle commandHandle, int enableSAT);
B3_SHARED_API int b3PhysicsParameterSetConstraintSolverType(b3SharedMemoryCommandHandle commandHandle, int constraintSolverType);
B3_SHARED_API int b3PhysicsParameterSetMinimumSolverIslandSize(b3SharedMemoryCommandHandle commandHandle, int minimumSolverIslandSize);
B3_SHARED_API int b3PhysicsParamSetSolverAnalytics(b3SharedMemoryCommandHandle commandHandle, int reportSolverAnalytics);
B3_SHARED_API int b3PhysicsParameterSetSparseSdfVoxelSize(b3SharedMemoryCommandHandle commandHandle, double sparseSdfVoxelSize);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRequestPhysicsParamCommand(b3PhysicsClientHandle physClient);
B3_SHARED_API int b3GetStatusPhysicsSimulationParameters(b3SharedMemoryStatusHandle statusHandle, struct b3PhysicsSimulationParameters* params);
//b3PhysicsParamSetInternalSimFlags is for internal/temporary/easter-egg/experimental demo purposes
//Use at own risk: magic things may or my not happen when calling this API
B3_SHARED_API int b3PhysicsParamSetInternalSimFlags(b3SharedMemoryCommandHandle commandHandle, int flags);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitStepSimulationCommand(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitStepSimulationCommand2(b3SharedMemoryCommandHandle commandHandle);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitPerformCollisionDetectionCommand(b3PhysicsClientHandle physClient);
B3_SHARED_API int b3GetStatusForwardDynamicsAnalyticsData(b3SharedMemoryStatusHandle statusHandle, struct b3ForwardDynamicsAnalyticsArgs* analyticsData);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitResetSimulationCommand(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitResetSimulationCommand2(b3SharedMemoryCommandHandle commandHandle);
B3_SHARED_API int b3InitResetSimulationSetFlags(b3SharedMemoryCommandHandle commandHandle, int flags);
///Load a robot from a URDF file. Status type will CMD_URDF_LOADING_COMPLETED.
///Access the robot from the unique body index, through b3GetStatusBodyIndex(statusHandle);
B3_SHARED_API b3SharedMemoryCommandHandle b3LoadUrdfCommandInit(b3PhysicsClientHandle physClient, const char* urdfFileName);
B3_SHARED_API b3SharedMemoryCommandHandle b3LoadUrdfCommandInit2(b3SharedMemoryCommandHandle commandHandle, const char* urdfFileName);
B3_SHARED_API int b3LoadUrdfCommandSetStartPosition(b3SharedMemoryCommandHandle commandHandle, double startPosX, double startPosY, double startPosZ);
B3_SHARED_API int b3LoadUrdfCommandSetStartOrientation(b3SharedMemoryCommandHandle commandHandle, double startOrnX, double startOrnY, double startOrnZ, double startOrnW);
B3_SHARED_API int b3LoadUrdfCommandSetUseMultiBody(b3SharedMemoryCommandHandle commandHandle, int useMultiBody);
B3_SHARED_API int b3LoadUrdfCommandSetUseFixedBase(b3SharedMemoryCommandHandle commandHandle, int useFixedBase);
B3_SHARED_API int b3LoadUrdfCommandSetFlags(b3SharedMemoryCommandHandle commandHandle, int flags);
B3_SHARED_API int b3LoadUrdfCommandSetGlobalScaling(b3SharedMemoryCommandHandle commandHandle, double globalScaling);
B3_SHARED_API b3SharedMemoryCommandHandle b3SaveStateCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRemoveStateCommand(b3PhysicsClientHandle physClient, int stateId);
B3_SHARED_API int b3GetStatusGetStateId(b3SharedMemoryStatusHandle statusHandle);
B3_SHARED_API b3SharedMemoryCommandHandle b3LoadStateCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API int b3LoadStateSetStateId(b3SharedMemoryCommandHandle commandHandle, int stateId);
B3_SHARED_API int b3LoadStateSetFileName(b3SharedMemoryCommandHandle commandHandle, const char* fileName);
B3_SHARED_API b3SharedMemoryCommandHandle b3LoadBulletCommandInit(b3PhysicsClientHandle physClient, const char* fileName);
B3_SHARED_API b3SharedMemoryCommandHandle b3SaveBulletCommandInit(b3PhysicsClientHandle physClient, const char* fileName);
B3_SHARED_API b3SharedMemoryCommandHandle b3LoadMJCFCommandInit(b3PhysicsClientHandle physClient, const char* fileName);
B3_SHARED_API b3SharedMemoryCommandHandle b3LoadMJCFCommandInit2(b3SharedMemoryCommandHandle commandHandle, const char* fileName);
B3_SHARED_API void b3LoadMJCFCommandSetFlags(b3SharedMemoryCommandHandle commandHandle, int flags);
B3_SHARED_API void b3LoadMJCFCommandSetUseMultiBody(b3SharedMemoryCommandHandle commandHandle, int useMultiBody);
///compute the forces to achieve an acceleration, given a state q and qdot using inverse dynamics
B3_SHARED_API b3SharedMemoryCommandHandle b3CalculateInverseDynamicsCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId,
const double* jointPositionsQ, const double* jointVelocitiesQdot, const double* jointAccelerations);
B3_SHARED_API b3SharedMemoryCommandHandle b3CalculateInverseDynamicsCommandInit2(b3PhysicsClientHandle physClient, int bodyUniqueId,
const double* jointPositionsQ, int dofCountQ, const double* jointVelocitiesQdot, const double* jointAccelerations, int dofCountQdot);
B3_SHARED_API void b3CalculateInverseDynamicsSetFlags(b3SharedMemoryCommandHandle commandHandle, int flags);
B3_SHARED_API int b3GetStatusInverseDynamicsJointForces(b3SharedMemoryStatusHandle statusHandle,
int* bodyUniqueId,
int* dofCount,
double* jointForces);
B3_SHARED_API b3SharedMemoryCommandHandle b3CalculateJacobianCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId, int linkIndex, const double* localPosition, const double* jointPositionsQ, const double* jointVelocitiesQdot, const double* jointAccelerations);
B3_SHARED_API int b3GetStatusJacobian(b3SharedMemoryStatusHandle statusHandle,
int* dofCount,
double* linearJacobian,
double* angularJacobian);
B3_SHARED_API b3SharedMemoryCommandHandle b3CalculateMassMatrixCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId, const double* jointPositionsQ, int dofCountQ);
B3_SHARED_API void b3CalculateMassMatrixSetFlags(b3SharedMemoryCommandHandle commandHandle, int flags);
///the mass matrix is stored in column-major layout of size dofCount*dofCount
B3_SHARED_API int b3GetStatusMassMatrix(b3PhysicsClientHandle physClient, b3SharedMemoryStatusHandle statusHandle, int* dofCount, double* massMatrix);
///compute the joint positions to move the end effector to a desired target using inverse kinematics
B3_SHARED_API b3SharedMemoryCommandHandle b3CalculateInverseKinematicsCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId);
B3_SHARED_API void b3CalculateInverseKinematicsAddTargetPurePosition(b3SharedMemoryCommandHandle commandHandle, int endEffectorLinkIndex, const double targetPosition[/*3*/]);
B3_SHARED_API void b3CalculateInverseKinematicsAddTargetsPurePosition(b3SharedMemoryCommandHandle commandHandle, int numEndEffectorLinkIndices, const int* endEffectorIndices, const double* targetPositions);
B3_SHARED_API void b3CalculateInverseKinematicsAddTargetPositionWithOrientation(b3SharedMemoryCommandHandle commandHandle, int endEffectorLinkIndex, const double targetPosition[/*3*/], const double targetOrientation[/*4*/]);
B3_SHARED_API void b3CalculateInverseKinematicsPosWithNullSpaceVel(b3SharedMemoryCommandHandle commandHandle, int numDof, int endEffectorLinkIndex, const double targetPosition[/*3*/], const double* lowerLimit, const double* upperLimit, const double* jointRange, const double* restPose);
B3_SHARED_API void b3CalculateInverseKinematicsPosOrnWithNullSpaceVel(b3SharedMemoryCommandHandle commandHandle, int numDof, int endEffectorLinkIndex, const double targetPosition[/*3*/], const double targetOrientation[/*4*/], const double* lowerLimit, const double* upperLimit, const double* jointRange, const double* restPose);
B3_SHARED_API void b3CalculateInverseKinematicsSetJointDamping(b3SharedMemoryCommandHandle commandHandle, int numDof, const double* jointDampingCoeff);
B3_SHARED_API void b3CalculateInverseKinematicsSelectSolver(b3SharedMemoryCommandHandle commandHandle, int solver);
B3_SHARED_API int b3GetStatusInverseKinematicsJointPositions(b3SharedMemoryStatusHandle statusHandle,
int* bodyUniqueId,
int* dofCount,
double* jointPositions);
B3_SHARED_API void b3CalculateInverseKinematicsSetCurrentPositions(b3SharedMemoryCommandHandle commandHandle, int numDof, const double* currentJointPositions);
B3_SHARED_API void b3CalculateInverseKinematicsSetMaxNumIterations(b3SharedMemoryCommandHandle commandHandle, int maxNumIterations);
B3_SHARED_API void b3CalculateInverseKinematicsSetResidualThreshold(b3SharedMemoryCommandHandle commandHandle, double residualThreshold);
B3_SHARED_API b3SharedMemoryCommandHandle b3CollisionFilterCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API void b3SetCollisionFilterPair(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueIdA,
int bodyUniqueIdB, int linkIndexA, int linkIndexB, int enableCollision);
B3_SHARED_API void b3SetCollisionFilterGroupMask(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueIdA,
int linkIndexA, int collisionFilterGroup, int collisionFilterMask);
B3_SHARED_API b3SharedMemoryCommandHandle b3LoadSdfCommandInit(b3PhysicsClientHandle physClient, const char* sdfFileName);
B3_SHARED_API b3SharedMemoryCommandHandle b3LoadSdfCommandInit2(b3SharedMemoryCommandHandle commandHandle, const char* sdfFileName);
B3_SHARED_API int b3LoadSdfCommandSetUseMultiBody(b3SharedMemoryCommandHandle commandHandle, int useMultiBody);
B3_SHARED_API int b3LoadSdfCommandSetUseGlobalScaling(b3SharedMemoryCommandHandle commandHandle, double globalScaling);
B3_SHARED_API b3SharedMemoryCommandHandle b3SaveWorldCommandInit(b3PhysicsClientHandle physClient, const char* sdfFileName);
///The b3JointControlCommandInit method is obsolete, use b3JointControlCommandInit2 instead
B3_SHARED_API b3SharedMemoryCommandHandle b3JointControlCommandInit(b3PhysicsClientHandle physClient, int controlMode);
///Set joint motor control variables such as desired position/angle, desired velocity,
///applied joint forces, dependent on the control mode (CONTROL_MODE_VELOCITY or CONTROL_MODE_TORQUE)
B3_SHARED_API b3SharedMemoryCommandHandle b3JointControlCommandInit2(b3PhysicsClientHandle physClient, int bodyUniqueId, int controlMode);
B3_SHARED_API b3SharedMemoryCommandHandle b3JointControlCommandInit2Internal(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int controlMode);
///Only use when controlMode is CONTROL_MODE_POSITION_VELOCITY_PD
B3_SHARED_API int b3JointControlSetDesiredPosition(b3SharedMemoryCommandHandle commandHandle, int qIndex, double value);
B3_SHARED_API int b3JointControlSetDesiredPositionMultiDof(b3SharedMemoryCommandHandle commandHandle, int qIndex, const double* position, int dofCount);
B3_SHARED_API int b3JointControlSetKp(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double value);
B3_SHARED_API int b3JointControlSetKpMultiDof(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double* kps, int dofCount);
B3_SHARED_API int b3JointControlSetKd(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double value);
B3_SHARED_API int b3JointControlSetKdMultiDof(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double* kds, int dofCount);
B3_SHARED_API int b3JointControlSetMaximumVelocity(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double maximumVelocity);
///Only use when controlMode is CONTROL_MODE_VELOCITY
B3_SHARED_API int b3JointControlSetDesiredVelocity(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double value); /* find a better name for dof/q/u indices, point to b3JointInfo */
B3_SHARED_API int b3JointControlSetDesiredVelocityMultiDof(b3SharedMemoryCommandHandle commandHandle, int dofIndex, const double* velocity, int dofCount);
B3_SHARED_API int b3JointControlSetDesiredVelocityMultiDof2(b3SharedMemoryCommandHandle commandHandle, int dofIndex, const double* velocity, int dofCount);
B3_SHARED_API int b3JointControlSetMaximumForce(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double value);
B3_SHARED_API int b3JointControlSetDesiredForceTorqueMultiDof(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double* forces, int dofCount);
B3_SHARED_API int b3JointControlSetDamping(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double value);
B3_SHARED_API int b3JointControlSetDampingMultiDof(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double* damping, int dofCount);
///Only use if when controlMode is CONTROL_MODE_TORQUE,
B3_SHARED_API int b3JointControlSetDesiredForceTorque(b3SharedMemoryCommandHandle commandHandle, int dofIndex, double value);
///the creation of collision shapes and rigid bodies etc is likely going to change,
///but good to have a b3CreateBoxShapeCommandInit for now
B3_SHARED_API b3SharedMemoryCommandHandle b3CreateCollisionShapeCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API int b3CreateCollisionShapeAddSphere(b3SharedMemoryCommandHandle commandHandle, double radius);
B3_SHARED_API int b3CreateCollisionShapeAddBox(b3SharedMemoryCommandHandle commandHandle, const double halfExtents[/*3*/]);
B3_SHARED_API int b3CreateCollisionShapeAddCapsule(b3SharedMemoryCommandHandle commandHandle, double radius, double height);
B3_SHARED_API int b3CreateCollisionShapeAddCylinder(b3SharedMemoryCommandHandle commandHandle, double radius, double height);
B3_SHARED_API int b3CreateCollisionShapeAddHeightfield(b3SharedMemoryCommandHandle commandHandle, const char* fileName, const double meshScale[/*3*/], double textureScaling);
B3_SHARED_API int b3CreateCollisionShapeAddHeightfield2(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, const double meshScale[/*3*/], double textureScaling, float* heightfieldData, int numHeightfieldRows, int numHeightfieldColumns, int replaceHeightfieldIndex);
B3_SHARED_API int b3CreateCollisionShapeAddPlane(b3SharedMemoryCommandHandle commandHandle, const double planeNormal[/*3*/], double planeConstant);
B3_SHARED_API int b3CreateCollisionShapeAddMesh(b3SharedMemoryCommandHandle commandHandle, const char* fileName, const double meshScale[/*3*/]);
B3_SHARED_API int b3CreateCollisionShapeAddConvexMesh(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, const double meshScale[/*3*/], const double* vertices, int numVertices);
B3_SHARED_API int b3CreateCollisionShapeAddConcaveMesh(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, const double meshScale[/*3*/], const double* vertices, int numVertices, const int* indices, int numIndices);
B3_SHARED_API void b3CreateCollisionSetFlag(b3SharedMemoryCommandHandle commandHandle, int shapeIndex, int flags);
B3_SHARED_API void b3CreateCollisionShapeSetChildTransform(b3SharedMemoryCommandHandle commandHandle, int shapeIndex, const double childPosition[/*3*/], const double childOrientation[/*4*/]);
B3_SHARED_API int b3GetStatusCollisionShapeUniqueId(b3SharedMemoryStatusHandle statusHandle);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRemoveCollisionShapeCommand(b3PhysicsClientHandle physClient, int collisionShapeId);
B3_SHARED_API b3SharedMemoryCommandHandle b3GetMeshDataCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId, int linkIndex);
B3_SHARED_API void b3GetMeshDataSimulationMesh(b3SharedMemoryCommandHandle commandHandle);
B3_SHARED_API void b3MeshDataSimulationMeshVelocity(b3SharedMemoryCommandHandle commandHandle);
B3_SHARED_API void b3GetMeshDataSetCollisionShapeIndex(b3SharedMemoryCommandHandle commandHandle, int shapeIndex);
B3_SHARED_API void b3GetMeshDataSetFlags(b3SharedMemoryCommandHandle commandHandle, int flags);
B3_SHARED_API void b3GetMeshData(b3PhysicsClientHandle physClient, struct b3MeshData* meshData);
B3_SHARED_API b3SharedMemoryCommandHandle b3ResetMeshDataCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId, int num_vertices, const double* vertices);
B3_SHARED_API b3SharedMemoryCommandHandle b3CreateVisualShapeCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API int b3CreateVisualShapeAddSphere(b3SharedMemoryCommandHandle commandHandle, double radius);
B3_SHARED_API int b3CreateVisualShapeAddBox(b3SharedMemoryCommandHandle commandHandle, const double halfExtents[/*3*/]);
B3_SHARED_API int b3CreateVisualShapeAddCapsule(b3SharedMemoryCommandHandle commandHandle, double radius, double height);
B3_SHARED_API int b3CreateVisualShapeAddCylinder(b3SharedMemoryCommandHandle commandHandle, double radius, double height);
B3_SHARED_API int b3CreateVisualShapeAddPlane(b3SharedMemoryCommandHandle commandHandle, const double planeNormal[/*3*/], double planeConstant);
B3_SHARED_API int b3CreateVisualShapeAddMesh(b3SharedMemoryCommandHandle commandHandle, const char* fileName, const double meshScale[/*3*/]);
B3_SHARED_API int b3CreateVisualShapeAddMesh2(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, const double meshScale[/*3*/], const double* vertices, int numVertices, const int* indices, int numIndices, const double* normals, int numNormals, const double* uvs, int numUVs);
B3_SHARED_API void b3CreateVisualSetFlag(b3SharedMemoryCommandHandle commandHandle, int shapeIndex, int flags);
B3_SHARED_API void b3CreateVisualShapeSetChildTransform(b3SharedMemoryCommandHandle commandHandle, int shapeIndex, const double childPosition[/*3*/], const double childOrientation[/*4*/]);
B3_SHARED_API void b3CreateVisualShapeSetSpecularColor(b3SharedMemoryCommandHandle commandHandle, int shapeIndex, const double specularColor[/*3*/]);
B3_SHARED_API void b3CreateVisualShapeSetRGBAColor(b3SharedMemoryCommandHandle commandHandle, int shapeIndex, const double rgbaColor[/*4*/]);
B3_SHARED_API int b3GetStatusVisualShapeUniqueId(b3SharedMemoryStatusHandle statusHandle);
B3_SHARED_API b3SharedMemoryCommandHandle b3CreateMultiBodyCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API int b3CreateMultiBodyBase(b3SharedMemoryCommandHandle commandHandle, double mass, int collisionShapeUnique, int visualShapeUniqueId, const double basePosition[/*3*/], const double baseOrientation[/*4*/], const double baseInertialFramePosition[/*3*/], const double baseInertialFrameOrientation[/*4*/]);
B3_SHARED_API int b3CreateMultiBodyLink(b3SharedMemoryCommandHandle commandHandle, double linkMass, double linkCollisionShapeIndex,
double linkVisualShapeIndex,
const double linkPosition[/*3*/],
const double linkOrientation[/*4*/],
const double linkInertialFramePosition[/*3*/],
const double linkInertialFrameOrientation[/*4*/],
int linkParentIndex,
int linkJointType,
const double linkJointAxis[/*3*/]);
//batch creation is an performance feature to create a large number of multi bodies in one command
B3_SHARED_API int b3CreateMultiBodySetBatchPositions(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, double* batchPositions, int numBatchObjects);
//useMaximalCoordinates are disabled by default, enabling them is experimental and not fully supported yet
B3_SHARED_API void b3CreateMultiBodyUseMaximalCoordinates(b3SharedMemoryCommandHandle commandHandle);
B3_SHARED_API void b3CreateMultiBodySetFlags(b3SharedMemoryCommandHandle commandHandle, int flags);
//int b3CreateMultiBodyAddLink(b3SharedMemoryCommandHandle commandHandle, int jointType, int parentLinkIndex, double linkMass, int linkCollisionShapeUnique, int linkVisualShapeUniqueId);
///create a box of size (1,1,1) at world origin (0,0,0) at orientation quat (0,0,0,1)
///after that, you can optionally adjust the initial position, orientation and size
B3_SHARED_API b3SharedMemoryCommandHandle b3CreateBoxShapeCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API int b3CreateBoxCommandSetStartPosition(b3SharedMemoryCommandHandle commandHandle, double startPosX, double startPosY, double startPosZ);
B3_SHARED_API int b3CreateBoxCommandSetStartOrientation(b3SharedMemoryCommandHandle commandHandle, double startOrnX, double startOrnY, double startOrnZ, double startOrnW);
B3_SHARED_API int b3CreateBoxCommandSetHalfExtents(b3SharedMemoryCommandHandle commandHandle, double halfExtentsX, double halfExtentsY, double halfExtentsZ);
B3_SHARED_API int b3CreateBoxCommandSetMass(b3SharedMemoryCommandHandle commandHandle, double mass);
B3_SHARED_API int b3CreateBoxCommandSetCollisionShapeType(b3SharedMemoryCommandHandle commandHandle, int collisionShapeType);
B3_SHARED_API int b3CreateBoxCommandSetColorRGBA(b3SharedMemoryCommandHandle commandHandle, double red, double green, double blue, double alpha);
///b3CreatePoseCommandInit will initialize (teleport) the pose of a body/robot. You can individually set the base position,
///base orientation and joint angles. This will set all velocities of base and joints to zero.
///This is not a robot control command using actuators/joint motors, but manual repositioning the robot.
B3_SHARED_API b3SharedMemoryCommandHandle b3CreatePoseCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId);
B3_SHARED_API b3SharedMemoryCommandHandle b3CreatePoseCommandInit2(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId);
B3_SHARED_API int b3CreatePoseCommandSetBasePosition(b3SharedMemoryCommandHandle commandHandle, double startPosX, double startPosY, double startPosZ);
B3_SHARED_API int b3CreatePoseCommandSetBaseOrientation(b3SharedMemoryCommandHandle commandHandle, double startOrnX, double startOrnY, double startOrnZ, double startOrnW);
B3_SHARED_API int b3CreatePoseCommandSetBaseLinearVelocity(b3SharedMemoryCommandHandle commandHandle, const double linVel[/*3*/]);
B3_SHARED_API int b3CreatePoseCommandSetBaseAngularVelocity(b3SharedMemoryCommandHandle commandHandle, const double angVel[/*3*/]);
B3_SHARED_API int b3CreatePoseCommandSetBaseScaling(b3SharedMemoryCommandHandle commandHandle, double scaling[/* 3*/]);
B3_SHARED_API int b3CreatePoseCommandSetJointPositions(b3SharedMemoryCommandHandle commandHandle, int numJointPositions, const double* jointPositions);
B3_SHARED_API int b3CreatePoseCommandSetJointPosition(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, int jointIndex, double jointPosition);
B3_SHARED_API int b3CreatePoseCommandSetJointPositionMultiDof(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, int jointIndex, const double* jointPosition, int posSize);
B3_SHARED_API int b3CreatePoseCommandSetQ(b3SharedMemoryCommandHandle commandHandle, int numJointPositions, const double* q, const int* hasQ);
B3_SHARED_API int b3CreatePoseCommandSetQdots(b3SharedMemoryCommandHandle commandHandle, int numJointVelocities, const double* qDots, const int* hasQdots);
B3_SHARED_API int b3CreatePoseCommandSetJointVelocities(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, int numJointVelocities, const double* jointVelocities);
B3_SHARED_API int b3CreatePoseCommandSetJointVelocity(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, int jointIndex, double jointVelocity);
B3_SHARED_API int b3CreatePoseCommandSetJointVelocityMultiDof(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, int jointIndex, const double* jointVelocity, int velSize);
///We are currently not reading the sensor information from the URDF file, and programmatically assign sensors.
///This is rather inconsistent, to mix programmatical creation with loading from file.
B3_SHARED_API b3SharedMemoryCommandHandle b3CreateSensorCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId);
B3_SHARED_API int b3CreateSensorEnable6DofJointForceTorqueSensor(b3SharedMemoryCommandHandle commandHandle, int jointIndex, int enable);
///b3CreateSensorEnableIMUForLink is not implemented yet.
///For now, if the IMU is located in the root link, use the root world transform to mimic an IMU.
B3_SHARED_API int b3CreateSensorEnableIMUForLink(b3SharedMemoryCommandHandle commandHandle, int linkIndex, int enable);
B3_SHARED_API b3SharedMemoryCommandHandle b3RequestActualStateCommandInit(b3PhysicsClientHandle physClient, int bodyUniqueId);
B3_SHARED_API b3SharedMemoryCommandHandle b3RequestActualStateCommandInit2(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId);
B3_SHARED_API int b3RequestActualStateCommandComputeLinkVelocity(b3SharedMemoryCommandHandle commandHandle, int computeLinkVelocity);
B3_SHARED_API int b3RequestActualStateCommandComputeForwardKinematics(b3SharedMemoryCommandHandle commandHandle, int computeForwardKinematics);
B3_SHARED_API int b3GetJointState(b3PhysicsClientHandle physClient, b3SharedMemoryStatusHandle statusHandle, int jointIndex, struct b3JointSensorState* state);
B3_SHARED_API int b3GetJointStateMultiDof(b3PhysicsClientHandle physClient, b3SharedMemoryStatusHandle statusHandle, int jointIndex, struct b3JointSensorState2* state);
B3_SHARED_API int b3GetLinkState(b3PhysicsClientHandle physClient, b3SharedMemoryStatusHandle statusHandle, int linkIndex, struct b3LinkState* state);
B3_SHARED_API b3SharedMemoryCommandHandle b3PickBody(b3PhysicsClientHandle physClient, double rayFromWorldX,
double rayFromWorldY, double rayFromWorldZ,
double rayToWorldX, double rayToWorldY, double rayToWorldZ);
B3_SHARED_API b3SharedMemoryCommandHandle b3MovePickedBody(b3PhysicsClientHandle physClient, double rayFromWorldX,
double rayFromWorldY, double rayFromWorldZ,
double rayToWorldX, double rayToWorldY,
double rayToWorldZ);
B3_SHARED_API b3SharedMemoryCommandHandle b3RemovePickingConstraint(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3CreateRaycastCommandInit(b3PhysicsClientHandle physClient, double rayFromWorldX,
double rayFromWorldY, double rayFromWorldZ,
double rayToWorldX, double rayToWorldY, double rayToWorldZ);
B3_SHARED_API b3SharedMemoryCommandHandle b3CreateRaycastBatchCommandInit(b3PhysicsClientHandle physClient);
// Sets the number of threads to use to compute the ray intersections for the batch. Specify 0 to let Bullet decide, 1 (default) for single core execution, 2 or more to select the number of threads to use.
B3_SHARED_API void b3RaycastBatchSetNumThreads(b3SharedMemoryCommandHandle commandHandle, int numThreads);
//max num rays for b3RaycastBatchAddRay is MAX_RAY_INTERSECTION_BATCH_SIZE
B3_SHARED_API void b3RaycastBatchAddRay(b3SharedMemoryCommandHandle commandHandle, const double rayFromWorld[/*3*/], const double rayToWorld[/*3*/]);
//max num rays for b3RaycastBatchAddRays is MAX_RAY_INTERSECTION_BATCH_SIZE_STREAMING
B3_SHARED_API void b3RaycastBatchAddRays(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, const double* rayFromWorld, const double* rayToWorld, int numRays);
B3_SHARED_API void b3RaycastBatchSetParentObject(b3SharedMemoryCommandHandle commandHandle, int parentObjectUniqueId, int parentLinkIndex);
B3_SHARED_API void b3RaycastBatchSetReportHitNumber(b3SharedMemoryCommandHandle commandHandle, int reportHitNumber);
B3_SHARED_API void b3RaycastBatchSetCollisionFilterMask(b3SharedMemoryCommandHandle commandHandle, int collisionFilterMask);
B3_SHARED_API void b3RaycastBatchSetFractionEpsilon(b3SharedMemoryCommandHandle commandHandle, double fractionEpsilon);
B3_SHARED_API void b3GetRaycastInformation(b3PhysicsClientHandle physClient, struct b3RaycastInformation* raycastInfo);
/// Apply external force at the body (or link) center of mass, in world space/Cartesian coordinates.
B3_SHARED_API b3SharedMemoryCommandHandle b3ApplyExternalForceCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API void b3ApplyExternalForce(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkId, const double force[/*3*/], const double position[/*3*/], int flag);
B3_SHARED_API void b3ApplyExternalTorque(b3SharedMemoryCommandHandle commandHandle, int bodyUniqueId, int linkId, const double torque[/*3*/], int flag);
///experiments of robots interacting with non-rigid objects (such as btSoftBody)
B3_SHARED_API b3SharedMemoryCommandHandle b3LoadSoftBodyCommandInit(b3PhysicsClientHandle physClient, const char* fileName);
B3_SHARED_API int b3LoadSoftBodySetScale(b3SharedMemoryCommandHandle commandHandle, double scale);
B3_SHARED_API int b3LoadSoftBodySetMass(b3SharedMemoryCommandHandle commandHandle, double mass);
B3_SHARED_API int b3LoadSoftBodySetCollisionMargin(b3SharedMemoryCommandHandle commandHandle, double collisionMargin);
B3_SHARED_API int b3LoadSoftBodySetStartPosition(b3SharedMemoryCommandHandle commandHandle, double startPosX, double startPosY, double startPosZ);
B3_SHARED_API int b3LoadSoftBodySetStartOrientation(b3SharedMemoryCommandHandle commandHandle, double startOrnX, double startOrnY, double startOrnZ, double startOrnW);
B3_SHARED_API int b3LoadSoftBodyUpdateSimMesh(b3SharedMemoryCommandHandle commandHandle, const char* filename);
B3_SHARED_API int b3LoadSoftBodyAddCorotatedForce(b3SharedMemoryCommandHandle commandHandle, double corotatedMu, double corotatedLambda);
B3_SHARED_API int b3LoadSoftBodyAddCorotatedForce(b3SharedMemoryCommandHandle commandHandle, double corotatedMu, double corotatedLambda);
B3_SHARED_API int b3LoadSoftBodyAddNeoHookeanForce(b3SharedMemoryCommandHandle commandHandle, double NeoHookeanMu, double NeoHookeanLambda, double NeoHookeanDamping);
B3_SHARED_API int b3LoadSoftBodyAddMassSpringForce(b3SharedMemoryCommandHandle commandHandle, double springElasticStiffness , double springDampingStiffness);
B3_SHARED_API int b3LoadSoftBodyAddGravityForce(b3SharedMemoryCommandHandle commandHandle, double gravityX, double gravityY, double gravityZ);
B3_SHARED_API int b3LoadSoftBodySetCollisionHardness(b3SharedMemoryCommandHandle commandHandle, double collisionHardness);
B3_SHARED_API int b3LoadSoftBodySetSelfCollision(b3SharedMemoryCommandHandle commandHandle, int useSelfCollision);
B3_SHARED_API int b3LoadSoftBodySetRepulsionStiffness(b3SharedMemoryCommandHandle commandHandle, double stiffness);
B3_SHARED_API int b3LoadSoftBodyUseFaceContact(b3SharedMemoryCommandHandle commandHandle, int useFaceContact);
B3_SHARED_API int b3LoadSoftBodySetFrictionCoefficient(b3SharedMemoryCommandHandle commandHandle, double frictionCoefficient);
B3_SHARED_API int b3LoadSoftBodyUseBendingSprings(b3SharedMemoryCommandHandle commandHandle, int useBendingSprings, double bendingStiffness);
B3_SHARED_API int b3LoadSoftBodyUseAllDirectionDampingSprings(b3SharedMemoryCommandHandle commandHandle, int useAllDirectionDamping);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitCreateSoftBodyAnchorConstraintCommand(b3PhysicsClientHandle physClient, int softBodyUniqueId, int nodeIndex, int bodyUniqueId, int linkIndex, const double bodyFramePosition[3]);
B3_SHARED_API b3SharedMemoryCommandHandle b3RequestVREventsCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API void b3VREventsSetDeviceTypeFilter(b3SharedMemoryCommandHandle commandHandle, int deviceTypeFilter);
B3_SHARED_API void b3GetVREventsData(b3PhysicsClientHandle physClient, struct b3VREventsData* vrEventsData);
B3_SHARED_API b3SharedMemoryCommandHandle b3SetVRCameraStateCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API int b3SetVRCameraRootPosition(b3SharedMemoryCommandHandle commandHandle, const double rootPos[/*3*/]);
B3_SHARED_API int b3SetVRCameraRootOrientation(b3SharedMemoryCommandHandle commandHandle, const double rootOrn[/*4*/]);
B3_SHARED_API int b3SetVRCameraTrackingObject(b3SharedMemoryCommandHandle commandHandle, int objectUniqueId);
B3_SHARED_API int b3SetVRCameraTrackingObjectFlag(b3SharedMemoryCommandHandle commandHandle, int flag);
B3_SHARED_API b3SharedMemoryCommandHandle b3RequestKeyboardEventsCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3RequestKeyboardEventsCommandInit2(b3SharedMemoryCommandHandle commandHandle);
B3_SHARED_API void b3GetKeyboardEventsData(b3PhysicsClientHandle physClient, struct b3KeyboardEventsData* keyboardEventsData);
B3_SHARED_API b3SharedMemoryCommandHandle b3RequestMouseEventsCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API void b3GetMouseEventsData(b3PhysicsClientHandle physClient, struct b3MouseEventsData* mouseEventsData);
B3_SHARED_API b3SharedMemoryCommandHandle b3StateLoggingCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API int b3StateLoggingStart(b3SharedMemoryCommandHandle commandHandle, int loggingType, const char* fileName);
B3_SHARED_API int b3StateLoggingAddLoggingObjectUniqueId(b3SharedMemoryCommandHandle commandHandle, int objectUniqueId);
B3_SHARED_API int b3StateLoggingSetMaxLogDof(b3SharedMemoryCommandHandle commandHandle, int maxLogDof);
B3_SHARED_API int b3StateLoggingSetLinkIndexA(b3SharedMemoryCommandHandle commandHandle, int linkIndexA);
B3_SHARED_API int b3StateLoggingSetLinkIndexB(b3SharedMemoryCommandHandle commandHandle, int linkIndexB);
B3_SHARED_API int b3StateLoggingSetBodyAUniqueId(b3SharedMemoryCommandHandle commandHandle, int bodyAUniqueId);
B3_SHARED_API int b3StateLoggingSetBodyBUniqueId(b3SharedMemoryCommandHandle commandHandle, int bodyBUniqueId);
B3_SHARED_API int b3StateLoggingSetDeviceTypeFilter(b3SharedMemoryCommandHandle commandHandle, int deviceTypeFilter);
B3_SHARED_API int b3StateLoggingSetLogFlags(b3SharedMemoryCommandHandle commandHandle, int logFlags);
B3_SHARED_API int b3GetStatusLoggingUniqueId(b3SharedMemoryStatusHandle statusHandle);
B3_SHARED_API int b3StateLoggingStop(b3SharedMemoryCommandHandle commandHandle, int loggingUid);
B3_SHARED_API b3SharedMemoryCommandHandle b3ProfileTimingCommandInit(b3PhysicsClientHandle physClient, const char* name);
B3_SHARED_API void b3SetProfileTimingDuractionInMicroSeconds(b3SharedMemoryCommandHandle commandHandle, int duration);
B3_SHARED_API void b3SetProfileTimingType(b3SharedMemoryCommandHandle commandHandle, int type);
B3_SHARED_API void b3PushProfileTiming(b3PhysicsClientHandle physClient, const char* timingName);
B3_SHARED_API void b3PopProfileTiming(b3PhysicsClientHandle physClient);
B3_SHARED_API void b3SetTimeOut(b3PhysicsClientHandle physClient, double timeOutInSeconds);
B3_SHARED_API double b3GetTimeOut(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3SetAdditionalSearchPath(b3PhysicsClientHandle physClient, const char* path);
B3_SHARED_API void b3MultiplyTransforms(const double posA[/*3*/], const double ornA[/*4*/], const double posB[/*3*/], const double ornB[/*4*/], double outPos[/*3*/], double outOrn[/*4*/]);
B3_SHARED_API void b3InvertTransform(const double pos[/*3*/], const double orn[/*4*/], double outPos[/*3*/], double outOrn[/*4*/]);
B3_SHARED_API void b3QuaternionSlerp(const double startQuat[/*4*/], const double endQuat[/*4*/], double interpolationFraction, double outOrn[/*4*/]);
B3_SHARED_API void b3GetQuaternionFromAxisAngle(const double axis[/*3*/], double angle, double outQuat[/*4*/]);
B3_SHARED_API void b3GetAxisAngleFromQuaternion(const double quat[/*4*/], double axis[/*3*/], double* angle);
B3_SHARED_API void b3GetQuaternionDifference(const double startQuat[/*4*/], const double endQuat[/*4*/], double outOrn[/*4*/]);
B3_SHARED_API void b3GetAxisDifferenceQuaternion(const double startQuat[/*4*/], const double endQuat[/*4*/], double axisOut[/*3*/]);
B3_SHARED_API void b3CalculateVelocityQuaternion(const double startQuat[/*4*/], const double endQuat[/*4*/], double deltaTime, double angVelOut[/*3*/]);
B3_SHARED_API void b3RotateVector(const double quat[/*4*/], const double vec[/*3*/], double vecOut[/*3*/]);
#ifdef BT_ENABLE_VHACD
B3_SHARED_API void b3VHACD(const char* fileNameInput, const char* fileNameOutput, const char* fileNameLogging,
double concavity, double alpha, double beta, double gamma, double minVolumePerCH, int resolution,
int maxNumVerticesPerCH, int depth, int planeDownsampling, int convexhullDownsampling,
int pca, int mode, int convexhullApproximation);
#endif
#ifdef __cplusplus
}
#endif
#endif //PHYSICS_CLIENT_C_API_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,13 @@
#ifndef PHYSICS_CLIENT_EXAMPLE_H
#define PHYSICS_CLIENT_EXAMPLE_H
enum ClientExampleOptions
{
eCLIENTEXAMPLE_LOOPBACK = 1,
eCLIENTEXAMPLE_DIRECT = 2,
eCLIENTEXAMPLE_SERVER = 3,
};
class CommonExampleInterface* PhysicsClientCreateFunc(struct CommonExampleOptions& options);
#endif //PHYSICS_CLIENT_EXAMPLE_H

View file

@ -0,0 +1,224 @@
#ifdef BT_ENABLE_GRPC
#include "PhysicsClientGRPC.h"
#include "SharedMemory/grpc/proto/pybullet.grpc.pb.h"
#include <grpc++/grpc++.h>
using grpc::Channel;
#include <stdio.h>
#include <string.h>
#include "../Utils/b3Clock.h"
#include "PhysicsClient.h"
//#include "LinearMath/btVector3.h"
#include "SharedMemoryCommands.h"
#include <string>
#include "Bullet3Common/b3Logging.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "SharedMemory/grpc/ConvertGRPCBullet.h"
using pybullet_grpc::grpc::PyBulletAPI;
static unsigned int b3DeserializeInt2(const unsigned char* input)
{
unsigned int tmp = (input[3] << 24) + (input[2] << 16) + (input[1] << 8) + input[0];
return tmp;
}
bool gVerboseNetworkMessagesClient3 = false;
struct GRPCNetworkedInternalData
{
std::shared_ptr<grpc::Channel> m_grpcChannel;
std::unique_ptr<PyBulletAPI::Stub> m_stub;
bool m_isConnected;
SharedMemoryCommand m_clientCmd;
bool m_hasCommand;
SharedMemoryStatus m_lastStatus;
b3AlignedObjectArray<char> m_stream;
std::string m_hostName;
int m_port;
b3AlignedObjectArray<unsigned char> m_tempBuffer;
double m_timeOutInSeconds;
GRPCNetworkedInternalData()
: m_isConnected(false),
m_hasCommand(false),
m_timeOutInSeconds(60)
{
}
void disconnect()
{
if (m_isConnected)
{
m_stub = 0;
m_grpcChannel = 0;
m_isConnected = false;
}
}
bool connectGRPC()
{
if (m_isConnected)
return true;
std::string hostport = m_hostName;
if (m_port >= 0)
{
hostport += ':' + std::to_string(m_port);
}
m_grpcChannel = grpc::CreateChannel(
hostport, grpc::InsecureChannelCredentials());
m_stub = PyBulletAPI::NewStub(m_grpcChannel);
// Set timeout for API
std::chrono::system_clock::time_point deadline =
std::chrono::system_clock::now() + std::chrono::seconds((long long)m_timeOutInSeconds);
grpc::ClientContext context;
context.set_deadline(deadline);
::pybullet_grpc::PyBulletCommand request;
pybullet_grpc::CheckVersionCommand* cmd1 = request.mutable_checkversioncommand();
cmd1->set_clientversion(SHARED_MEMORY_MAGIC_NUMBER);
::pybullet_grpc::PyBulletStatus response;
// The actual RPC.
grpc::Status status = m_stub->SubmitCommand(&context, request, &response);
if (response.has_checkversionstatus())
{
if (response.checkversionstatus().serverversion() == SHARED_MEMORY_MAGIC_NUMBER)
{
m_isConnected = true;
}
else
{
printf("Error: Client version (%d) is different from server version (%d)", SHARED_MEMORY_MAGIC_NUMBER, response.checkversionstatus().serverversion());
}
}
else
{
printf("Error: cannot connect to GRPC server\n");
}
return m_isConnected;
}
bool checkData()
{
bool hasStatus = false;
return hasStatus;
}
};
GRPCNetworkedPhysicsProcessor::GRPCNetworkedPhysicsProcessor(const char* hostName, int port)
{
m_data = new GRPCNetworkedInternalData;
if (hostName)
{
m_data->m_hostName = hostName;
}
m_data->m_port = port;
}
GRPCNetworkedPhysicsProcessor::~GRPCNetworkedPhysicsProcessor()
{
disconnect();
delete m_data;
}
bool GRPCNetworkedPhysicsProcessor::processCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
{
if (gVerboseNetworkMessagesClient3)
{
printf("GRPCNetworkedPhysicsProcessor::processCommand\n");
}
::pybullet_grpc::PyBulletCommand grpcCommand;
pybullet_grpc::PyBulletCommand* grpcCmdPtr = convertBulletToGRPCCommand(clientCmd, grpcCommand);
if (grpcCmdPtr)
{
grpc::ClientContext context;
std::chrono::system_clock::time_point deadline =
std::chrono::system_clock::now() + std::chrono::seconds((long long)m_data->m_timeOutInSeconds);
context.set_deadline(deadline);
::pybullet_grpc::PyBulletStatus status;
// The actual RPC.
grpc::Status grpcStatus = m_data->m_stub->SubmitCommand(&context, grpcCommand, &status);
//convert grpc status to Bullet status
bool convertedOk = convertGRPCToStatus(status, serverStatusOut, bufferServerToClient, bufferSizeInBytes);
if (!convertedOk)
{
disconnect();
}
return convertedOk;
}
return false;
}
bool GRPCNetworkedPhysicsProcessor::receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
{
bool hasStatus = m_data->checkData();
if (hasStatus)
{
if (gVerboseNetworkMessagesClient3)
{
printf("GRPCNetworkedPhysicsProcessor::receiveStatus\n");
}
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");
}
}
return hasStatus;
}
void GRPCNetworkedPhysicsProcessor::renderScene(int renderFlags)
{
}
void GRPCNetworkedPhysicsProcessor::physicsDebugDraw(int debugDrawFlags)
{
}
void GRPCNetworkedPhysicsProcessor::setGuiHelper(struct GUIHelperInterface* guiHelper)
{
}
bool GRPCNetworkedPhysicsProcessor::isConnected() const
{
return m_data->m_isConnected;
}
bool GRPCNetworkedPhysicsProcessor::connect()
{
bool isConnected = m_data->connectGRPC();
return isConnected;
}
void GRPCNetworkedPhysicsProcessor::disconnect()
{
m_data->disconnect();
}
void GRPCNetworkedPhysicsProcessor::setTimeOut(double timeOutInSeconds)
{
m_data->m_timeOutInSeconds = timeOutInSeconds;
}
#endif //BT_ENABLE_GRPC

View file

@ -0,0 +1,37 @@
#ifndef PHYSICS_CLIENT_GRPC_H
#define PHYSICS_CLIENT_GRPC_H
#include "PhysicsDirect.h"
#include "PhysicsCommandProcessorInterface.h"
class GRPCNetworkedPhysicsProcessor : public PhysicsCommandProcessorInterface
{
struct GRPCNetworkedInternalData* m_data;
public:
GRPCNetworkedPhysicsProcessor(const char* hostName, int port);
virtual ~GRPCNetworkedPhysicsProcessor();
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(int renderFlags);
virtual void physicsDebugDraw(int debugDrawFlags);
virtual void setGuiHelper(struct GUIHelperInterface* guiHelper);
virtual void setTimeOut(double timeOutInSeconds);
virtual void reportNotifications() {}
};
#endif //PHYSICS_CLIENT_GRPC_H

View file

@ -0,0 +1,27 @@
#ifdef BT_ENABLE_GRPC
#include "PhysicsClientGRPC_C_API.h"
#include "PhysicsClientGRPC.h"
#include "PhysicsDirect.h"
#include <stdio.h>
B3_SHARED_API b3PhysicsClientHandle b3ConnectPhysicsGRPC(const char* hostName, int port)
{
GRPCNetworkedPhysicsProcessor* tcp = new GRPCNetworkedPhysicsProcessor(hostName, port);
PhysicsDirect* direct = new PhysicsDirect(tcp, true);
bool connected;
connected = direct->connect();
if (connected)
{
printf("b3ConnectPhysicsGRPC connected successfully.\n");
}
else
{
printf("b3ConnectPhysicsGRPC connection failed.\n");
}
return (b3PhysicsClientHandle)direct;
}
#endif //BT_ENABLE_GRPC

View file

@ -0,0 +1,18 @@
#ifndef PHYSICS_CLIENT_GRPC_C_API_H
#define PHYSICS_CLIENT_GRPC_C_API_H
#include "PhysicsClientC_API.h"
#ifdef __cplusplus
extern "C"
{
#endif
///send physics commands using GRPC connection
B3_SHARED_API b3PhysicsClientHandle b3ConnectPhysicsGRPC(const char* hostName, int port);
#ifdef __cplusplus
}
#endif
#endif //PHYSICS_CLIENT_GRPC_C_API_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,107 @@
#ifndef BT_PHYSICS_CLIENT_SHARED_MEMORY_API_H
#define BT_PHYSICS_CLIENT_SHARED_MEMORY_API_H
#include "PhysicsClient.h"
//#include "SharedMemoryCommands.h"
#include "LinearMath/btVector3.h"
class PhysicsClientSharedMemory : public PhysicsClient
{
protected:
struct PhysicsClientSharedMemoryInternalData* m_data;
virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem);
void processBodyJointInfo(int bodyUniqueId, const struct SharedMemoryStatus& serverCmd);
void resetData();
void removeCachedBody(int bodyUniqueId);
void clearCachedBodies();
virtual void renderSceneInternal(){};
public:
PhysicsClientSharedMemory();
virtual ~PhysicsClientSharedMemory();
// return true if connection succesfull, can also check 'isConnected'
virtual bool connect();
virtual void disconnectSharedMemory();
virtual bool isConnected() const;
// return non-null if there is a status, nullptr otherwise
virtual const struct SharedMemoryStatus* processServerStatus();
virtual struct SharedMemoryCommand* getAvailableSharedMemoryCommand();
virtual bool canSubmitCommand() const;
virtual bool submitClientCommand(const struct SharedMemoryCommand& command);
virtual int getNumBodies() const;
virtual int getBodyUniqueId(int serialIndex) const;
virtual bool getBodyInfo(int bodyUniqueId, struct b3BodyInfo& info) const;
virtual int getNumJoints(int bodyUniqueId) const;
virtual int getNumDofs(int bodyUniqueId) const;
virtual bool getJointInfo(int bodyUniqueId, int jointIndex, struct b3JointInfo& info) const;
virtual int getNumUserConstraints() const;
virtual int getUserConstraintInfo(int constraintUniqueId, struct b3UserConstraint& info) const;
virtual int getUserConstraintId(int serialIndex) const;
virtual void setSharedMemoryKey(int key);
virtual void uploadBulletFileToSharedMemory(const char* data, int len);
virtual void uploadRaysToSharedMemory(struct SharedMemoryCommand& command, const double* rayFromWorldArray, const double* rayToWorldArray, int numRays);
virtual int getNumDebugLines() const;
virtual const float* getDebugLinesFrom() const;
virtual const float* getDebugLinesTo() const;
virtual const float* getDebugLinesColor() const;
virtual void getCachedCameraImage(struct b3CameraImageData* cameraData);
virtual void getCachedContactPointInformation(struct b3ContactInformation* contactPointData);
virtual void getCachedOverlappingObjects(struct b3AABBOverlapData* overlappingObjects);
virtual void getCachedVisualShapeInformation(struct b3VisualShapeInformation* visualShapesInfo);
virtual void getCachedCollisionShapeInformation(struct b3CollisionShapeInformation* collisionShapesInfo);
virtual void getCachedMeshData(struct b3MeshData* meshData);
virtual void getCachedVREvents(struct b3VREventsData* vrEventsData);
virtual void getCachedKeyboardEvents(struct b3KeyboardEventsData* keyboardEventsData);
virtual void getCachedMouseEvents(struct b3MouseEventsData* mouseEventsData);
virtual void getCachedRaycastHits(struct b3RaycastInformation* raycastHits);
virtual void getCachedMassMatrix(int dofCountCheck, double* massMatrix);
virtual bool getCachedReturnData(b3UserDataValue* returnData);
virtual void setTimeOut(double timeOutInSeconds);
virtual double getTimeOut() const;
virtual bool getCachedUserData(int userDataId, struct b3UserDataValue& valueOut) const;
virtual int getCachedUserDataId(int bodyUniqueId, int linkIndex, int visualShapeIndex, const char* key) const;
virtual int getNumUserData(int bodyUniqueId) const;
virtual void getUserDataInfo(int bodyUniqueId, int userDataIndex, const char** keyOut, int* userDataIdOut, int* linkIndexOut, int* visualShapeIndexOut) const;
virtual void pushProfileTiming(const char* timingName);
virtual void popProfileTiming();
};
#endif // BT_PHYSICS_CLIENT_API_H

View file

@ -0,0 +1,25 @@
#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, false)
{
m_proc = proc;
}
PhysicsClientSharedMemory2::~PhysicsClientSharedMemory2()
{
}
void PhysicsClientSharedMemory2::setSharedMemoryInterface(class SharedMemoryInterface* sharedMem)
{
if (m_proc)
{
m_proc->setSharedMemoryInterface(sharedMem);
}
}

View file

@ -0,0 +1,17 @@
#ifndef PHYSICS_CLIENT_SHARED_MEMORY3_H
#define PHYSICS_CLIENT_SHARED_MEMORY3_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_MEMORY3_H

View file

@ -0,0 +1,17 @@
#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, true);
cl->setSharedMemoryKey(key);
cl->connect();
return (b3PhysicsClientHandle)cl;
}

View file

@ -0,0 +1,17 @@
#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

View file

@ -0,0 +1,11 @@
#include "PhysicsClientSharedMemory_C_API.h"
#include "PhysicsClientSharedMemory.h"
B3_SHARED_API b3PhysicsClientHandle b3ConnectSharedMemory(int key)
{
PhysicsClientSharedMemory* cl = new PhysicsClientSharedMemory();
cl->setSharedMemoryKey(key);
cl->connect();
return (b3PhysicsClientHandle)cl;
}

View file

@ -0,0 +1,17 @@
#ifndef PHYSICS_CLIENT_SHARED_MEMORY_H
#define PHYSICS_CLIENT_SHARED_MEMORY_H
#include "PhysicsClientC_API.h"
#ifdef __cplusplus
extern "C"
{
#endif
B3_SHARED_API b3PhysicsClientHandle b3ConnectSharedMemory(int key);
#ifdef __cplusplus
}
#endif
#endif //PHYSICS_CLIENT_SHARED_MEMORY_H

View file

@ -0,0 +1,256 @@
#include "PhysicsClientTCP.h"
#include "ActiveSocket.h"
#include <stdio.h>
#include <string.h>
#include "../Utils/b3Clock.h"
#include "PhysicsClient.h"
//#include "LinearMath/btVector3.h"
#include "SharedMemoryCommands.h"
#include <string>
#include "Bullet3Common/b3Logging.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
unsigned int b3DeserializeInt2(const unsigned char* input)
{
unsigned int tmp = (input[3] << 24) + (input[2] << 16) + (input[1] << 8) + input[0];
return tmp;
}
bool gVerboseNetworkMessagesClient2 = false;
struct TcpNetworkedInternalData
{
/*
ENetHost* m_client;
ENetAddress m_address;
ENetPeer* m_peer;
ENetEvent m_event;
*/
CActiveSocket m_tcpSocket;
bool m_isConnected;
TcpNetworkedInternalData* m_tcpInternalData;
SharedMemoryCommand m_clientCmd;
bool m_hasCommand;
SharedMemoryStatus m_lastStatus;
b3AlignedObjectArray<char> m_stream;
std::string m_hostName;
int m_port;
b3AlignedObjectArray<unsigned char> m_tempBuffer;
double m_timeOutInSeconds;
TcpNetworkedInternalData()
: m_isConnected(false),
m_hasCommand(false),
m_timeOutInSeconds(60)
{
}
bool connectTCP()
{
if (m_isConnected)
return true;
m_tcpSocket.Initialize();
m_isConnected = m_tcpSocket.Open(m_hostName.c_str(), m_port);
if (m_isConnected)
{
m_tcpSocket.SetSendTimeout(m_timeOutInSeconds, 0);
m_tcpSocket.SetReceiveTimeout(m_timeOutInSeconds, 0);
int key = SHARED_MEMORY_MAGIC_NUMBER;
m_tcpSocket.Send((uint8*)&key, 4);
}
return m_isConnected;
}
bool checkData()
{
bool hasStatus = false;
//int serviceResult = enet_host_service(m_client, &m_event, 0);
int maxLen = 4 + sizeof(SharedMemoryStatus) + SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE;
int rBytes = m_tcpSocket.Receive(maxLen);
if (rBytes <= 0)
return false;
//append to tmp buffer
//recBytes
unsigned char* d2 = (unsigned char*)m_tcpSocket.GetData();
int curSize = m_tempBuffer.size();
m_tempBuffer.resize(curSize + rBytes);
for (int i = 0; i < rBytes; i++)
{
m_tempBuffer[curSize + i] = d2[i];
}
int packetSizeInBytes = -1;
if (m_tempBuffer.size() >= 4)
{
packetSizeInBytes = b3DeserializeInt2(&m_tempBuffer[0]);
}
if (m_tempBuffer.size() == packetSizeInBytes)
{
unsigned char* data = &m_tempBuffer[0];
if (gVerboseNetworkMessagesClient2)
{
printf("A packet of length %d bytes received\n", m_tempBuffer.size());
}
hasStatus = true;
SharedMemoryStatus* statPtr = (SharedMemoryStatus*)&data[4];
if (statPtr->m_type == CMD_STEP_FORWARD_SIMULATION_COMPLETED)
{
SharedMemoryStatus dummy;
dummy.m_type = CMD_STEP_FORWARD_SIMULATION_COMPLETED;
m_lastStatus = dummy;
m_stream.resize(0);
}
else
{
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] = data[i + streamOffsetInBytes];
}
}
m_tempBuffer.clear();
}
return hasStatus;
}
};
TcpNetworkedPhysicsProcessor::TcpNetworkedPhysicsProcessor(const char* hostName, int port)
{
m_data = new TcpNetworkedInternalData;
if (hostName)
{
m_data->m_hostName = hostName;
}
m_data->m_port = port;
}
TcpNetworkedPhysicsProcessor::~TcpNetworkedPhysicsProcessor()
{
disconnect();
delete m_data;
}
bool TcpNetworkedPhysicsProcessor::processCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
{
if (gVerboseNetworkMessagesClient2)
{
printf("PhysicsClientTCP::processCommand\n");
}
{
int sz = 0;
unsigned char* data = 0;
m_data->m_tempBuffer.clear();
if (clientCmd.m_type == CMD_STEP_FORWARD_SIMULATION)
{
sz = sizeof(int);
data = (unsigned char*)&clientCmd.m_type;
}
else
{
if (clientCmd.m_type == CMD_REQUEST_VR_EVENTS_DATA)
{
sz = 3 * sizeof(int) + sizeof(smUint64_t) + 16;
data = (unsigned char*)&clientCmd;
}
else
{
sz = sizeof(SharedMemoryCommand);
data = (unsigned char*)&clientCmd;
}
}
m_data->m_tcpSocket.Send((const uint8*)data, sz);
}
return false;
}
bool TcpNetworkedPhysicsProcessor::receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
{
bool hasStatus = m_data->checkData();
if (hasStatus)
{
if (gVerboseNetworkMessagesClient2)
{
printf("TcpNetworkedPhysicsProcessor::receiveStatus\n");
}
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");
}
}
return hasStatus;
}
void TcpNetworkedPhysicsProcessor::renderScene(int renderFlags)
{
}
void TcpNetworkedPhysicsProcessor::physicsDebugDraw(int debugDrawFlags)
{
}
void TcpNetworkedPhysicsProcessor::setGuiHelper(struct GUIHelperInterface* guiHelper)
{
}
bool TcpNetworkedPhysicsProcessor::isConnected() const
{
return m_data->m_isConnected;
}
bool TcpNetworkedPhysicsProcessor::connect()
{
bool isConnected = m_data->connectTCP();
return isConnected;
}
void TcpNetworkedPhysicsProcessor::disconnect()
{
const char msg[16] = "disconnect";
m_data->m_tcpSocket.Send((const uint8*)msg, 10);
m_data->m_tcpSocket.Close();
m_data->m_isConnected = false;
}
void TcpNetworkedPhysicsProcessor::setTimeOut(double timeOutInSeconds)
{
m_data->m_timeOutInSeconds = timeOutInSeconds;
}

View file

@ -0,0 +1,37 @@
#ifndef PHYSICS_CLIENT_TCP_H
#define PHYSICS_CLIENT_TCP_H
#include "PhysicsDirect.h"
#include "PhysicsCommandProcessorInterface.h"
class TcpNetworkedPhysicsProcessor : public PhysicsCommandProcessorInterface
{
struct TcpNetworkedInternalData* m_data;
public:
TcpNetworkedPhysicsProcessor(const char* hostName, int port);
virtual ~TcpNetworkedPhysicsProcessor();
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(int renderFlags);
virtual void physicsDebugDraw(int debugDrawFlags);
virtual void setGuiHelper(struct GUIHelperInterface* guiHelper);
virtual void setTimeOut(double timeOutInSeconds);
virtual void reportNotifications() {}
};
#endif //PHYSICS_CLIENT_TCP_H

View file

@ -0,0 +1,24 @@
#include "PhysicsClientTCP_C_API.h"
#include "PhysicsClientTCP.h"
#include "PhysicsDirect.h"
#include <stdio.h>
B3_SHARED_API b3PhysicsClientHandle b3ConnectPhysicsTCP(const char* hostName, int port)
{
TcpNetworkedPhysicsProcessor* tcp = new TcpNetworkedPhysicsProcessor(hostName, port);
PhysicsDirect* direct = new PhysicsDirect(tcp, true);
bool connected;
connected = direct->connect();
if (connected)
{
printf("b3ConnectPhysicsTCP connected successfully.\n");
}
else
{
printf("b3ConnectPhysicsTCP connection failed.\n");
}
return (b3PhysicsClientHandle)direct;
}

View file

@ -0,0 +1,18 @@
#ifndef PHYSICS_CLIENT_TCP_C_API_H
#define PHYSICS_CLIENT_TCP_C_API_H
#include "PhysicsClientC_API.h"
#ifdef __cplusplus
extern "C"
{
#endif
///send physics commands using TCP networking
B3_SHARED_API b3PhysicsClientHandle b3ConnectPhysicsTCP(const char* hostName, int port);
#ifdef __cplusplus
}
#endif
#endif //PHYSICS_CLIENT_TCP_C_API_H

View file

@ -0,0 +1,597 @@
#include "PhysicsClientUDP.h"
#include <enet/enet.h>
#include <stdio.h>
#include <string.h>
#include "../Utils/b3Clock.h"
#include "PhysicsClient.h"
//#include "LinearMath/btVector3.h"
#include "SharedMemoryCommands.h"
#include <string>
#include "Bullet3Common/b3Logging.h"
#include "../MultiThreading/b3ThreadSupportInterface.h"
void UDPThreadFunc(void* userPtr, void* lsMemory);
void* UDPlsMemoryFunc();
void UDPlsMemoryReleaseFunc(void* ptr);
bool gVerboseNetworkMessagesClient = false;
#ifndef _WIN32
#include "../MultiThreading/b3PosixThreadSupport.h"
b3ThreadSupportInterface* createUDPThreadSupport(int numThreads)
{
b3PosixThreadSupport::ThreadConstructionInfo constructionInfo("UDPThread",
UDPThreadFunc,
UDPlsMemoryFunc,
UDPlsMemoryReleaseFunc,
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, UDPlsMemoryReleaseFunc, 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<char> m_stream;
std::string m_hostName;
int m_port;
double m_timeOutInSeconds;
UdpNetworkedInternalData()
: m_client(0),
m_peer(0),
m_isConnected(false),
m_threadSupport(0),
m_hasCommand(false),
m_hasStatus(false),
m_timeOutInSeconds(60)
{
}
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:
if (gVerboseNetworkMessagesClient)
{
printf(
"A packet of length %lu containing '%s' was "
"received from %s on channel %u.\n",
m_event.packet->dataLength,
(char*)m_event.packet->data,
(char*)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 disconnected.\n", (char*)m_event.peer->data);
break;
default:
{
printf("unknown event type: %d.\n", m_event.type);
}
}
}
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, 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:
{
if (gVerboseNetworkMessagesClient)
{
printf(
"A packet of length %lu containing '%s' was "
"received from %s on channel %u.\n",
m_event.packet->dataLength,
(char*)m_event.packet->data,
(char*)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];
if (statPtr->m_type == CMD_STEP_FORWARD_SIMULATION_COMPLETED)
{
SharedMemoryStatus dummy;
dummy.m_type = CMD_STEP_FORWARD_SIMULATION_COMPLETED;
m_lastStatus = dummy;
m_stream.resize(0);
}
else
{
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 disconnected.\n", (char*)m_event.peer->data);
break;
}
default:
{
printf("unknown event type: %d.\n", m_event.type);
}
}
}
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
{
b3Clock::usleep(0);
deltaTimeInSeconds += double(clock.getTimeMicroseconds()) / 1000000.;
{
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 = 0;
ENetPacket* packet = 0;
if (args->m_clientCmd.m_type == CMD_STEP_FORWARD_SIMULATION)
{
sz = sizeof(int);
packet = enet_packet_create(&args->m_clientCmd.m_type, sz, ENET_PACKET_FLAG_RELIABLE);
}
else
{
sz = sizeof(SharedMemoryCommand);
packet = enet_packet_create(&args->m_clientCmd, sz, ENET_PACKET_FLAG_RELIABLE);
}
int res;
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;
}
void UDPlsMemoryReleaseFunc(void* ptr)
{
UDPThreadLocalStorage* p = (UDPThreadLocalStorage*)ptr;
delete p;
}
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)
{
if (gVerboseNetworkMessagesClient)
{
printf("PhysicsClientUDP::processCommand\n");
}
// int sz = sizeof(SharedMemoryCommand);
b3Clock clock;
double startTime = clock.getTimeInSeconds();
double timeOutInSeconds = m_data->m_timeOutInSeconds;
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) && (clock.getTimeInSeconds() - startTime < timeOutInSeconds))
{
b3Clock::usleep(0);
}
#if 0
bool hasStatus = false;
b3Clock clock;
double startTime = clock.getTimeInSeconds();
double timeOutInSeconds = m_data->m_timeOutInSeconds;
const SharedMemoryStatus* stat = 0;
while ((!hasStatus) && (clock.getTimeInSeconds() - startTime < timeOutInSeconds))
{
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)
{
if (gVerboseNetworkMessagesClient)
{
printf("UdpNetworkedPhysicsProcessor::receiveStatus\n");
}
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(int renderFlags)
{
}
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);
}
}
unsigned int sharedParam = m_data->m_cs->getSharedParam(1);
bool isConnected = (sharedParam == eUDP_Connected);
return isConnected;
}
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;
m_data->m_isConnected = false;
}
}
void UdpNetworkedPhysicsProcessor::setTimeOut(double timeOutInSeconds)
{
m_data->m_timeOutInSeconds = timeOutInSeconds;
}

View file

@ -0,0 +1,37 @@
#ifndef PHYSICS_CLIENT_UDP_H
#define PHYSICS_CLIENT_UDP_H
#include "PhysicsDirect.h"
#include "PhysicsCommandProcessorInterface.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(int renderFlags);
virtual void physicsDebugDraw(int debugDrawFlags);
virtual void setGuiHelper(struct GUIHelperInterface* guiHelper);
virtual void setTimeOut(double timeOutInSeconds);
virtual void reportNotifications() {}
};
#endif //PHYSICS_CLIENT_UDP_H

View file

@ -0,0 +1,25 @@
#include "PhysicsClientUDP_C_API.h"
#include "PhysicsClientUDP.h"
#include "PhysicsDirect.h"
#include <stdio.h>
//think more about naming. The b3ConnectPhysicsLoopback
B3_SHARED_API b3PhysicsClientHandle b3ConnectPhysicsUDP(const char* hostName, int port)
{
UdpNetworkedPhysicsProcessor* udp = new UdpNetworkedPhysicsProcessor(hostName, port);
PhysicsDirect* direct = new PhysicsDirect(udp, true);
bool connected;
connected = direct->connect();
if (connected)
{
printf("b3ConnectPhysicsUDP connected successfully.\n");
}
else
{
printf("b3ConnectPhysicsUDP connection failed.\n");
}
return (b3PhysicsClientHandle)direct;
}

View file

@ -0,0 +1,18 @@
#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
B3_SHARED_API b3PhysicsClientHandle b3ConnectPhysicsUDP(const char* hostName, int port);
#ifdef __cplusplus
}
#endif
#endif //PHYSICS_CLIENT_UDP_C_API_H

View file

@ -0,0 +1,62 @@
#ifndef PHYSICS_COMMAND_PROCESSOR_INTERFACE_H
#define PHYSICS_COMMAND_PROCESSOR_INTERFACE_H
enum PhysicsCommandRenderFlags
{
COV_DISABLE_SYNC_RENDERING = 1
};
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(int renderFlags) = 0;
virtual void physicsDebugDraw(int debugDrawFlags) = 0;
virtual void setGuiHelper(struct GUIHelperInterface* guiHelper) = 0;
virtual void setTimeOut(double timeOutInSeconds) = 0;
virtual void reportNotifications() = 0;
};
class btVector3;
class btQuaternion;
class CommandProcessorInterface : public PhysicsCommandProcessorInterface
{
public:
virtual ~CommandProcessorInterface() {}
virtual void syncPhysicsToGraphics() = 0;
virtual void stepSimulationRealTime(double dtInSec, const struct b3VRControllerEvent* vrControllerEvents, int numVRControllerEvents, const struct b3KeyboardEvent* keyEvents, int numKeyEvents, const struct b3MouseEvent* mouseEvents, int numMouseEvents) = 0;
virtual void enableRealTimeSimulation(bool enableRealTimeSim) = 0;
virtual bool isRealTimeSimulationEnabled() const = 0;
virtual void enableCommandLogging(bool enable, const char* fileName) = 0;
virtual void replayFromLogFile(const char* fileName) = 0;
virtual void replayLogCommand(char* bufferServerToClient, int bufferSizeInBytes) = 0;
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) = 0;
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) = 0;
virtual void removePickingConstraint() = 0;
virtual const btVector3& getVRTeleportPosition() const = 0;
virtual void setVRTeleportPosition(const btVector3& vrReleportPos) = 0;
virtual const btQuaternion& getVRTeleportOrientation() const = 0;
virtual void setVRTeleportOrientation(const btQuaternion& vrReleportOrn) = 0;
virtual void processClientCommands() = 0;
};
#endif //PHYSICS_COMMAND_PROCESSOR_INTERFACE_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,138 @@
#ifndef PHYSICS_DIRECT_H
#define PHYSICS_DIRECT_H
//#include "SharedMemoryCommands.h"
#include "PhysicsClient.h"
#include "LinearMath/btVector3.h"
///PhysicsDirect executes the commands directly, without transporting them or having a separate server executing commands
class PhysicsDirect : public PhysicsClient
{
protected:
struct PhysicsDirectInternalData* m_data;
bool processDebugLines(const struct SharedMemoryCommand& orgCommand);
bool processCamera(const struct SharedMemoryCommand& orgCommand);
bool processContactPointData(const struct SharedMemoryCommand& orgCommand);
bool processOverlappingObjects(const struct SharedMemoryCommand& orgCommand);
bool processVisualShapeData(const struct SharedMemoryCommand& orgCommand);
bool processMeshData(const struct SharedMemoryCommand& orgCommand);
void processBodyJointInfo(int bodyUniqueId, const struct SharedMemoryStatus& serverCmd);
void processAddUserData(const struct SharedMemoryStatus& serverCmd);
bool processRequestBodyInfo(const struct SharedMemoryCommand& command, SharedMemoryStatus& status);
bool processCustomCommand(const struct SharedMemoryCommand& orgCommand);
void postProcessStatus(const struct SharedMemoryStatus& serverCmd);
void resetData();
void removeCachedBody(int bodyUniqueId);
void clearCachedBodies();
public:
PhysicsDirect(class PhysicsCommandProcessorInterface* physSdk, bool passSdkOwnership);
virtual ~PhysicsDirect();
// return true if connection succesfull, can also check 'isConnected'
//it is OK to pass a null pointer for the gui helper
virtual bool connect();
////todo: rename to 'disconnect'
virtual void disconnectSharedMemory();
virtual bool isConnected() const;
// return non-null if there is a status, nullptr otherwise
virtual const SharedMemoryStatus* processServerStatus();
virtual SharedMemoryCommand* getAvailableSharedMemoryCommand();
virtual bool canSubmitCommand() const;
virtual bool submitClientCommand(const struct SharedMemoryCommand& command);
virtual int getNumBodies() const;
virtual int getBodyUniqueId(int serialIndex) const;
virtual bool getBodyInfo(int bodyUniqueId, struct b3BodyInfo& info) const;
virtual int getNumJoints(int bodyUniqueId) const;
virtual int getNumDofs(int bodyUniqueId) const;
virtual bool getJointInfo(int bodyIndex, int jointIndex, struct b3JointInfo& info) const;
virtual int getNumUserConstraints() const;
virtual int getUserConstraintInfo(int constraintUniqueId, struct b3UserConstraint& info) const;
virtual int getUserConstraintId(int serialIndex) const;
///todo: move this out of the
virtual void setSharedMemoryKey(int key);
void uploadBulletFileToSharedMemory(const char* data, int len);
virtual void uploadRaysToSharedMemory(struct SharedMemoryCommand& command, const double* rayFromWorldArray, const double* rayToWorldArray, int numRays);
virtual int getNumDebugLines() const;
virtual const float* getDebugLinesFrom() const;
virtual const float* getDebugLinesTo() const;
virtual const float* getDebugLinesColor() const;
virtual void getCachedCameraImage(b3CameraImageData* cameraData);
virtual void getCachedContactPointInformation(struct b3ContactInformation* contactPointData);
virtual void getCachedOverlappingObjects(struct b3AABBOverlapData* overlappingObjects);
virtual void getCachedVisualShapeInformation(struct b3VisualShapeInformation* visualShapesInfo);
virtual void getCachedCollisionShapeInformation(struct b3CollisionShapeInformation* collisionShapesInfo);
virtual void getCachedMeshData(struct b3MeshData* meshData);
virtual void getCachedVREvents(struct b3VREventsData* vrEventsData);
virtual void getCachedKeyboardEvents(struct b3KeyboardEventsData* keyboardEventsData);
virtual void getCachedMouseEvents(struct b3MouseEventsData* mouseEventsData);
virtual void getCachedRaycastHits(struct b3RaycastInformation* raycastHits);
virtual void getCachedMassMatrix(int dofCountCheck, double* massMatrix);
virtual bool getCachedReturnData(b3UserDataValue* returnData);
//the following APIs are for internal use for visualization:
virtual bool connect(struct GUIHelperInterface* guiHelper);
virtual void renderScene();
virtual void debugDraw(int debugDrawMode);
virtual void setTimeOut(double timeOutInSeconds);
virtual double getTimeOut() const;
virtual bool getCachedUserData(int userDataId, struct b3UserDataValue& valueOut) const;
virtual int getCachedUserDataId(int bodyUniqueId, int linkIndex, int visualShapeIndex, const char* key) const;
virtual int getNumUserData(int bodyUniqueId) const;
virtual void getUserDataInfo(int bodyUniqueId, int userDataIndex, const char** keyOut, int* userDataIdOut, int* linkIndexOut, int* visualShapeIndexOut) const;
virtual void pushProfileTiming(const char* timingName);
virtual void popProfileTiming();
};
#endif //PHYSICS_DIRECT_H

View file

@ -0,0 +1,18 @@
#include "PhysicsDirectC_API.h"
#include "PhysicsDirect.h"
#include "PhysicsServerCommandProcessor.h"
//think more about naming. The b3ConnectPhysicsLoopback
B3_SHARED_API b3PhysicsClientHandle b3ConnectPhysicsDirect()
{
PhysicsServerCommandProcessor* sdk = new PhysicsServerCommandProcessor;
PhysicsDirect* direct = new PhysicsDirect(sdk, true);
bool connected;
connected = direct->connect();
return (b3PhysicsClientHandle)direct;
}
//

View file

@ -0,0 +1,18 @@
#ifndef PHYSICS_DIRECT_C_API_H
#define PHYSICS_DIRECT_C_API_H
#include "PhysicsClientC_API.h"
#ifdef __cplusplus
extern "C"
{
#endif
///think more about naming. Directly execute commands without transport (no shared memory, UDP, socket, grpc etc)
B3_SHARED_API b3PhysicsClientHandle b3ConnectPhysicsDirect();
#ifdef __cplusplus
}
#endif
#endif //PHYSICS_DIRECT_C_API_H

View file

@ -0,0 +1,271 @@
#include "PhysicsLoopBack.h"
#include "PhysicsServerSharedMemory.h"
#include "PhysicsClientSharedMemory.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "PhysicsServerCommandProcessor.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
struct PhysicsLoopBackInternalData
{
CommandProcessorInterface* m_commandProcessor;
PhysicsClientSharedMemory* m_physicsClient;
PhysicsServerSharedMemory* m_physicsServer;
DummyGUIHelper m_noGfx;
PhysicsLoopBackInternalData()
: m_commandProcessor(0),
m_physicsClient(0),
m_physicsServer(0)
{
}
};
struct Bullet2CommandProcessorCreation2 : public CommandProcessorCreationInterface
{
virtual class CommandProcessorInterface* createCommandProcessor()
{
PhysicsServerCommandProcessor* proc = new PhysicsServerCommandProcessor;
return proc;
}
virtual void deleteCommandProcessor(CommandProcessorInterface* proc)
{
delete proc;
}
};
static Bullet2CommandProcessorCreation2 sB2Proc;
PhysicsLoopBack::PhysicsLoopBack()
{
m_data = new PhysicsLoopBackInternalData;
m_data->m_physicsServer = new PhysicsServerSharedMemory(&sB2Proc, 0, 0);
m_data->m_physicsClient = new PhysicsClientSharedMemory();
}
PhysicsLoopBack::~PhysicsLoopBack()
{
delete m_data->m_physicsClient;
delete m_data->m_physicsServer;
delete m_data->m_commandProcessor;
delete m_data;
}
// return true if connection succesfull, can also check 'isConnected'
bool PhysicsLoopBack::connect()
{
m_data->m_physicsServer->connectSharedMemory(&m_data->m_noGfx);
m_data->m_physicsClient->connect();
return m_data->m_physicsClient->isConnected();
}
////todo: rename to 'disconnect'
void PhysicsLoopBack::disconnectSharedMemory()
{
m_data->m_physicsClient->disconnectSharedMemory();
m_data->m_physicsServer->disconnectSharedMemory(true);
}
bool PhysicsLoopBack::isConnected() const
{
return m_data->m_physicsClient->isConnected();
}
// return non-null if there is a status, nullptr otherwise
const SharedMemoryStatus* PhysicsLoopBack::processServerStatus()
{
m_data->m_physicsServer->processClientCommands();
return m_data->m_physicsClient->processServerStatus();
}
SharedMemoryCommand* PhysicsLoopBack::getAvailableSharedMemoryCommand()
{
return m_data->m_physicsClient->getAvailableSharedMemoryCommand();
}
bool PhysicsLoopBack::canSubmitCommand() const
{
return m_data->m_physicsClient->canSubmitCommand();
}
bool PhysicsLoopBack::submitClientCommand(const struct SharedMemoryCommand& command)
{
return m_data->m_physicsClient->submitClientCommand(command);
}
int PhysicsLoopBack::getNumBodies() const
{
return m_data->m_physicsClient->getNumBodies();
}
int PhysicsLoopBack::getBodyUniqueId(int serialIndex) const
{
return m_data->m_physicsClient->getBodyUniqueId(serialIndex);
}
bool PhysicsLoopBack::getBodyInfo(int bodyUniqueId, struct b3BodyInfo& info) const
{
return m_data->m_physicsClient->getBodyInfo(bodyUniqueId, info);
}
int PhysicsLoopBack::getNumJoints(int bodyUniqueId) const
{
return m_data->m_physicsClient->getNumJoints(bodyUniqueId);
}
int PhysicsLoopBack::getNumDofs(int bodyUniqueId) const
{
return m_data->m_physicsClient->getNumDofs(bodyUniqueId);
}
bool PhysicsLoopBack::getJointInfo(int bodyIndex, int jointIndex, struct b3JointInfo& info) const
{
return m_data->m_physicsClient->getJointInfo(bodyIndex, jointIndex, info);
}
int PhysicsLoopBack::getNumUserConstraints() const
{
return m_data->m_physicsClient->getNumUserConstraints();
}
int PhysicsLoopBack::getUserConstraintInfo(int constraintUniqueId, struct b3UserConstraint& info) const
{
return m_data->m_physicsClient->getUserConstraintInfo(constraintUniqueId, info);
}
int PhysicsLoopBack::getUserConstraintId(int serialIndex) const
{
return m_data->m_physicsClient->getUserConstraintId(serialIndex);
}
///todo: move this out of the interface
void PhysicsLoopBack::setSharedMemoryKey(int key)
{
m_data->m_physicsServer->setSharedMemoryKey(key);
m_data->m_physicsClient->setSharedMemoryKey(key);
}
void PhysicsLoopBack::uploadBulletFileToSharedMemory(const char* data, int len)
{
m_data->m_physicsClient->uploadBulletFileToSharedMemory(data, len);
}
void PhysicsLoopBack::uploadRaysToSharedMemory(struct SharedMemoryCommand& command, const double* rayFromWorldArray, const double* rayToWorldArray, int numRays)
{
m_data->m_physicsClient->uploadRaysToSharedMemory(command, rayFromWorldArray, rayToWorldArray, numRays);
}
int PhysicsLoopBack::getNumDebugLines() const
{
return m_data->m_physicsClient->getNumDebugLines();
}
const float* PhysicsLoopBack::getDebugLinesFrom() const
{
return m_data->m_physicsClient->getDebugLinesFrom();
}
const float* PhysicsLoopBack::getDebugLinesTo() const
{
return m_data->m_physicsClient->getDebugLinesTo();
}
const float* PhysicsLoopBack::getDebugLinesColor() const
{
return m_data->m_physicsClient->getDebugLinesColor();
}
void PhysicsLoopBack::getCachedCameraImage(struct b3CameraImageData* cameraData)
{
return m_data->m_physicsClient->getCachedCameraImage(cameraData);
}
void PhysicsLoopBack::getCachedMeshData(struct b3MeshData* meshData)
{
return m_data->m_physicsClient->getCachedMeshData(meshData);
}
void PhysicsLoopBack::getCachedContactPointInformation(struct b3ContactInformation* contactPointData)
{
return m_data->m_physicsClient->getCachedContactPointInformation(contactPointData);
}
void PhysicsLoopBack::getCachedVisualShapeInformation(struct b3VisualShapeInformation* visualShapesInfo)
{
return m_data->m_physicsClient->getCachedVisualShapeInformation(visualShapesInfo);
}
void PhysicsLoopBack::getCachedCollisionShapeInformation(struct b3CollisionShapeInformation* collisionShapesInfo)
{
return m_data->m_physicsClient->getCachedCollisionShapeInformation(collisionShapesInfo);
}
void PhysicsLoopBack::getCachedVREvents(struct b3VREventsData* vrEventsData)
{
return m_data->m_physicsClient->getCachedVREvents(vrEventsData);
}
void PhysicsLoopBack::getCachedKeyboardEvents(struct b3KeyboardEventsData* keyboardEventsData)
{
return m_data->m_physicsClient->getCachedKeyboardEvents(keyboardEventsData);
}
void PhysicsLoopBack::getCachedMouseEvents(struct b3MouseEventsData* mouseEventsData)
{
return m_data->m_physicsClient->getCachedMouseEvents(mouseEventsData);
}
void PhysicsLoopBack::getCachedOverlappingObjects(struct b3AABBOverlapData* overlappingObjects)
{
return m_data->m_physicsClient->getCachedOverlappingObjects(overlappingObjects);
}
void PhysicsLoopBack::getCachedRaycastHits(struct b3RaycastInformation* raycastHits)
{
return m_data->m_physicsClient->getCachedRaycastHits(raycastHits);
}
void PhysicsLoopBack::getCachedMassMatrix(int dofCountCheck, double* massMatrix)
{
m_data->m_physicsClient->getCachedMassMatrix(dofCountCheck, massMatrix);
}
bool PhysicsLoopBack::getCachedReturnData(struct b3UserDataValue* returnData)
{
return m_data->m_physicsClient->getCachedReturnData(returnData);
}
void PhysicsLoopBack::setTimeOut(double timeOutInSeconds)
{
m_data->m_physicsClient->setTimeOut(timeOutInSeconds);
}
double PhysicsLoopBack::getTimeOut() const
{
return m_data->m_physicsClient->getTimeOut();
}
bool PhysicsLoopBack::getCachedUserData(int userDataId, struct b3UserDataValue& valueOut) const
{
return m_data->m_physicsClient->getCachedUserData(userDataId, valueOut);
}
int PhysicsLoopBack::getCachedUserDataId(int bodyUniqueId, int linkIndex, int visualShapeIndex, const char* key) const
{
return m_data->m_physicsClient->getCachedUserDataId(bodyUniqueId, linkIndex, visualShapeIndex, key);
}
int PhysicsLoopBack::getNumUserData(int bodyUniqueId) const
{
return m_data->m_physicsClient->getNumUserData(bodyUniqueId);
}
void PhysicsLoopBack::getUserDataInfo(int bodyUniqueId, int userDataIndex, const char** keyOut, int* userDataIdOut, int* linkIndexOut, int* visualShapeIndexOut) const
{
m_data->m_physicsClient->getUserDataInfo(bodyUniqueId, userDataIndex, keyOut, userDataIdOut, linkIndexOut, visualShapeIndexOut);
}
void PhysicsLoopBack::pushProfileTiming(const char* timingName)
{
m_data->m_physicsClient->pushProfileTiming(timingName);
}
void PhysicsLoopBack::popProfileTiming()
{
m_data->m_physicsClient->popProfileTiming();
}

View file

@ -0,0 +1,105 @@
#ifndef PHYSICS_LOOP_BACK_H
#define PHYSICS_LOOP_BACK_H
//#include "SharedMemoryCommands.h"
#include "PhysicsClient.h"
#include "LinearMath/btVector3.h"
///todo: the PhysicsClient API was designed with shared memory in mind,
///now it become more general we need to move out the shared memory specifics away
///for example naming [disconnectSharedMemory -> disconnect] [ move setSharedMemoryKey to shared memory specific subclass ]
class PhysicsLoopBack : public PhysicsClient
{
struct PhysicsLoopBackInternalData* m_data;
public:
PhysicsLoopBack();
virtual ~PhysicsLoopBack();
// return true if connection succesfull, can also check 'isConnected'
virtual bool connect();
////todo: rename to 'disconnect'
virtual void disconnectSharedMemory();
virtual bool isConnected() const;
// return non-null if there is a status, nullptr otherwise
virtual const SharedMemoryStatus* processServerStatus();
virtual SharedMemoryCommand* getAvailableSharedMemoryCommand();
virtual bool canSubmitCommand() const;
virtual bool submitClientCommand(const struct SharedMemoryCommand& command);
virtual int getNumBodies() const;
virtual int getBodyUniqueId(int serialIndex) const;
virtual bool getBodyInfo(int bodyUniqueId, struct b3BodyInfo& info) const;
virtual int getNumJoints(int bodyUniqueId) const;
virtual int getNumDofs(int bodyUniqueId) const;
virtual bool getJointInfo(int bodyIndex, int jointIndex, struct b3JointInfo& info) const;
virtual int getNumUserConstraints() const;
virtual int getUserConstraintInfo(int constraintUniqueId, struct b3UserConstraint& info) const;
virtual int getUserConstraintId(int serialIndex) const;
///todo: move this out of the
virtual void setSharedMemoryKey(int key);
void uploadBulletFileToSharedMemory(const char* data, int len);
virtual void uploadRaysToSharedMemory(struct SharedMemoryCommand& command, const double* rayFromWorldArray, const double* rayToWorldArray, int numRays);
virtual int getNumDebugLines() const;
virtual const float* getDebugLinesFrom() const;
virtual const float* getDebugLinesTo() const;
virtual const float* getDebugLinesColor() const;
virtual void getCachedCameraImage(struct b3CameraImageData* cameraData);
virtual void getCachedContactPointInformation(struct b3ContactInformation* contactPointData);
virtual void getCachedOverlappingObjects(struct b3AABBOverlapData* overlappingObjects);
virtual void getCachedVisualShapeInformation(struct b3VisualShapeInformation* visualShapesInfo);
virtual void getCachedCollisionShapeInformation(struct b3CollisionShapeInformation* collisionShapesInfo);
virtual void getCachedMeshData(struct b3MeshData* meshData);
virtual void getCachedVREvents(struct b3VREventsData* vrEventsData);
virtual void getCachedKeyboardEvents(struct b3KeyboardEventsData* keyboardEventsData);
virtual void getCachedMouseEvents(struct b3MouseEventsData* mouseEventsData);
virtual void getCachedRaycastHits(struct b3RaycastInformation* raycastHits);
virtual void getCachedMassMatrix(int dofCountCheck, double* massMatrix);
virtual bool getCachedReturnData(struct b3UserDataValue* returnData);
virtual void setTimeOut(double timeOutInSeconds);
virtual double getTimeOut() const;
virtual bool getCachedUserData(int userDataId, struct b3UserDataValue& valueOut) const;
virtual int getCachedUserDataId(int bodyUniqueId, int linkIndex, int visualShapeIndex, const char* key) const;
virtual int getNumUserData(int bodyUniqueId) const;
virtual void getUserDataInfo(int bodyUniqueId, int userDataIndex, const char** keyOut, int* userDataIdOut, int* linkIndexOut, int* visualShapeIndexOut) const;
virtual void pushProfileTiming(const char* timingName);
virtual void popProfileTiming();
};
#endif //PHYSICS_LOOP_BACK_H

View file

@ -0,0 +1,13 @@
#include "PhysicsLoopBackC_API.h"
#include "PhysicsLoopBack.h"
//think more about naming. The b3ConnectPhysicsLoopback
b3PhysicsClientHandle b3ConnectPhysicsLoopback(int key)
{
PhysicsLoopBack* loopBack = new PhysicsLoopBack();
loopBack->setSharedMemoryKey(key);
bool connected;
connected = loopBack->connect();
return (b3PhysicsClientHandle)loopBack;
}

View file

@ -0,0 +1,18 @@
#ifndef PHYSICS_LOOPBACK_C_API_H
#define PHYSICS_LOOPBACK_C_API_H
#include "PhysicsClientC_API.h"
#ifdef __cplusplus
extern "C"
{
#endif
///think more about naming. The b3ConnectPhysicsLoopback
b3PhysicsClientHandle b3ConnectPhysicsLoopback(int key);
#ifdef __cplusplus
}
#endif
#endif //PHYSICS_LOOPBACK_C_API_H

View file

@ -0,0 +1,5 @@
#include "PhysicsServer.h"
PhysicsServer::~PhysicsServer()
{
}

View file

@ -0,0 +1,37 @@
#ifndef PHYSICS_SERVER_H
#define PHYSICS_SERVER_H
#include "LinearMath/btVector3.h"
class PhysicsServer
{
public:
virtual ~PhysicsServer();
virtual void setSharedMemoryKey(int key) = 0;
virtual bool connectSharedMemory(struct GUIHelperInterface* guiHelper) = 0;
virtual void disconnectSharedMemory(bool deInitializeSharedMemory) = 0;
virtual void processClientCommands() = 0;
// virtual bool supportsJointMotor(class btMultiBody* body, int linkIndex)=0;
//@todo(erwincoumans) Should we have shared memory commands for picking objects?
///The pickBody method will try to pick the first body along a ray, return true if succeeds, false otherwise
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) { return false; }
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) { return false; }
virtual void removePickingConstraint() {}
//for physicsDebugDraw and renderScene are mainly for debugging purposes
//and for physics visualization. The idea is that physicsDebugDraw can also send wireframe
//to a physics client, over shared memory
virtual void physicsDebugDraw(int debugDrawFlags) {}
virtual void renderScene(int renderFlags) {}
virtual void enableCommandLogging(bool enable, const char* fileName) {}
virtual void replayFromLogFile(const char* fileName) {}
};
#endif //PHYSICS_SERVER_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,195 @@
#ifndef PHYSICS_SERVER_COMMAND_PROCESSOR_H
#define PHYSICS_SERVER_COMMAND_PROCESSOR_H
#include "LinearMath/btHashMap.h"
#include "LinearMath/btVector3.h"
#include "PhysicsCommandProcessorInterface.h"
#include "../Importers/ImportURDFDemo/UrdfParser.h"
struct SharedMemLines
{
btVector3 m_from;
btVector3 m_to;
btVector3 m_color;
};
///todo: naming. Perhaps PhysicsSdkCommandprocessor?
class PhysicsServerCommandProcessor : public CommandProcessorInterface
{
struct PhysicsServerCommandProcessorInternalData* m_data;
void resetSimulation(int flags = 0);
void createThreadPool();
class btDeformableMultiBodyDynamicsWorld* getDeformableWorld();
class btSoftMultiBodyDynamicsWorld* getSoftWorld();
protected:
bool processStateLoggingCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestCameraImageCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processSaveWorldCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCreateCollisionShapeCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCreateVisualShapeCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestMeshDataCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processResetMeshDataCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCustomCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processUserDebugDrawCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processSetVRCameraStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestVREventsCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestMouseEventsCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestKeyboardEventsCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestRaycastIntersectionsCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestDebugLinesCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processSyncBodyInfoCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processSendDesiredStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestActualStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestContactpointInformationCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestDeformableContactpointHelper(const struct SharedMemoryCommand& clientCmd);
bool processRequestDeformableDeformableContactpointHelper(const struct SharedMemoryCommand& clientCmd);
bool processRequestBodyInfoCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processLoadSDFCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCreateMultiBodyCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCreateMultiBodyCommandSingle(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processLoadURDFCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processLoadSoftBodyCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCreateSensorCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processProfileTimingCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestCollisionInfoCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processForwardDynamicsCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool performCollisionDetectionCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestInternalDataCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processChangeDynamicsInfoCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processSetAdditionalSearchPathCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processGetDynamicsInfoCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestPhysicsSimulationParametersCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processSendPhysicsParametersCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processInitPoseCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processResetSimulationCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCreateRigidBodyCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processPickBodyCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processMovePickedBodyCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRemovePickingConstraintCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestAabbOverlapCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestOpenGLVisualizeCameraCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processConfigureOpenGLVisualizerCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processInverseDynamicsCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCalculateJacobianCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCalculateMassMatrixCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processApplyExternalForceCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRemoveBodyCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCreateUserConstraintCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCalculateInverseKinematicsCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCalculateInverseKinematicsCommand2(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestVisualShapeInfoCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestCollisionShapeInfoCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processUpdateVisualShapeCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processChangeTextureCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processLoadTextureCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processLoadBulletCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processSaveBulletCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processLoadMJCFCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRestoreStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processSaveStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRemoveStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processSyncUserDataCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestUserDataCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processAddUserDataCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRemoveUserDataCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processCollisionFilterCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
int extractCollisionShapes(const class btCollisionShape* colShape, const class btTransform& transform, struct b3CollisionShapeData* collisionShapeBuffer, int maxCollisionShapes);
bool loadSdf(const char* fileName, char* bufferServerToClient, int bufferSizeInBytes, bool useMultiBody, int flags, btScalar globalScaling);
bool loadUrdf(const char* fileName, const class btVector3& pos, const class btQuaternion& orn,
bool useMultiBody, bool useFixedBase, int* bodyUniqueIdPtr, char* bufferServerToClient, int bufferSizeInBytes, int flags, btScalar globalScaling);
bool loadMjcf(const char* fileName, char* bufferServerToClient, int bufferSizeInBytes, bool useMultiBody, int flags);
bool processImportedObjects(const char* fileName, char* bufferServerToClient, int bufferSizeInBytes, bool useMultiBody, int flags, class URDFImporterInterface& u2b);
bool processDeformable(const UrdfDeformable& deformable, const btVector3& pos, const btQuaternion& orn, int* bodyUniqueId, char* bufferServerToClient, int bufferSizeInBytes, btScalar scale, bool useSelfCollision);
bool processReducedDeformable(const UrdfReducedDeformable& deformable, const btVector3& pos, const btQuaternion& orn, int* bodyUniqueId, char* bufferServerToClient, int bufferSizeInBytes, btScalar scale, bool useSelfCollision);
bool supportsJointMotor(class btMultiBody* body, int linkIndex);
int createBodyInfoStream(int bodyUniqueId, char* bufferServerToClient, int bufferSizeInBytes);
void deleteCachedInverseDynamicsBodies();
void deleteCachedInverseKinematicsBodies();
void deleteStateLoggers();
public:
PhysicsServerCommandProcessor();
virtual ~PhysicsServerCommandProcessor();
void createJointMotors(class btMultiBody* body);
virtual void createEmptyDynamicsWorld(int flags = 0);
virtual void deleteDynamicsWorld();
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(int renderFlags);
virtual void physicsDebugDraw(int debugDrawFlags);
virtual void setGuiHelper(struct GUIHelperInterface* guiHelper);
virtual void syncPhysicsToGraphics();
virtual void syncPhysicsToGraphics2();
//@todo(erwincoumans) Should we have shared memory commands for picking objects?
///The pickBody method will try to pick the first body along a ray, return true if succeeds, false otherwise
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld);
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld);
virtual void removePickingConstraint();
//logging /playback the shared memory commands
virtual void enableCommandLogging(bool enable, const char* fileName);
virtual void replayFromLogFile(const char* fileName);
virtual void replayLogCommand(char* bufferServerToClient, int bufferSizeInBytes);
//logging of object states (position etc)
virtual void reportNotifications();
virtual void processClientCommands();
void tickPlugins(btScalar timeStep, bool isPreTick);
void logObjectStates(btScalar timeStep);
void processCollisionForces(btScalar timeStep);
virtual void stepSimulationRealTime(double dtInSec, const struct b3VRControllerEvent* vrControllerEvents, int numVRControllerEvents, const struct b3KeyboardEvent* keyEvents, int numKeyEvents, const struct b3MouseEvent* mouseEvents, int numMouseEvents);
virtual void enableRealTimeSimulation(bool enableRealTimeSim);
virtual bool isRealTimeSimulationEnabled() const;
void applyJointDamping(int bodyUniqueId);
virtual void setTimeOut(double timeOutInSeconds);
virtual const btVector3& getVRTeleportPosition() const;
virtual void setVRTeleportPosition(const btVector3& vrTeleportPos);
virtual const btQuaternion& getVRTeleportOrientation() const;
virtual void setVRTeleportOrientation(const btQuaternion& vrTeleportOrn);
private:
void addBodyChangedNotifications();
int addUserData(int bodyUniqueId, int linkIndex, int visualShapeIndex, const char* key, const char* valueBytes, int valueLength, int valueType);
void addUserData(const btHashMap<btHashString, std::string>& user_data_entries, int bodyUniqueId, int linkIndex = -1, int visualShapeIndex = -1);
};
#endif //PHYSICS_SERVER_COMMAND_PROCESSOR_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef PHYSICS_SERVER_EXAMPLE_H
#define PHYSICS_SERVER_EXAMPLE_H
enum PhysicsServerOptions
{
PHYSICS_SERVER_ENABLE_COMMAND_LOGGING = 1,
PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG = 2,
PHYSICS_SERVER_USE_RTC_CLOCK = 4,
};
///Don't use PhysicsServerCreateFuncInternal directly
///Use PhysicsServerCreateFuncBullet2 instead, or initialize options.m_commandProcessor
class CommonExampleInterface* PhysicsServerCreateFuncInternal(struct CommonExampleOptions& options);
#endif //PHYSICS_SERVER_EXAMPLE_H

View file

@ -0,0 +1,31 @@
#include "PhysicsServerExampleBullet2.h"
#include "PhysicsServerExample.h"
#include "PhysicsServerCommandProcessor.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
struct Bullet2CommandProcessorCreation : public CommandProcessorCreationInterface
{
virtual class CommandProcessorInterface* createCommandProcessor()
{
PhysicsServerCommandProcessor* proc = new PhysicsServerCommandProcessor;
return proc;
}
virtual void deleteCommandProcessor(CommandProcessorInterface* proc)
{
delete proc;
}
};
static Bullet2CommandProcessorCreation sBullet2CommandCreator;
CommonExampleInterface* PhysicsServerCreateFuncBullet2(struct CommonExampleOptions& options)
{
options.m_commandProcessorCreation = &sBullet2CommandCreator;
CommonExampleInterface* example = PhysicsServerCreateFuncInternal(options);
return example;
}
B3_STANDALONE_EXAMPLE(PhysicsServerCreateFuncBullet2)

View file

@ -0,0 +1,7 @@
#ifndef PHYSICS_SERVER_EXAMPLE_BULLET_2_H
#define PHYSICS_SERVER_EXAMPLE_BULLET_2_H
class CommonExampleInterface* PhysicsServerCreateFuncBullet2(struct CommonExampleOptions& options);
#endif //PHYSICS_SERVER_EXAMPLE_BULLET_2_H

View file

@ -0,0 +1,328 @@
#include "PhysicsServerSharedMemory.h"
#include "PosixSharedMemory.h"
#include "Win32SharedMemory.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btTransform.h"
#include "Bullet3Common/b3Logging.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "SharedMemoryBlock.h"
#include "PhysicsCommandProcessorInterface.h"
//number of shared memory blocks == number of simultaneous connections
#define MAX_SHARED_MEMORY_BLOCKS 2
struct PhysicsServerSharedMemoryInternalData
{
///end handle management
SharedMemoryInterface* m_sharedMemory;
bool m_ownsSharedMemory;
SharedMemoryBlock* m_testBlocks[MAX_SHARED_MEMORY_BLOCKS];
int m_sharedMemoryKey;
bool m_areConnected[MAX_SHARED_MEMORY_BLOCKS];
bool m_verboseOutput;
CommandProcessorInterface* m_commandProcessor;
CommandProcessorCreationInterface* m_commandProcessorCreator;
PhysicsServerSharedMemoryInternalData()
: m_sharedMemory(0),
m_ownsSharedMemory(false),
m_sharedMemoryKey(SHARED_MEMORY_KEY),
m_verboseOutput(false),
m_commandProcessor(0)
{
for (int i = 0; i < MAX_SHARED_MEMORY_BLOCKS; i++)
{
m_testBlocks[i] = 0;
m_areConnected[i] = false;
}
}
SharedMemoryStatus& createServerStatus(int statusType, int sequenceNumber, int timeStamp, int blockIndex)
{
SharedMemoryStatus& serverCmd = m_testBlocks[blockIndex]->m_serverCommands[0];
serverCmd.m_type = statusType;
serverCmd.m_sequenceNumber = sequenceNumber;
serverCmd.m_timeStamp = timeStamp;
return serverCmd;
}
void submitServerStatus(SharedMemoryStatus& status, int blockIndex)
{
m_testBlocks[blockIndex]->m_numServerCommands++;
}
};
PhysicsServerSharedMemory::PhysicsServerSharedMemory(CommandProcessorCreationInterface* commandProcessorCreator, SharedMemoryInterface* sharedMem, int bla)
{
m_data = new PhysicsServerSharedMemoryInternalData();
m_data->m_commandProcessorCreator = commandProcessorCreator;
if (sharedMem)
{
m_data->m_sharedMemory = sharedMem;
m_data->m_ownsSharedMemory = false;
}
else
{
#ifdef _WIN32
m_data->m_sharedMemory = new Win32SharedMemoryServer();
#else
m_data->m_sharedMemory = new PosixSharedMemory();
#endif
m_data->m_ownsSharedMemory = true;
}
m_data->m_commandProcessor = commandProcessorCreator->createCommandProcessor();
}
PhysicsServerSharedMemory::~PhysicsServerSharedMemory()
{
if (m_data->m_sharedMemory)
{
if (m_data->m_verboseOutput)
{
b3Printf("m_sharedMemory\n");
}
if (m_data->m_ownsSharedMemory)
{
delete m_data->m_sharedMemory;
}
m_data->m_sharedMemory = 0;
}
m_data->m_commandProcessorCreator->deleteCommandProcessor(m_data->m_commandProcessor);
delete m_data;
}
/*void PhysicsServerSharedMemory::resetDynamicsWorld()
{
m_data->m_commandProcessor->deleteDynamicsWorld();
m_data->m_commandProcessor ->createEmptyDynamicsWorld();
}
*/
void PhysicsServerSharedMemory::setSharedMemoryKey(int key)
{
m_data->m_sharedMemoryKey = key;
}
bool PhysicsServerSharedMemory::connectSharedMemory(struct GUIHelperInterface* guiHelper)
{
m_data->m_commandProcessor->setGuiHelper(guiHelper);
bool allowCreation = true;
bool allConnected = false;
int numConnected = 0;
int counter = 0;
for (int block = 0; block < MAX_SHARED_MEMORY_BLOCKS; block++)
{
if (m_data->m_areConnected[block])
{
allConnected = true;
numConnected++;
b3Warning("connectSharedMemory, while already connected");
continue;
}
do
{
m_data->m_testBlocks[block] = (SharedMemoryBlock*)m_data->m_sharedMemory->allocateSharedMemory(m_data->m_sharedMemoryKey + block, SHARED_MEMORY_SIZE, allowCreation);
if (m_data->m_testBlocks[block])
{
int magicId = m_data->m_testBlocks[block]->m_magicId;
if (m_data->m_verboseOutput)
{
b3Printf("magicId = %d\n", magicId);
}
if (m_data->m_testBlocks[block]->m_magicId != SHARED_MEMORY_MAGIC_NUMBER)
{
InitSharedMemoryBlock(m_data->m_testBlocks[block]);
if (m_data->m_verboseOutput)
{
b3Printf("Created and initialized shared memory block\n");
}
m_data->m_areConnected[block] = true;
numConnected++;
}
else
{
m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey + block, SHARED_MEMORY_SIZE);
m_data->m_testBlocks[block] = 0;
m_data->m_areConnected[block] = false;
}
}
else
{
//b3Error("Cannot connect to shared memory");
m_data->m_areConnected[block] = false;
}
} while (counter++ < 10 && !m_data->m_areConnected[block]);
if (!m_data->m_areConnected[block])
{
b3Error("Server cannot connect to shared memory.\n");
}
}
allConnected = (numConnected == MAX_SHARED_MEMORY_BLOCKS);
return allConnected;
}
void PhysicsServerSharedMemory::disconnectSharedMemory(bool deInitializeSharedMemory)
{
//m_data->m_commandProcessor->deleteDynamicsWorld();
m_data->m_commandProcessor->setGuiHelper(0);
if (m_data->m_verboseOutput)
{
b3Printf("releaseSharedMemory1\n");
}
for (int block = 0; block < MAX_SHARED_MEMORY_BLOCKS; block++)
{
if (m_data->m_testBlocks[block])
{
if (m_data->m_verboseOutput)
{
b3Printf("m_testBlock1\n");
}
if (deInitializeSharedMemory)
{
m_data->m_testBlocks[block]->m_magicId = 0;
if (m_data->m_verboseOutput)
{
b3Printf("De-initialized shared memory, magic id = %d\n", m_data->m_testBlocks[block]->m_magicId);
}
}
btAssert(m_data->m_sharedMemory);
m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey + block, SHARED_MEMORY_SIZE);
}
m_data->m_testBlocks[block] = 0;
m_data->m_areConnected[block] = false;
}
}
void PhysicsServerSharedMemory::releaseSharedMemory()
{
disconnectSharedMemory(true);
}
void PhysicsServerSharedMemory::stepSimulationRealTime(double dtInSec, const struct b3VRControllerEvent* vrEvents, int numVREvents, const struct b3KeyboardEvent* keyEvents, int numKeyEvents, const struct b3MouseEvent* mouseEvents, int numMouseEvents)
{
m_data->m_commandProcessor->stepSimulationRealTime(dtInSec, vrEvents, numVREvents, keyEvents, numKeyEvents, mouseEvents, numMouseEvents);
}
void PhysicsServerSharedMemory::enableRealTimeSimulation(bool enableRealTimeSim)
{
m_data->m_commandProcessor->enableRealTimeSimulation(enableRealTimeSim);
}
bool PhysicsServerSharedMemory::isRealTimeSimulationEnabled() const
{
return m_data->m_commandProcessor->isRealTimeSimulationEnabled();
}
void PhysicsServerSharedMemory::reportNotifications()
{
m_data->m_commandProcessor->reportNotifications();
}
void PhysicsServerSharedMemory::processClientCommands()
{
//handle client commands in any of the plugins
m_data->m_commandProcessor->processClientCommands();
//now handle the client commands from the shared memory
for (int block = 0; block < MAX_SHARED_MEMORY_BLOCKS; block++)
{
if (m_data->m_areConnected[block] && m_data->m_testBlocks[block])
{
m_data->m_commandProcessor->replayLogCommand(&m_data->m_testBlocks[block]->m_bulletStreamDataServerToClientRefactor[0], SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
///we ignore overflow of integer for now
if (m_data->m_testBlocks[block]->m_numClientCommands > m_data->m_testBlocks[block]->m_numProcessedClientCommands)
{
//BT_PROFILE("processClientCommand");
//until we implement a proper ring buffer, we assume always maximum of 1 outstanding commands
btAssert(m_data->m_testBlocks[block]->m_numClientCommands == m_data->m_testBlocks[block]->m_numProcessedClientCommands + 1);
const SharedMemoryCommand& clientCmd = m_data->m_testBlocks[block]->m_clientCommands[0];
m_data->m_testBlocks[block]->m_numProcessedClientCommands++;
//todo, timeStamp
int timeStamp = 0;
SharedMemoryStatus& serverStatusOut = m_data->createServerStatus(CMD_BULLET_DATA_STREAM_RECEIVED_COMPLETED, clientCmd.m_sequenceNumber, timeStamp, block);
bool hasStatus = m_data->m_commandProcessor->processCommand(clientCmd, serverStatusOut, &m_data->m_testBlocks[block]->m_bulletStreamDataServerToClientRefactor[0], SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
if (hasStatus)
{
m_data->submitServerStatus(serverStatusOut, block);
}
}
}
}
}
void PhysicsServerSharedMemory::renderScene(int renderFlags)
{
m_data->m_commandProcessor->renderScene(renderFlags);
}
void PhysicsServerSharedMemory::syncPhysicsToGraphics()
{
m_data->m_commandProcessor->syncPhysicsToGraphics();
}
void PhysicsServerSharedMemory::physicsDebugDraw(int debugDrawFlags)
{
m_data->m_commandProcessor->physicsDebugDraw(debugDrawFlags);
}
bool PhysicsServerSharedMemory::pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
{
return m_data->m_commandProcessor->pickBody(rayFromWorld, rayToWorld);
}
bool PhysicsServerSharedMemory::movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
{
return m_data->m_commandProcessor->movePickedBody(rayFromWorld, rayToWorld);
}
void PhysicsServerSharedMemory::removePickingConstraint()
{
m_data->m_commandProcessor->removePickingConstraint();
}
void PhysicsServerSharedMemory::enableCommandLogging(bool enable, const char* fileName)
{
m_data->m_commandProcessor->enableCommandLogging(enable, fileName);
}
void PhysicsServerSharedMemory::replayFromLogFile(const char* fileName)
{
m_data->m_commandProcessor->replayFromLogFile(fileName);
}
const btVector3& PhysicsServerSharedMemory::getVRTeleportPosition() const
{
return m_data->m_commandProcessor->getVRTeleportPosition();
}
void PhysicsServerSharedMemory::setVRTeleportPosition(const btVector3& vrTeleportPos)
{
m_data->m_commandProcessor->setVRTeleportPosition(vrTeleportPos);
}
const btQuaternion& PhysicsServerSharedMemory::getVRTeleportOrientation() const
{
return m_data->m_commandProcessor->getVRTeleportOrientation();
}
void PhysicsServerSharedMemory::setVRTeleportOrientation(const btQuaternion& vrTeleportOrn)
{
m_data->m_commandProcessor->setVRTeleportOrientation(vrTeleportOrn);
}

View file

@ -0,0 +1,58 @@
#ifndef PHYSICS_SERVER_SHARED_MEMORY_H
#define PHYSICS_SERVER_SHARED_MEMORY_H
#include "PhysicsServer.h"
#include "LinearMath/btQuaternion.h"
class PhysicsServerSharedMemory : public PhysicsServer
{
struct PhysicsServerSharedMemoryInternalData* m_data;
protected:
void releaseSharedMemory();
public:
PhysicsServerSharedMemory(struct CommandProcessorCreationInterface* commandProcessorCreator, class SharedMemoryInterface* sharedMem, int bla);
virtual ~PhysicsServerSharedMemory();
virtual void setSharedMemoryKey(int key);
//todo: implement option to allocated shared memory from client
virtual bool connectSharedMemory(struct GUIHelperInterface* guiHelper);
virtual void disconnectSharedMemory(bool deInitializeSharedMemory);
virtual void processClientCommands();
virtual void stepSimulationRealTime(double dtInSec, const struct b3VRControllerEvent* vrEvents, int numVREvents, const struct b3KeyboardEvent* keyEvents, int numKeyEvents, const struct b3MouseEvent* mouseEvents, int numMouseEvents);
virtual void enableRealTimeSimulation(bool enableRealTimeSim);
virtual bool isRealTimeSimulationEnabled() const;
virtual void reportNotifications();
//bool supportsJointMotor(class btMultiBody* body, int linkIndex);
///The pickBody method will try to pick the first body along a ray, return true if succeeds, false otherwise
virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld);
virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld);
virtual void removePickingConstraint();
virtual const btVector3& getVRTeleportPosition() const;
virtual void setVRTeleportPosition(const btVector3& vrTeleportPos);
virtual const btQuaternion& getVRTeleportOrientation() const;
virtual void setVRTeleportOrientation(const btQuaternion& vrTeleportOrn);
//for physicsDebugDraw and renderScene are mainly for debugging purposes
//and for physics visualization. The idea is that physicsDebugDraw can also send wireframe
//to a physics client, over shared memory
void physicsDebugDraw(int debugDrawFlags);
void renderScene(int renderFlags);
void syncPhysicsToGraphics();
void enableCommandLogging(bool enable, const char* fileName);
void replayFromLogFile(const char* fileName);
};
#endif //PHYSICS_SERVER_EXAMPLESHARED_MEMORY_H

View file

@ -0,0 +1,174 @@
#include "PosixSharedMemory.h"
#include "Bullet3Common/b3Logging.h"
#include "LinearMath/btScalar.h" //for btAssert
#include "LinearMath/btAlignedObjectArray.h"
//Windows implementation is in Win32SharedMemory.cpp
#ifndef _WIN32
#define TEST_SHARED_MEMORY
#endif //_WIN32
//Shmem not available on target api < 26
#if defined(__ANDROID_API__) && (__ANDROID_API__ < 26)
#undef TEST_SHARED_MEMORY
#endif //__ANDROID__
#include <stddef.h>
#ifdef TEST_SHARED_MEMORY
#include <sys/shm.h>
#include <sys/ipc.h>
#endif
struct btSharedMemorySegment
{
int m_key;
int m_sharedMemoryId;
void* m_sharedMemoryPtr;
bool m_createdSharedMemory;
btSharedMemorySegment()
: m_sharedMemoryId(-1),
m_sharedMemoryPtr(0),
m_createdSharedMemory(true)
{
}
};
struct PosixSharedMemoryInteralData
{
btAlignedObjectArray<btSharedMemorySegment> m_segments;
PosixSharedMemoryInteralData()
{
}
};
PosixSharedMemory::PosixSharedMemory()
{
m_internalData = new PosixSharedMemoryInteralData;
}
PosixSharedMemory::~PosixSharedMemory()
{
delete m_internalData;
}
struct btPointerCaster
{
union {
void* ptr;
ptrdiff_t integer;
};
};
void* PosixSharedMemory::allocateSharedMemory(int key, int size, bool allowCreation)
{
#ifdef TEST_SHARED_MEMORY
{
btSharedMemorySegment* seg = 0;
int i = 0;
for (i = 0; i < m_internalData->m_segments.size(); i++)
{
if (m_internalData->m_segments[i].m_key == key)
{
seg = &m_internalData->m_segments[i];
break;
}
}
if (seg)
{
b3Error("already created shared memory segment using same key");
return seg->m_sharedMemoryPtr;
}
}
int flags = (allowCreation ? IPC_CREAT : 0) | 0666;
int id = shmget((key_t)key, (size_t)size, flags);
if (id < 0)
{
//b3Warning("shmget error1");
}
else
{
btPointerCaster result;
result.ptr = shmat(id, 0, 0);
if (result.integer == -1)
{
b3Error("shmat returned -1");
}
else
{
btSharedMemorySegment seg;
seg.m_key = key;
seg.m_createdSharedMemory = allowCreation;
seg.m_sharedMemoryId = id;
seg.m_sharedMemoryPtr = result.ptr;
m_internalData->m_segments.push_back(seg);
return result.ptr;
}
}
#else
//not implemented yet
btAssert(0);
#endif
return 0;
}
void PosixSharedMemory::releaseSharedMemory(int key, int size)
{
#ifdef TEST_SHARED_MEMORY
btSharedMemorySegment* seg = 0;
int i = 0;
for (i = 0; i < m_internalData->m_segments.size(); i++)
{
if (m_internalData->m_segments[i].m_key == key)
{
seg = &m_internalData->m_segments[i];
break;
}
}
if (0 == seg)
{
b3Error("PosixSharedMemory::releaseSharedMemory: shared memory key not found");
return;
}
if (seg->m_sharedMemoryId < 0)
{
b3Error("PosixSharedMemory::releaseSharedMemory: shared memory id is not set");
}
else
{
if (seg->m_createdSharedMemory)
{
int result = shmctl(seg->m_sharedMemoryId, IPC_RMID, 0);
if (result == -1)
{
b3Error("PosixSharedMemory::releaseSharedMemory: shmat returned -1");
}
else
{
b3Printf("PosixSharedMemory::releaseSharedMemory removed shared memory");
}
seg->m_createdSharedMemory = false;
seg->m_sharedMemoryId = -1;
}
if (seg->m_sharedMemoryPtr)
{
shmdt(seg->m_sharedMemoryPtr);
seg->m_sharedMemoryPtr = 0;
b3Printf("PosixSharedMemory::releaseSharedMemory detached shared memory\n");
}
}
m_internalData->m_segments.removeAtIndex(i);
#endif
}

View file

@ -0,0 +1,18 @@
#ifndef POSIX_SHARED_MEMORY_H
#define POSIX_SHARED_MEMORY_H
#include "SharedMemoryInterface.h"
class PosixSharedMemory : public SharedMemoryInterface
{
struct PosixSharedMemoryInteralData* m_internalData;
public:
PosixSharedMemory();
virtual ~PosixSharedMemory();
virtual void* allocateSharedMemory(int key, int size, bool allowCreation);
virtual void releaseSharedMemory(int key, int size);
};
#endif //

View file

@ -0,0 +1,639 @@
#include "RemoteGUIHelper.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "Bullet3Common/b3Logging.h"
#include "GraphicsSharedMemoryCommands.h"
#include "PosixSharedMemory.h"
#include "Win32SharedMemory.h"
#include "GraphicsSharedMemoryBlock.h"
#include "Bullet3Common/b3Scalar.h"
#include "LinearMath/btMinMax.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
struct RemoteGUIHelperInternalData
{
// GUIHelperInterface* m_guiHelper;
bool m_waitingForServer;
GraphicsSharedMemoryBlock* m_testBlock1;
SharedMemoryInterface* m_sharedMemory;
GraphicsSharedMemoryStatus m_lastServerStatus;
int m_sharedMemoryKey;
bool m_isConnected;
RemoteGUIHelperInternalData()
: m_waitingForServer(false),
m_testBlock1(0)
{
#ifdef _WIN32
m_sharedMemory = new Win32SharedMemoryClient();
#else
m_sharedMemory = new PosixSharedMemory();
#endif
m_sharedMemoryKey = GRAPHICS_SHARED_MEMORY_KEY;
m_isConnected = false;
connect();
}
virtual ~RemoteGUIHelperInternalData()
{
disconnect();
delete m_sharedMemory;
}
virtual bool isConnected()
{
return m_isConnected;
}
bool canSubmitCommand() const
{
if (m_isConnected && !m_waitingForServer)
{
if (m_testBlock1->m_magicId == GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER)
{
return true;
}
else
{
return false;
}
}
return false;
}
struct GraphicsSharedMemoryCommand* getAvailableSharedMemoryCommand()
{
static int sequence = 0;
if (m_testBlock1)
{
m_testBlock1->m_clientCommands[0].m_sequenceNumber = sequence++;
return &m_testBlock1->m_clientCommands[0];
}
return 0;
}
bool submitClientCommand(const GraphicsSharedMemoryCommand& command)
{
/// at the moment we allow a maximum of 1 outstanding command, so we check for this
// once the server processed the command and returns a status, we clear the flag
// "m_data->m_waitingForServer" and allow submitting the next command
btAssert(!m_waitingForServer);
if (!m_waitingForServer)
{
//printf("submit command of type %d\n", command.m_type);
if (&m_testBlock1->m_clientCommands[0] != &command)
{
m_testBlock1->m_clientCommands[0] = command;
}
m_testBlock1->m_numClientCommands++;
m_waitingForServer = true;
return true;
}
return false;
}
const GraphicsSharedMemoryStatus* processServerStatus()
{
// SharedMemoryStatus* stat = 0;
if (!m_testBlock1)
{
m_lastServerStatus.m_type = GFX_CMD_SHARED_MEMORY_NOT_INITIALIZED;
return &m_lastServerStatus;
}
if (!m_waitingForServer)
{
return 0;
}
if (m_testBlock1->m_magicId != GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER)
{
m_lastServerStatus.m_type = GFX_CMD_SHARED_MEMORY_NOT_INITIALIZED;
return &m_lastServerStatus;
}
if (m_testBlock1->m_numServerCommands >
m_testBlock1->m_numProcessedServerCommands)
{
B3_PROFILE("processServerCMD");
b3Assert(m_testBlock1->m_numServerCommands ==
m_testBlock1->m_numProcessedServerCommands + 1);
const GraphicsSharedMemoryStatus& serverCmd = m_testBlock1->m_serverCommands[0];
m_lastServerStatus = serverCmd;
// EnumSharedMemoryServerStatus s = (EnumSharedMemoryServerStatus)serverCmd.m_type;
// consume the command
switch (serverCmd.m_type)
{
case GFX_CMD_CLIENT_COMMAND_COMPLETED:
{
B3_PROFILE("CMD_CLIENT_COMMAND_COMPLETED");
break;
}
default:
{
}
}
m_testBlock1->m_numProcessedServerCommands++;
// we don't have more than 1 command outstanding (in total, either server or client)
b3Assert(m_testBlock1->m_numProcessedServerCommands ==
m_testBlock1->m_numServerCommands);
if (m_testBlock1->m_numServerCommands ==
m_testBlock1->m_numProcessedServerCommands)
{
m_waitingForServer = false;
}
else
{
m_waitingForServer = true;
}
return &m_lastServerStatus;
}
return 0;
}
bool connect()
{
/// server always has to create and initialize shared memory
bool allowCreation = false;
m_testBlock1 = (GraphicsSharedMemoryBlock*)m_sharedMemory->allocateSharedMemory(
m_sharedMemoryKey, GRAPHICS_SHARED_MEMORY_SIZE, allowCreation);
if (m_testBlock1)
{
if (m_testBlock1->m_magicId != GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER)
{
b3Error("Error connecting to shared memory: please start server before client\n");
m_sharedMemory->releaseSharedMemory(m_sharedMemoryKey,
GRAPHICS_SHARED_MEMORY_SIZE);
m_testBlock1 = 0;
return false;
}
else
{
m_isConnected = true;
}
}
else
{
b3Warning("Cannot connect to shared memory");
return false;
}
return true;
}
void disconnect()
{
if (m_isConnected && m_sharedMemory)
{
m_sharedMemory->releaseSharedMemory(m_sharedMemoryKey, GRAPHICS_SHARED_MEMORY_SIZE);
}
m_isConnected = false;
}
};
RemoteGUIHelper::RemoteGUIHelper()
{
m_data = new RemoteGUIHelperInternalData;
if (m_data->canSubmitCommand())
{
removeAllGraphicsInstances();
}
}
RemoteGUIHelper::~RemoteGUIHelper()
{
delete m_data;
}
bool RemoteGUIHelper::isConnected() const
{
return m_data->isConnected();
}
void RemoteGUIHelper::setVisualizerFlag(int flag, int enable)
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_updateFlags = 0;
cmd->m_visualizerFlagCommand.m_visualizerFlag = flag;
cmd->m_visualizerFlagCommand.m_enable = enable;
cmd->m_type = GFX_CMD_SET_VISUALIZER_FLAG;
m_data->submitClientCommand(*cmd);
}
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
}
void RemoteGUIHelper::createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color)
{
printf("createRigidBodyGraphicsObject\n");
}
bool RemoteGUIHelper::getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3], float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float camTarget[3]) const
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_updateFlags = 0;
cmd->m_type = GFX_CMD_GET_CAMERA_INFO;
m_data->submitClientCommand(*cmd);
}
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
if (status->m_type == GFX_CMD_GET_CAMERA_INFO_COMPLETED)
{
*width = status->m_getCameraInfoStatus.width;
*height = status->m_getCameraInfoStatus.height;
for (int i = 0; i < 16; i++)
{
viewMatrix[i] = status->m_getCameraInfoStatus.viewMatrix[i];
projectionMatrix[i] = status->m_getCameraInfoStatus.projectionMatrix[i];
}
for (int i = 0; i < 3; i++)
{
camUp[i] = status->m_getCameraInfoStatus.camUp[i];
camForward[i] = status->m_getCameraInfoStatus.camForward[i];
hor[i] = status->m_getCameraInfoStatus.hor[i];
vert[i] = status->m_getCameraInfoStatus.vert[i];
camTarget[i] = status->m_getCameraInfoStatus.camTarget[i];
}
*yaw = status->m_getCameraInfoStatus.yaw;
*pitch = status->m_getCameraInfoStatus.pitch;
*camDist = status->m_getCameraInfoStatus.camDist;
return true;
}
return false;
}
void RemoteGUIHelper::createCollisionObjectGraphicsObject(btCollisionObject* body, const btVector3& color)
{
if (body->getUserIndex() < 0)
{
btCollisionShape* shape = body->getCollisionShape();
btTransform startTransform = body->getWorldTransform();
int graphicsShapeId = shape->getUserIndex();
if (graphicsShapeId >= 0)
{
// btAssert(graphicsShapeId >= 0);
//the graphics shape is already scaled
float localScaling[4] = {1.f, 1.f, 1.f, 1.f};
float colorRGBA[4] = {(float)color[0], (float)color[1], (float)color[2], (float)color[3]};
float pos[4] = {(float)startTransform.getOrigin()[0], (float)startTransform.getOrigin()[1], (float)startTransform.getOrigin()[2], (float)startTransform.getOrigin()[3]};
float orn[4] = {(float)startTransform.getRotation()[0], (float)startTransform.getRotation()[1], (float)startTransform.getRotation()[2], (float)startTransform.getRotation()[3]};
int graphicsInstanceId = registerGraphicsInstance(graphicsShapeId, pos, orn, colorRGBA, localScaling);
body->setUserIndex(graphicsInstanceId);
}
}
}
void RemoteGUIHelper::createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)
{
printf("createCollisionShapeGraphicsObject\n");
}
void RemoteGUIHelper::syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)
{
}
void RemoteGUIHelper::syncPhysicsToGraphics2(const btDiscreteDynamicsWorld* rbWorld)
{
b3AlignedObjectArray<GUISyncPosition> updatedPositions;
int numCollisionObjects = rbWorld->getNumCollisionObjects();
{
B3_PROFILE("write all InstanceTransformToCPU2");
for (int i = 0; i < numCollisionObjects; i++)
{
//B3_PROFILE("writeSingleInstanceTransformToCPU");
btCollisionObject* colObj = rbWorld->getCollisionObjectArray()[i];
btCollisionShape* collisionShape = colObj->getCollisionShape();
btVector3 pos = colObj->getWorldTransform().getOrigin();
btQuaternion orn = colObj->getWorldTransform().getRotation();
int index = colObj->getUserIndex();
if (index >= 0)
{
GUISyncPosition p;
p.m_graphicsInstanceId = index;
for (int q = 0; q < 4; q++)
{
p.m_pos[q] = pos[q];
p.m_orn[q] = orn[q];
}
updatedPositions.push_back(p);
}
}
}
if (updatedPositions.size())
{
syncPhysicsToGraphics2(&updatedPositions[0], updatedPositions.size());
}
}
void RemoteGUIHelper::syncPhysicsToGraphics2(const GUISyncPosition* positions, int numPositions)
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
uploadData((unsigned char*)positions, numPositions * sizeof(GUISyncPosition), 0);
cmd->m_updateFlags = 0;
cmd->m_syncTransformsCommand.m_numPositions = numPositions;
cmd->m_type = GFX_CMD_SYNCHRONIZE_TRANSFORMS;
m_data->submitClientCommand(*cmd);
}
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
}
void RemoteGUIHelper::render(const btDiscreteDynamicsWorld* rbWorld)
{
}
void RemoteGUIHelper::createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld)
{
}
int RemoteGUIHelper::uploadData(const unsigned char* data, int sizeInBytes, int slot)
{
int chunkSize = GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE;
int remainingBytes = sizeInBytes;
int offset = 0;
while (remainingBytes)
{
btAssert(remainingBytes >= 0);
int curBytes = btMin(remainingBytes, chunkSize);
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
for (int i = 0; i < curBytes; i++)
{
m_data->m_testBlock1->m_bulletStreamData[i] = data[i + offset];
}
cmd->m_updateFlags = 0;
cmd->m_type = GFX_CMD_UPLOAD_DATA;
cmd->m_uploadDataCommand.m_numBytes = curBytes;
cmd->m_uploadDataCommand.m_dataOffset = offset;
cmd->m_uploadDataCommand.m_dataSlot = slot;
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
offset += curBytes;
remainingBytes -= curBytes;
}
}
return 0;
}
int RemoteGUIHelper::registerTexture(const unsigned char* texels, int width, int height)
{
int textureId = -1;
//first upload all data
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
int sizeInBytes = width * height * 3; //rgb
uploadData(texels, sizeInBytes, 0);
cmd->m_updateFlags = 0;
cmd->m_type = GFX_CMD_REGISTER_TEXTURE;
cmd->m_registerTextureCommand.m_width = width;
cmd->m_registerTextureCommand.m_height = height;
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
if (status->m_type == GFX_CMD_REGISTER_TEXTURE_COMPLETED)
{
textureId = status->m_registerTextureStatus.m_textureId;
}
}
return textureId;
}
int RemoteGUIHelper::registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId)
{
int shapeId = -1;
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
uploadData((unsigned char*)vertices, numvertices * 9 * sizeof(float), 0);
uploadData((unsigned char*)indices, numIndices * sizeof(int), 1);
cmd->m_type = GFX_CMD_REGISTER_GRAPHICS_SHAPE;
cmd->m_updateFlags = 0;
cmd->m_registerGraphicsShapeCommand.m_numVertices = numvertices;
cmd->m_registerGraphicsShapeCommand.m_numIndices = numIndices;
cmd->m_registerGraphicsShapeCommand.m_primitiveType = primitiveType;
cmd->m_registerGraphicsShapeCommand.m_textureId = textureId;
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
if (status->m_type == GFX_CMD_REGISTER_GRAPHICS_SHAPE_COMPLETED)
{
shapeId = status->m_registerGraphicsShapeStatus.m_shapeId;
}
}
return shapeId;
}
int RemoteGUIHelper::registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling)
{
int graphicsInstanceId = -1;
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_type = GFX_CMD_REGISTER_GRAPHICS_INSTANCE;
cmd->m_updateFlags = 0;
cmd->m_registerGraphicsInstanceCommand.m_shapeIndex = shapeIndex;
for (int i = 0; i < 4; i++)
{
cmd->m_registerGraphicsInstanceCommand.m_position[i] = position[i];
cmd->m_registerGraphicsInstanceCommand.m_quaternion[i] = quaternion[i];
cmd->m_registerGraphicsInstanceCommand.m_color[i] = color[i];
cmd->m_registerGraphicsInstanceCommand.m_scaling[i] = scaling[i];
}
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
if (status->m_type == GFX_CMD_REGISTER_GRAPHICS_INSTANCE_COMPLETED)
{
graphicsInstanceId = status->m_registerGraphicsInstanceStatus.m_graphicsInstanceId;
}
}
return graphicsInstanceId;
}
void RemoteGUIHelper::removeAllGraphicsInstances()
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_updateFlags = 0;
cmd->m_type = GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES;
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
}
}
void RemoteGUIHelper::removeGraphicsInstance(int graphicsUid)
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_updateFlags = 0;
cmd->m_type = GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE;
cmd->m_removeGraphicsInstanceCommand.m_graphicsUid = graphicsUid;
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
}
}
void RemoteGUIHelper::changeScaling(int instanceUid, const double scaling[3])
{
}
void RemoteGUIHelper::changeRGBAColor(int instanceUid, const double rgbaColor[4])
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_updateFlags = 0;
cmd->m_type = GFX_CMD_CHANGE_RGBA_COLOR;
cmd->m_changeRGBAColorCommand.m_graphicsUid = instanceUid;
for (int i = 0; i < 4; i++)
{
cmd->m_changeRGBAColorCommand.m_rgbaColor[i] = rgbaColor[i];
}
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
}
}
Common2dCanvasInterface* RemoteGUIHelper::get2dCanvasInterface()
{
return 0;
}
CommonParameterInterface* RemoteGUIHelper::getParameterInterface()
{
return 0;
}
CommonRenderInterface* RemoteGUIHelper::getRenderInterface()
{
return 0;
}
CommonGraphicsApp* RemoteGUIHelper::getAppInterface()
{
return 0;
}
void RemoteGUIHelper::setUpAxis(int axis)
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_updateFlags = 0;
cmd->m_upAxisYCommand.m_enableUpAxisY = axis == 1;
cmd->m_type = GFX_CMD_0;
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
}
}
void RemoteGUIHelper::resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ)
{
}
void RemoteGUIHelper::copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int width, int height, int* numPixelsCopied)
{
if (numPixelsCopied)
*numPixelsCopied = 0;
}
void RemoteGUIHelper::setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16])
{
}
void RemoteGUIHelper::setProjectiveTexture(bool useProjectiveTexture)
{
}
void RemoteGUIHelper::autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
{
}
void RemoteGUIHelper::drawText3D(const char* txt, float posX, float posZY, float posZ, float size)
{
}
void RemoteGUIHelper::drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag)
{
}
int RemoteGUIHelper::addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid)
{
return -1;
}
int RemoteGUIHelper::addUserDebugPoints(const double debugPointPositionXYZ[3], const double debugPointColorRGB[3], double pointSize, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid, int debugPointNum)
{
return -1;
}
void RemoteGUIHelper::removeUserDebugItem(int debugItemUniqueId)
{
}
void RemoteGUIHelper::removeAllUserDebugItems()
{
}

View file

@ -0,0 +1,79 @@
#ifndef REMOTE_HELPER_H
#define REMOTE_HELPER_H
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
///a RemoteGUIHelper will connect to an existing graphics server through shared memory
struct RemoteGUIHelper : public GUIHelperInterface
{
struct RemoteGUIHelperInternalData* m_data;
RemoteGUIHelper();
virtual ~RemoteGUIHelper();
bool isConnected() const;
virtual void setVisualizerFlag(int flag, int enable);
virtual void createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color);
virtual void createCollisionObjectGraphicsObject(btCollisionObject* body, const btVector3& color);
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape);
virtual bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3], float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float camTarget[3]) const;
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld);
virtual void syncPhysicsToGraphics2(const class btDiscreteDynamicsWorld* rbWorld);
virtual void syncPhysicsToGraphics2(const GUISyncPosition* positions, int numPositions);
virtual void render(const btDiscreteDynamicsWorld* rbWorld);
virtual void createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld);
virtual int registerTexture(const unsigned char* texels, int width, int height);
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId);
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling);
virtual void removeAllGraphicsInstances();
virtual void removeGraphicsInstance(int graphicsUid);
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]);
virtual void changeScaling(int instanceUid, const double scaling[3]);
virtual Common2dCanvasInterface* get2dCanvasInterface();
virtual CommonParameterInterface* getParameterInterface();
virtual CommonRenderInterface* getRenderInterface();
virtual CommonGraphicsApp* getAppInterface();
virtual void setUpAxis(int axis);
virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ);
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int width, int height, int* numPixelsCopied);
virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]);
virtual void setProjectiveTexture(bool useProjectiveTexture);
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld);
virtual void drawText3D(const char* txt, float posX, float posZY, float posZ, float size);
virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag);
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid);
virtual int addUserDebugPoints(const double debugPointPositionXYZ[3], const double debugPointColorRGB[3], double pointSize, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid, int debugPointNum);
virtual void removeUserDebugItem(int debugItemUniqueId);
virtual void removeAllUserDebugItems();
int uploadData(const unsigned char* data, int sizeInBytes, int slot);
};
#endif //REMOTE_HELPER_H

View file

@ -0,0 +1,651 @@
#include "RemoteGUIHelperTCP.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "Bullet3Common/b3Logging.h"
#include "GraphicsSharedMemoryCommands.h"
#include "GraphicsSharedMemoryBlock.h"
#include "Bullet3Common/b3Scalar.h"
#include "LinearMath/btMinMax.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
#include "ActiveSocket.h"
#include <string>
static unsigned int b3DeserializeInt3(const unsigned char* input)
{
unsigned int tmp = (input[3] << 24) + (input[2] << 16) + (input[1] << 8) + input[0];
return tmp;
}
static bool gVerboseNetworkMessagesClient3 = true;//false;
const char* cmd2txt[]=
{
"GFX_CMD_INVALID",
"GFX_CMD_0",
"GFX_CMD_SET_VISUALIZER_FLAG",
"GFX_CMD_UPLOAD_DATA",
"GFX_CMD_REGISTER_TEXTURE",
"GFX_CMD_REGISTER_GRAPHICS_SHAPE",
"GFX_CMD_REGISTER_GRAPHICS_INSTANCE",
"GFX_CMD_SYNCHRONIZE_TRANSFORMS",
"GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES",
"GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE",
"GFX_CMD_CHANGE_RGBA_COLOR",
"GFX_CMD_GET_CAMERA_INFO",
//don't go beyond this command!
"GFX_CMD_MAX_CLIENT_COMMANDS",
};
struct RemoteGUIHelperTCPInternalData
{
// GUIHelperInterface* m_guiHelper;
bool m_waitingForServer;
std::string m_hostName;
int m_port;
GraphicsSharedMemoryStatus m_lastServerStatus;
CActiveSocket m_tcpSocket;
bool m_isConnected;
b3AlignedObjectArray<unsigned char> m_tempBuffer;
GraphicsSharedMemoryStatus m_lastStatus;
GraphicsSharedMemoryCommand m_command;
double m_timeOutInSeconds;
b3AlignedObjectArray<char> m_stream;
RemoteGUIHelperTCPInternalData(const char* hostName, int port)
: m_waitingForServer(false),
m_hostName(hostName),
m_port(port),
m_timeOutInSeconds(60.)
{
m_isConnected = false;
connect();
}
virtual ~RemoteGUIHelperTCPInternalData()
{
disconnect();
}
virtual bool isConnected()
{
return m_isConnected;
}
bool canSubmitCommand() const
{
if (m_isConnected && !m_waitingForServer)
{
return true;
}
return false;
}
struct GraphicsSharedMemoryCommand* getAvailableSharedMemoryCommand()
{
static int sequence = 0;
m_command.m_sequenceNumber = sequence++;
return &m_command;
}
bool submitClientCommand(const GraphicsSharedMemoryCommand& command)
{
if (gVerboseNetworkMessagesClient3)
printf("submitClientCommand: %d %s\n", command.m_type, cmd2txt[command.m_type]);
/// at the moment we allow a maximum of 1 outstanding command, so we check for this
// once the server processed the command and returns a status, we clear the flag
// "m_data->m_waitingForServer" and allow submitting the next command
btAssert(!m_waitingForServer);
if (!m_waitingForServer)
{
int sz = 0;
unsigned char* data = 0;
m_tempBuffer.clear();
sz = sizeof(GraphicsSharedMemoryCommand);
data = (unsigned char*)&command;
//printf("submit command of type %d\n", command.m_type);
m_tcpSocket.Send((const uint8*)data, sz);
m_waitingForServer = true;
return true;
}
return false;
}
const GraphicsSharedMemoryStatus* processServerStatus()
{
bool hasStatus = false;
//int serviceResult = enet_host_service(m_client, &m_event, 0);
int maxLen = 4 + sizeof(GraphicsSharedMemoryStatus) + GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE;
int rBytes = m_tcpSocket.Receive(maxLen);
if (rBytes <= 0)
return 0;
//append to tmp buffer
//recBytes
unsigned char* d2 = (unsigned char*)m_tcpSocket.GetData();
int curSize = m_tempBuffer.size();
m_tempBuffer.resize(curSize + rBytes);
for (int i = 0; i < rBytes; i++)
{
m_tempBuffer[curSize + i] = d2[i];
}
int packetSizeInBytes = -1;
if (m_tempBuffer.size() >= 4)
{
packetSizeInBytes = b3DeserializeInt3(&m_tempBuffer[0]);
}
if (m_tempBuffer.size() == packetSizeInBytes)
{
unsigned char* data = &m_tempBuffer[0];
if (gVerboseNetworkMessagesClient3)
{
printf("A packet of length %d bytes received\n", m_tempBuffer.size());
}
hasStatus = true;
GraphicsSharedMemoryStatus* statPtr = (GraphicsSharedMemoryStatus*)&data[4];
#if 0
if (statPtr->m_type == CMD_STEP_FORWARD_SIMULATION_COMPLETED)
{
GraphicsSharedMemoryStatus dummy;
dummy.m_type = CMD_STEP_FORWARD_SIMULATION_COMPLETED;
m_lastStatus = dummy;
m_stream.resize(0);
}
else
#endif
{
m_lastStatus = *statPtr;
int streamOffsetInBytes = 4 + sizeof(GraphicsSharedMemoryStatus);
int numStreamBytes = packetSizeInBytes - streamOffsetInBytes;
m_stream.resize(numStreamBytes);
for (int i = 0; i < numStreamBytes; i++)
{
m_stream[i] = data[i + streamOffsetInBytes];
}
}
m_tempBuffer.clear();
m_waitingForServer = false;
if (gVerboseNetworkMessagesClient3)
printf("processServerStatus: %d\n", m_lastStatus.m_type);
return &m_lastStatus;
}
return 0;
}
bool connect()
{
if (m_isConnected)
return true;
m_tcpSocket.Initialize();
m_isConnected = m_tcpSocket.Open(m_hostName.c_str(), m_port);
if (m_isConnected)
{
m_tcpSocket.SetSendTimeout(m_timeOutInSeconds, 0);
m_tcpSocket.SetReceiveTimeout(m_timeOutInSeconds, 0);
}
int key = GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER;
m_tcpSocket.Send((uint8*)&key, 4);
m_tcpSocket.SetBlocking();
return m_isConnected;
}
void disconnect()
{
const char msg[16] = "disconnect";
m_tcpSocket.Send((const uint8*)msg, 10);
m_tcpSocket.Close();
m_isConnected = false;
}
};
RemoteGUIHelperTCP::RemoteGUIHelperTCP(const char* hostName, int port)
{
m_data = new RemoteGUIHelperTCPInternalData(hostName, port);
if (m_data->canSubmitCommand())
{
removeAllGraphicsInstances();
}
}
RemoteGUIHelperTCP::~RemoteGUIHelperTCP()
{
delete m_data;
}
void RemoteGUIHelperTCP::setVisualizerFlag(int flag, int enable)
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_updateFlags = 0;
cmd->m_visualizerFlagCommand.m_visualizerFlag = flag;
cmd->m_visualizerFlagCommand.m_enable = enable;
cmd->m_type = GFX_CMD_SET_VISUALIZER_FLAG;
m_data->submitClientCommand(*cmd);
}
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
}
void RemoteGUIHelperTCP::createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color)
{
printf("todo: createRigidBodyGraphicsObject\n");
}
bool RemoteGUIHelperTCP::getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3], float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float camTarget[3]) const
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_updateFlags = 0;
cmd->m_type = GFX_CMD_GET_CAMERA_INFO;
m_data->submitClientCommand(*cmd);
}
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
if (status->m_type == GFX_CMD_GET_CAMERA_INFO_COMPLETED)
{
*width = status->m_getCameraInfoStatus.width;
*height = status->m_getCameraInfoStatus.height;
for (int i = 0; i < 16; i++)
{
viewMatrix[i] = status->m_getCameraInfoStatus.viewMatrix[i];
projectionMatrix[i] = status->m_getCameraInfoStatus.projectionMatrix[i];
}
for (int i = 0; i < 3; i++)
{
camUp[i] = status->m_getCameraInfoStatus.camUp[i];
camForward[i] = status->m_getCameraInfoStatus.camForward[i];
hor[i] = status->m_getCameraInfoStatus.hor[i];
vert[i] = status->m_getCameraInfoStatus.vert[i];
camTarget[i] = status->m_getCameraInfoStatus.camTarget[i];
}
*yaw = status->m_getCameraInfoStatus.yaw;
*pitch = status->m_getCameraInfoStatus.pitch;
*camDist = status->m_getCameraInfoStatus.camDist;
return true;
}
return false;
}
void RemoteGUIHelperTCP::createCollisionObjectGraphicsObject(btCollisionObject* body, const btVector3& color)
{
if (body->getUserIndex() < 0)
{
btCollisionShape* shape = body->getCollisionShape();
btTransform startTransform = body->getWorldTransform();
int graphicsShapeId = shape->getUserIndex();
if (graphicsShapeId >= 0)
{
// btAssert(graphicsShapeId >= 0);
//the graphics shape is already scaled
float localScaling[4] = {1.f, 1.f, 1.f, 1.f};
float colorRGBA[4] = {(float)color[0], (float)color[1], (float)color[2], (float)color[3]};
float pos[4] = {(float)startTransform.getOrigin()[0], (float)startTransform.getOrigin()[1], (float)startTransform.getOrigin()[2], (float)startTransform.getOrigin()[3]};
float orn[4] = {(float)startTransform.getRotation()[0], (float)startTransform.getRotation()[1], (float)startTransform.getRotation()[2], (float)startTransform.getRotation()[3]};
int graphicsInstanceId = registerGraphicsInstance(graphicsShapeId, pos, orn, colorRGBA, localScaling);
body->setUserIndex(graphicsInstanceId);
}
}
}
void RemoteGUIHelperTCP::createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)
{
printf("todo; createCollisionShapeGraphicsObject\n");
}
void RemoteGUIHelperTCP::syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)
{
}
void RemoteGUIHelperTCP::syncPhysicsToGraphics2(const btDiscreteDynamicsWorld* rbWorld)
{
b3AlignedObjectArray<GUISyncPosition> updatedPositions;
int numCollisionObjects = rbWorld->getNumCollisionObjects();
{
B3_PROFILE("write all InstanceTransformToCPU2");
for (int i = 0; i < numCollisionObjects; i++)
{
//B3_PROFILE("writeSingleInstanceTransformToCPU");
btCollisionObject* colObj = rbWorld->getCollisionObjectArray()[i];
btCollisionShape* collisionShape = colObj->getCollisionShape();
btVector3 pos = colObj->getWorldTransform().getOrigin();
btQuaternion orn = colObj->getWorldTransform().getRotation();
int index = colObj->getUserIndex();
if (index >= 0)
{
GUISyncPosition p;
p.m_graphicsInstanceId = index;
for (int q = 0; q < 4; q++)
{
p.m_pos[q] = pos[q];
p.m_orn[q] = orn[q];
}
updatedPositions.push_back(p);
}
}
}
if (updatedPositions.size())
{
syncPhysicsToGraphics2(&updatedPositions[0], updatedPositions.size());
}
}
void RemoteGUIHelperTCP::syncPhysicsToGraphics2(const GUISyncPosition* positions, int numPositions)
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
uploadData((unsigned char*)positions, numPositions * sizeof(GUISyncPosition), 0);
cmd->m_updateFlags = 0;
cmd->m_syncTransformsCommand.m_numPositions = numPositions;
cmd->m_type = GFX_CMD_SYNCHRONIZE_TRANSFORMS;
m_data->submitClientCommand(*cmd);
}
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
}
void RemoteGUIHelperTCP::render(const btDiscreteDynamicsWorld* rbWorld)
{
}
void RemoteGUIHelperTCP::createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld)
{
}
int RemoteGUIHelperTCP::uploadData(const unsigned char* data, int sizeInBytes, int slot)
{
int chunkSize = 1024;// GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE;
int remainingBytes = sizeInBytes;
int offset = 0;
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
cmd->m_updateFlags = 0;
cmd->m_type = GFX_CMD_UPLOAD_DATA;
cmd->m_uploadDataCommand.m_numBytes = sizeInBytes;
cmd->m_uploadDataCommand.m_dataOffset = offset;
cmd->m_uploadDataCommand.m_dataSlot = slot;
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
while (remainingBytes > 0)
{
int curBytes = btMin(remainingBytes, chunkSize);
m_data->m_tcpSocket.Send((const uint8*)data+offset, curBytes);
if (gVerboseNetworkMessagesClient3)
printf("sending %d bytes\n", curBytes);
remainingBytes -= curBytes;
offset += curBytes;
}
if (gVerboseNetworkMessagesClient3)
printf("send all bytes!\n");
status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
return 0;
}
int RemoteGUIHelperTCP::registerTexture(const unsigned char* texels, int width, int height)
{
int textureId = -1;
//first upload all data
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
int sizeInBytes = width * height * 3; //rgb
uploadData(texels, sizeInBytes, 0);
cmd->m_updateFlags = 0;
cmd->m_type = GFX_CMD_REGISTER_TEXTURE;
cmd->m_registerTextureCommand.m_width = width;
cmd->m_registerTextureCommand.m_height = height;
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
if (status->m_type == GFX_CMD_REGISTER_TEXTURE_COMPLETED)
{
textureId = status->m_registerTextureStatus.m_textureId;
}
}
return textureId;
}
int RemoteGUIHelperTCP::registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId)
{
int shapeId = -1;
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
uploadData((unsigned char*)vertices, numvertices * 9 * sizeof(float), 0);
uploadData((unsigned char*)indices, numIndices * sizeof(int), 1);
cmd->m_type = GFX_CMD_REGISTER_GRAPHICS_SHAPE;
cmd->m_updateFlags = 0;
cmd->m_registerGraphicsShapeCommand.m_numVertices = numvertices;
cmd->m_registerGraphicsShapeCommand.m_numIndices = numIndices;
cmd->m_registerGraphicsShapeCommand.m_primitiveType = primitiveType;
cmd->m_registerGraphicsShapeCommand.m_textureId = textureId;
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
if (status->m_type == GFX_CMD_REGISTER_GRAPHICS_SHAPE_COMPLETED)
{
shapeId = status->m_registerGraphicsShapeStatus.m_shapeId;
}
}
return shapeId;
}
int RemoteGUIHelperTCP::registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling)
{
int graphicsInstanceId = -1;
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_type = GFX_CMD_REGISTER_GRAPHICS_INSTANCE;
cmd->m_updateFlags = 0;
cmd->m_registerGraphicsInstanceCommand.m_shapeIndex = shapeIndex;
for (int i = 0; i < 4; i++)
{
cmd->m_registerGraphicsInstanceCommand.m_position[i] = position[i];
cmd->m_registerGraphicsInstanceCommand.m_quaternion[i] = quaternion[i];
cmd->m_registerGraphicsInstanceCommand.m_color[i] = color[i];
cmd->m_registerGraphicsInstanceCommand.m_scaling[i] = scaling[i];
}
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
if (status->m_type == GFX_CMD_REGISTER_GRAPHICS_INSTANCE_COMPLETED)
{
graphicsInstanceId = status->m_registerGraphicsInstanceStatus.m_graphicsInstanceId;
}
}
return graphicsInstanceId;
}
void RemoteGUIHelperTCP::removeAllGraphicsInstances()
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_updateFlags = 0;
cmd->m_type = GFX_CMD_REMOVE_ALL_GRAPHICS_INSTANCES;
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
}
}
void RemoteGUIHelperTCP::removeGraphicsInstance(int graphicsUid)
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_updateFlags = 0;
cmd->m_type = GFX_CMD_REMOVE_SINGLE_GRAPHICS_INSTANCE;
cmd->m_removeGraphicsInstanceCommand.m_graphicsUid = graphicsUid;
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
}
}
void RemoteGUIHelperTCP::changeRGBAColor(int instanceUid, const double rgbaColor[4])
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_updateFlags = 0;
cmd->m_type = GFX_CMD_CHANGE_RGBA_COLOR;
cmd->m_changeRGBAColorCommand.m_graphicsUid = instanceUid;
for (int i = 0; i < 4; i++)
{
cmd->m_changeRGBAColorCommand.m_rgbaColor[i] = rgbaColor[i];
}
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
}
}
Common2dCanvasInterface* RemoteGUIHelperTCP::get2dCanvasInterface()
{
return 0;
}
CommonParameterInterface* RemoteGUIHelperTCP::getParameterInterface()
{
return 0;
}
CommonRenderInterface* RemoteGUIHelperTCP::getRenderInterface()
{
return 0;
}
CommonGraphicsApp* RemoteGUIHelperTCP::getAppInterface()
{
return 0;
}
void RemoteGUIHelperTCP::setUpAxis(int axis)
{
GraphicsSharedMemoryCommand* cmd = m_data->getAvailableSharedMemoryCommand();
if (cmd)
{
cmd->m_updateFlags = 0;
cmd->m_upAxisYCommand.m_enableUpAxisY = axis == 1;
cmd->m_type = GFX_CMD_0;
m_data->submitClientCommand(*cmd);
const GraphicsSharedMemoryStatus* status = 0;
while ((status = m_data->processServerStatus()) == 0)
{
}
}
}
void RemoteGUIHelperTCP::resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ)
{
}
void RemoteGUIHelperTCP::copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int width, int height, int* numPixelsCopied)
{
if (numPixelsCopied)
*numPixelsCopied = 0;
}
void RemoteGUIHelperTCP::setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16])
{
}
void RemoteGUIHelperTCP::setProjectiveTexture(bool useProjectiveTexture)
{
}
void RemoteGUIHelperTCP::autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld)
{
}
void RemoteGUIHelperTCP::drawText3D(const char* txt, float posX, float posZY, float posZ, float size)
{
}
void RemoteGUIHelperTCP::drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag)
{
}
int RemoteGUIHelperTCP::addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid)
{
return -1;
}
int RemoteGUIHelperTCP::addUserDebugPoints(const double debugPointPositionXYZ[3], const double debugPointColorRGB[3], double pointSize, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid, int debugPointNum)
{
return -1;
}
void RemoteGUIHelperTCP::removeUserDebugItem(int debugItemUniqueId)
{
}
void RemoteGUIHelperTCP::removeAllUserDebugItems()
{
}

View file

@ -0,0 +1,77 @@
#ifndef REMOTE_HELPER_TCP_H
#define REMOTE_HELPER_TCP_H
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
///a RemoteGUIHelper will connect to an existing graphics server over TCP
struct RemoteGUIHelperTCP : public GUIHelperInterface
{
struct RemoteGUIHelperTCPInternalData* m_data;
RemoteGUIHelperTCP(const char* hostName, int port);
virtual ~RemoteGUIHelperTCP();
virtual void setVisualizerFlag(int flag, int enable);
virtual void createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color);
virtual void createCollisionObjectGraphicsObject(btCollisionObject* body, const btVector3& color);
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape);
virtual bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3], float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float camTarget[3]) const;
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld);
virtual void syncPhysicsToGraphics2(const class btDiscreteDynamicsWorld* rbWorld);
virtual void syncPhysicsToGraphics2(const GUISyncPosition* positions, int numPositions);
virtual void render(const btDiscreteDynamicsWorld* rbWorld);
virtual void createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld);
virtual int registerTexture(const unsigned char* texels, int width, int height);
virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId);
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling);
virtual void removeAllGraphicsInstances();
virtual void removeGraphicsInstance(int graphicsUid);
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]);
virtual Common2dCanvasInterface* get2dCanvasInterface();
virtual CommonParameterInterface* getParameterInterface();
virtual CommonRenderInterface* getRenderInterface();
virtual CommonGraphicsApp* getAppInterface();
virtual void setUpAxis(int axis);
virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ);
virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16],
unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels,
float* depthBuffer, int depthBufferSizeInPixels,
int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels,
int startPixelIndex, int width, int height, int* numPixelsCopied);
virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]);
virtual void setProjectiveTexture(bool useProjectiveTexture);
virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld);
virtual void drawText3D(const char* txt, float posX, float posZY, float posZ, float size);
virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag);
virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid);
virtual int addUserDebugPoints(const double debugPointPositionXYZ[3], const double debugPointColorRGB[3], double pointSize, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid, int debugPointNum);
virtual void removeUserDebugItem(int debugItemUniqueId);
virtual void removeAllUserDebugItems();
int uploadData(const unsigned char* data, int sizeInBytes, int slot);
virtual bool isRemoteVisualizer() { return true; }
};
#endif //REMOTE_HELPER_TCP_H

View file

@ -0,0 +1,666 @@
#include "RobotControlExample.h"
#if 0
#include "../CommonInterfaces/CommonParameterInterface.h"
#include "PhysicsServer.h"
#include "PhysicsClient.h"
#include "SharedMemoryCommon.h"
#include "../Utils/b3Clock.h"
#include "PhysicsClientC_API.h"
#include "../Utils/b3ResourcePath.h"
#include <string>
//const char* blaatnaam = "basename";
struct MyMotorInfo
{
std::string m_jointName;
btScalar m_velTarget;
btScalar m_posTarget;
btScalar m_kp;
btScalar m_kd;
btScalar m_maxForce;
int m_uIndex;
int m_posIndex;
int m_jointIndex;
btScalar m_measuredJointPosition;
btScalar m_measuredJointVelocity;
btVector3 m_measuredJointForce;
btVector3 m_measuredJointTorque;
};
#define MAX_NUM_MOTORS 128
class RobotControlExample : public SharedMemoryCommon
{
PhysicsServerSharedMemory m_physicsServer;
PhysicsClientSharedMemory m_physicsClient;
b3Clock m_realtimeClock;
int m_sequenceNumberGenerator;
bool m_wantsShutdown;
btAlignedObjectArray<SharedMemoryCommand> m_userCommandRequests;
void createButton(const char* name, int id, bool isTrigger );
public:
//@todo, add accessor methods
MyMotorInfo m_motorTargetState[MAX_NUM_MOTORS];
int m_numMotors;
int m_option;
bool m_verboseOutput;
RobotControlExample(GUIHelperInterface* helper, int option);
virtual ~RobotControlExample();
virtual void initPhysics();
virtual void stepSimulation(float deltaTime);
void prepareControlCommand(SharedMemoryCommand& cmd);
void enqueueCommand(const SharedMemoryCommand& orgCommand)
{
m_userCommandRequests.push_back(orgCommand);
SharedMemoryCommand& cmd = m_userCommandRequests[m_userCommandRequests.size()-1];
cmd.m_sequenceNumber = m_sequenceNumberGenerator++;
cmd.m_timeStamp = m_realtimeClock.getTimeMicroseconds();
if (m_verboseOutput)
{
b3Printf("User put command request %d on queue (queue length = %d)\n",cmd.m_type, m_userCommandRequests.size());
}
}
virtual void resetCamera()
{
float dist = 5;
float pitch = 50;
float yaw = 35;
float targetPos[3]={0,0,0};//-3,2.8,-2.5};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
}
virtual bool wantsTermination();
virtual bool isConnected();
virtual void renderScene()
{
m_physicsServer.renderScene();
}
virtual void exitPhysics(){}
virtual void physicsDebugDraw(int debugFlags)
{
m_physicsServer.physicsDebugDraw(debugFlags);
}
virtual bool mouseMoveCallback(float x,float y){return false;};
virtual bool mouseButtonCallback(int button, int state, float x, float y){return false;}
virtual bool keyboardCallback(int key, int state){return false;}
virtual void setSharedMemoryKey(int key)
{
m_physicsServer.setSharedMemoryKey(key);
m_physicsClient.setSharedMemoryKey(key);
}
};
bool RobotControlExample::isConnected()
{
return m_physicsClient.isConnected();
}
void MyCallback2(int buttonId, bool buttonState, void* userPtr)
{
RobotControlExample* cl = (RobotControlExample*) userPtr;
SharedMemoryCommand command;
switch (buttonId)
{
case CMD_LOAD_URDF:
{
command.m_type =CMD_LOAD_URDF;
command.m_updateFlags = URDF_ARGS_FILE_NAME|URDF_ARGS_INITIAL_POSITION|URDF_ARGS_INITIAL_ORIENTATION;
sprintf(command.m_urdfArguments.m_urdfFileName,"r2d2.urdf");//kuka_lwr/kuka.urdf");//r2d2.urdf");
command.m_urdfArguments.m_initialPosition[0] = 0.0;
command.m_urdfArguments.m_initialPosition[1] = 0.0;
command.m_urdfArguments.m_initialPosition[2] = 0.0;
command.m_urdfArguments.m_initialOrientation[0] = 0.0;
command.m_urdfArguments.m_initialOrientation[1] = 0.0;
command.m_urdfArguments.m_initialOrientation[2] = 0.0;
command.m_urdfArguments.m_initialOrientation[3] = 1.0;
command.m_urdfArguments.m_useFixedBase = false;
command.m_urdfArguments.m_useMultiBody = true;
cl->enqueueCommand(command);
break;
}
case CMD_SEND_PHYSICS_SIMULATION_PARAMETERS:
{
//#ifdef USE_C_API
b3InitPhysicsParamCommand(&command);
b3PhysicsParamSetGravity(&command, 1,1,-10);
// #else
//
// command.m_type = CMD_SEND_PHYSICS_SIMULATION_PARAMETERS;
// command.m_physSimParamArgs.m_gravityAcceleration[0] = 0;
// command.m_physSimParamArgs.m_gravityAcceleration[1] = 0;
// command.m_physSimParamArgs.m_gravityAcceleration[2] = -10;
// command.m_physSimParamArgs.m_updateFlags = SIM_PARAM_UPDATE_GRAVITY;
// #endif // USE_C_API
cl->enqueueCommand(command);
break;
};
case CMD_INIT_POSE:
{
///@todo: implement this
command.m_type = CMD_INIT_POSE;
cl->enqueueCommand(command);
break;
}
case CMD_CREATE_BOX_COLLISION_SHAPE:
{
command.m_type =CMD_CREATE_BOX_COLLISION_SHAPE;
command.m_updateFlags = BOX_SHAPE_HAS_INITIAL_POSITION;
command.m_createBoxShapeArguments.m_initialPosition[0] = 0;
command.m_createBoxShapeArguments.m_initialPosition[1] = 0;
command.m_createBoxShapeArguments.m_initialPosition[2] = -3;
cl->enqueueCommand(command);
break;
}
case CMD_REQUEST_ACTUAL_STATE:
{
command.m_type =CMD_REQUEST_ACTUAL_STATE;
cl->enqueueCommand(command);
break;
};
case CMD_STEP_FORWARD_SIMULATION:
{
command.m_type =CMD_STEP_FORWARD_SIMULATION;
cl->enqueueCommand(command);
break;
}
case CMD_SEND_DESIRED_STATE:
{
command.m_type =CMD_SEND_DESIRED_STATE;
cl->prepareControlCommand(command);
cl->enqueueCommand(command);
break;
}
case CMD_SEND_BULLET_DATA_STREAM:
{
command.m_type = buttonId;
sprintf(command.m_dataStreamArguments.m_bulletFileName,"slope.bullet");
command.m_dataStreamArguments.m_streamChunkLength = 0;
cl->enqueueCommand(command);
break;
}
default:
{
b3Error("Unknown buttonId");
btAssert(0);
}
};
}
void RobotControlExample::prepareControlCommand(SharedMemoryCommand& command)
{
for (int i=0;i<MAX_DEGREE_OF_FREEDOM;i++)
{
command.m_sendDesiredStateCommandArgument.m_desiredStateQdot[i] = 0;
command.m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[i] = 0;
}
switch (m_option)
{
case ROBOT_VELOCITY_CONTROL:
{
command.m_sendDesiredStateCommandArgument.m_controlMode = CONTROL_MODE_VELOCITY;
for (int i=0;i<MAX_DEGREE_OF_FREEDOM;i++)
{
command.m_sendDesiredStateCommandArgument.m_desiredStateQdot[i] = 0;
command.m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[i] = 1000;
}
for (int i=0;i<m_numMotors;i++)
{
btScalar targetVel = m_motorTargetState[i].m_velTarget;
int uIndex = m_motorTargetState[i].m_uIndex;
command.m_sendDesiredStateCommandArgument.m_desiredStateQdot[uIndex] = targetVel;
}
break;
}
case ROBOT_PD_CONTROL:
{
command.m_sendDesiredStateCommandArgument.m_controlMode = CONTROL_MODE_POSITION_VELOCITY_PD;
for (int i=0;i<m_numMotors;i++)
{
int uIndex = m_motorTargetState[i].m_uIndex;
command.m_sendDesiredStateCommandArgument.m_Kp[uIndex] = m_motorTargetState[i].m_kp;
command.m_sendDesiredStateCommandArgument.m_Kd[uIndex] = m_motorTargetState[i].m_kd;
command.m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[uIndex] = 10000;//max force
btScalar targetVel = m_motorTargetState[i].m_velTarget;
command.m_sendDesiredStateCommandArgument.m_desiredStateQdot[uIndex] = targetVel;
int posIndex = m_motorTargetState[i].m_posIndex;
btScalar targetPos = m_motorTargetState[i].m_posTarget;
command.m_sendDesiredStateCommandArgument.m_desiredStateQ[posIndex] = targetPos;
}
break;
}
case ROBOT_PING_PONG_JOINT_FEEDBACK:
{
command.m_sendDesiredStateCommandArgument.m_controlMode = CONTROL_MODE_VELOCITY;
for (int i=0;i<MAX_DEGREE_OF_FREEDOM;i++)
{
command.m_sendDesiredStateCommandArgument.m_desiredStateQdot[i] = 0;
command.m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[i] = 1000;
}
for (int i=0;i<m_numMotors;i++)
{
btScalar targetVel = m_motorTargetState[i].m_velTarget;
int uIndex = m_motorTargetState[i].m_uIndex;
command.m_sendDesiredStateCommandArgument.m_desiredStateQdot[uIndex] = m_motorTargetState[i].m_velTarget;
}
break;
}
default:
{
b3Warning("Unknown control mode in RobotControlExample::prepareControlCommand");
}
};
}
void RobotControlExample::createButton(const char* name, int buttonId, bool isTrigger )
{
ButtonParams button(name,buttonId, isTrigger);
button.m_callback = MyCallback2;
button.m_userPointer = this;
m_guiHelper->getParameterInterface()->registerButtonParameter(button);
}
RobotControlExample::RobotControlExample(GUIHelperInterface* helper, int option)
:SharedMemoryCommon(helper),
m_wantsShutdown(false),
m_sequenceNumberGenerator(0),
m_numMotors(0),
m_option(option),
m_verboseOutput(false)
{
bool useServer = true;
}
RobotControlExample::~RobotControlExample()
{
bool deInitializeSharedMemory = true;
m_physicsClient.disconnectSharedMemory();
m_physicsServer.disconnectSharedMemory(deInitializeSharedMemory);
}
void RobotControlExample::initPhysics()
{
///for this testing we use Z-axis up
int upAxis = 2;
m_guiHelper->setUpAxis(upAxis);
/* createEmptyDynamicsWorld();
//todo: create a special debug drawer that will cache the lines, so we can send the debug info over the wire
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
btVector3 grav(0,0,0);
grav[upAxis] = 0;//-9.8;
this->m_dynamicsWorld->setGravity(grav);
*/
m_physicsServer.connectSharedMemory( m_guiHelper);
if (m_guiHelper && m_guiHelper->getParameterInterface())
{
bool isTrigger = false;
createButton("Load URDF",CMD_LOAD_URDF, isTrigger);
createButton("Step Sim",CMD_STEP_FORWARD_SIMULATION, isTrigger);
createButton("Send Bullet Stream",CMD_SEND_BULLET_DATA_STREAM, isTrigger);
createButton("Get State",CMD_REQUEST_ACTUAL_STATE, isTrigger);
createButton("Send Desired State",CMD_SEND_DESIRED_STATE, isTrigger);
createButton("Create Box Collider",CMD_CREATE_BOX_COLLISION_SHAPE,isTrigger);
createButton("Set Physics Params",CMD_SEND_PHYSICS_SIMULATION_PARAMETERS,isTrigger);
createButton("Init Pose",CMD_INIT_POSE,isTrigger);
} else
{
/*
m_userCommandRequests.push_back(CMD_LOAD_URDF);
m_userCommandRequests.push_back(CMD_REQUEST_ACTUAL_STATE);
m_userCommandRequests.push_back(CMD_SEND_DESIRED_STATE);
m_userCommandRequests.push_back(CMD_REQUEST_ACTUAL_STATE);
//m_userCommandRequests.push_back(CMD_SET_JOINT_FEEDBACK);
m_userCommandRequests.push_back(CMD_CREATE_BOX_COLLISION_SHAPE);
//m_userCommandRequests.push_back(CMD_CREATE_RIGID_BODY);
m_userCommandRequests.push_back(CMD_STEP_FORWARD_SIMULATION);
m_userCommandRequests.push_back(CMD_REQUEST_ACTUAL_STATE);
m_userCommandRequests.push_back(CMD_SHUTDOWN);
*/
}
if (!m_physicsClient.connect())
{
b3Warning("Cannot eonnect to physics client");
}
}
bool RobotControlExample::wantsTermination()
{
return m_wantsShutdown;
}
void RobotControlExample::stepSimulation(float deltaTime)
{
m_physicsServer.processClientCommands();
if (m_physicsClient.isConnected())
{
SharedMemoryStatus status;
bool hasStatus = m_physicsClient.processServerStatus(status);
if ((m_option==ROBOT_PING_PONG_JOINT_FEEDBACK) && hasStatus && status.m_type == CMD_ACTUAL_STATE_UPDATE_COMPLETED)
{
//update sensor feedback: joint force/torque data and measured joint positions
for (int i=0;i<m_numMotors;i++)
{
int jointIndex = m_motorTargetState[i].m_jointIndex;
int positionIndex = m_motorTargetState[i].m_posIndex;
int velocityIndex = m_motorTargetState[i].m_uIndex;
m_motorTargetState[i].m_measuredJointPosition = status.m_sendActualStateArgs.m_actualStateQ[positionIndex];
m_motorTargetState[i].m_measuredJointVelocity = status.m_sendActualStateArgs.m_actualStateQdot[velocityIndex];
m_motorTargetState[i].m_measuredJointForce.setValue(status.m_sendActualStateArgs.m_jointReactionForces[6*jointIndex],
status.m_sendActualStateArgs.m_jointReactionForces[6*jointIndex+1],
status.m_sendActualStateArgs.m_jointReactionForces[6*jointIndex+2]);
m_motorTargetState[i].m_measuredJointTorque.setValue(status.m_sendActualStateArgs.m_jointReactionForces[6*jointIndex+3],
status.m_sendActualStateArgs.m_jointReactionForces[6*jointIndex+4],
status.m_sendActualStateArgs.m_jointReactionForces[6*jointIndex+5]);
if (m_motorTargetState[i].m_measuredJointPosition>0.1)
{
m_motorTargetState[i].m_velTarget = -1.5;
} else
{
m_motorTargetState[i].m_velTarget = 1.5;
}
b3Printf("Joint Force (Linear) [%s]=(%f,%f,%f)\n",m_motorTargetState[i].m_jointName.c_str(),m_motorTargetState[i].m_measuredJointForce.x(),m_motorTargetState[i].m_measuredJointForce.y(),m_motorTargetState[i].m_measuredJointForce.z());
b3Printf("Joint Torque (Angular) [%s]=(%f,%f,%f)\n",m_motorTargetState[i].m_jointName.c_str(),m_motorTargetState[i].m_measuredJointTorque.x(),m_motorTargetState[i].m_measuredJointTorque.y(),m_motorTargetState[i].m_measuredJointTorque.z());
}
}
if (hasStatus && status.m_type == CMD_URDF_LOADING_COMPLETED)
{
SharedMemoryCommand sensorCommand;
sensorCommand.m_type = CMD_CREATE_SENSOR;
sensorCommand.m_createSensorArguments.m_numJointSensorChanges = 0;
for (int jointIndex=0;jointIndex<m_physicsClient.getNumJoints();jointIndex++)
{
b3JointInfo info;
m_physicsClient.getJointInfo(jointIndex,info);
if (m_verboseOutput)
{
b3Printf("Joint %s at q-index %d and u-index %d\n",info.m_jointName,info.m_qIndex,info.m_uIndex);
}
if (info.m_flags & JOINT_HAS_MOTORIZED_POWER)
{
if (m_numMotors<MAX_NUM_MOTORS)
{
switch (m_option)
{
case ROBOT_VELOCITY_CONTROL:
{
char motorName[1024];
sprintf(motorName,"%s q'", info.m_jointName);
MyMotorInfo* motorInfo = &m_motorTargetState[m_numMotors];
motorInfo->m_jointName = info.m_jointName;
motorInfo->m_velTarget = 0.f;
motorInfo->m_posTarget = 0.f;
motorInfo->m_uIndex = info.m_uIndex;
SliderParams slider(motorName,&motorInfo->m_velTarget);
slider.m_minVal=-4;
slider.m_maxVal=4;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
m_numMotors++;
break;
}
case ROBOT_PD_CONTROL:
{
char motorName[1024];
MyMotorInfo* motorInfo = &m_motorTargetState[m_numMotors];
motorInfo->m_jointName = info.m_jointName;
motorInfo->m_velTarget = 0.f;
motorInfo->m_posTarget = 0.f;
motorInfo->m_uIndex = info.m_uIndex;
motorInfo->m_posIndex = info.m_qIndex;
motorInfo->m_kp = 1;
motorInfo->m_kd = 0;
{
sprintf(motorName,"%s kp", info.m_jointName);
SliderParams slider(motorName,&motorInfo->m_kp);
slider.m_minVal=0;
slider.m_maxVal=1;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
sprintf(motorName,"%s q", info.m_jointName);
SliderParams slider(motorName,&motorInfo->m_posTarget);
slider.m_minVal=-SIMD_PI;
slider.m_maxVal=SIMD_PI;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
sprintf(motorName,"%s kd", info.m_jointName);
SliderParams slider(motorName,&motorInfo->m_kd);
slider.m_minVal=0;
slider.m_maxVal=1;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
sprintf(motorName,"%s q'", info.m_jointName);
SliderParams slider(motorName,&motorInfo->m_velTarget);
slider.m_minVal=-10;
slider.m_maxVal=10;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
m_numMotors++;
break;
}
case ROBOT_PING_PONG_JOINT_FEEDBACK:
{
if (info.m_flags & JOINT_HAS_MOTORIZED_POWER)
{
if (m_numMotors<MAX_NUM_MOTORS)
{
MyMotorInfo* motorInfo = &m_motorTargetState[m_numMotors];
motorInfo->m_jointName = info.m_jointName;
motorInfo->m_velTarget = 0.f;
motorInfo->m_posTarget = 0.f;
motorInfo->m_uIndex = info.m_uIndex;
motorInfo->m_posIndex = info.m_qIndex;
motorInfo->m_jointIndex = jointIndex;
sensorCommand.m_createSensorArguments.m_sensorType[sensorCommand.m_createSensorArguments.m_numJointSensorChanges] = SENSOR_FORCE_TORQUE;
sensorCommand.m_createSensorArguments.m_jointIndex[sensorCommand.m_createSensorArguments.m_numJointSensorChanges] = jointIndex;
sensorCommand.m_createSensorArguments.m_enableJointForceSensor[sensorCommand.m_createSensorArguments.m_numJointSensorChanges] = true;
sensorCommand.m_createSensorArguments.m_numJointSensorChanges++;
m_numMotors++;
}
}
break;
}
default:
{
b3Warning("Unknown control mode in RobotControlExample::stepSimulation");
}
};
}
}
}
if (sensorCommand.m_createSensorArguments.m_numJointSensorChanges)
{
enqueueCommand(sensorCommand);
}
}
if (m_physicsClient.canSubmitCommand())
{
if (m_userCommandRequests.size())
{
if (m_verboseOutput)
{
b3Printf("Outstanding user command requests: %d\n", m_userCommandRequests.size());
}
SharedMemoryCommand cmd = m_userCommandRequests[0];
//a manual 'pop_front', we don't use 'remove' because it will re-order the commands
for (int i=1;i<m_userCommandRequests.size();i++)
{
m_userCommandRequests[i-1] = m_userCommandRequests[i];
}
m_userCommandRequests.pop_back();
if (cmd.m_type == CMD_CREATE_SENSOR)
{
b3Printf("CMD_CREATE_SENSOR!\n");
}
if (cmd.m_type == CMD_SEND_BULLET_DATA_STREAM)
{
char relativeFileName[1024];
bool fileFound = b3ResourcePath::findResourcePath(cmd.m_dataStreamArguments.m_bulletFileName,relativeFileName,1024);
if (fileFound)
{
FILE *fp = fopen(relativeFileName, "rb");
if (fp)
{
fseek(fp, 0L, SEEK_END);
int mFileLen = ftell(fp);
fseek(fp, 0L, SEEK_SET);
if (mFileLen<SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE)
{
char* data = (char*)malloc(mFileLen);
fread(data, mFileLen, 1, fp);
fclose(fp);
cmd.m_dataStreamArguments.m_streamChunkLength = mFileLen;
m_physicsClient.uploadBulletFileToSharedMemory(data,mFileLen);
if (m_verboseOutput)
{
b3Printf("Loaded bullet data chunks into shared memory\n");
}
free(data);
} else
{
b3Warning("Bullet file size (%d) exceeds of streaming memory chunk size (%d)\n", mFileLen,SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
}
} else
{
b3Warning("Cannot open file %s\n", relativeFileName);
}
} else
{
b3Warning("Cannot find file %s\n", cmd.m_dataStreamArguments.m_bulletFileName);
}
}
m_physicsClient.submitClientCommand(cmd);
} else
{
if (m_numMotors)
{
SharedMemoryCommand command;
command.m_type =CMD_SEND_DESIRED_STATE;
prepareControlCommand(command);
enqueueCommand(command);
command.m_type =CMD_STEP_FORWARD_SIMULATION;
enqueueCommand(command);
command.m_type = CMD_REQUEST_ACTUAL_STATE;
enqueueCommand(command);
}
}
}
}
}
extern int gSharedMemoryKey;
class CommonExampleInterface* RobotControlExampleCreateFunc(struct CommonExampleOptions& options)
{
RobotControlExample* example = new RobotControlExample(options.m_guiHelper, options.m_option);
if (gSharedMemoryKey>=0)
{
example->setSharedMemoryKey(gSharedMemoryKey);
}
return example;
}
#endif

View file

@ -0,0 +1,13 @@
#ifndef ROBOT_CONTROL_EXAMPLE_H
#define ROBOT_CONTROL_EXAMPLE_H
enum EnumRobotControls
{
ROBOT_VELOCITY_CONTROL = 0,
ROBOT_PD_CONTROL,
ROBOT_PING_PONG_JOINT_FEEDBACK,
};
class CommonExampleInterface* RobotControlExampleCreateFunc(struct CommonExampleOptions& options);
#endif //ROBOT_CONTROL_EXAMPLE_H

View file

@ -0,0 +1,44 @@
#ifndef SHARED_MEMORY_BLOCK_H
#define SHARED_MEMORY_BLOCK_H
#define SHARED_MEMORY_MAX_COMMANDS 1
#include "SharedMemoryCommands.h"
struct SharedMemoryBlock
{
int m_magicId;
struct SharedMemoryCommand m_clientCommands[SHARED_MEMORY_MAX_COMMANDS];
struct SharedMemoryStatus m_serverCommands[SHARED_MEMORY_MAX_COMMANDS];
int m_numClientCommands;
int m_numProcessedClientCommands;
int m_numServerCommands;
int m_numProcessedServerCommands;
//m_bulletStreamDataServerToClient is used to send (debug) data from server to client, for
//example to provide all details of a multibody including joint/link names, after loading a URDF file.
char m_bulletStreamDataServerToClientRefactor[SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE];
};
//http://stackoverflow.com/questions/24736304/unable-to-use-inline-in-declaration-get-error-c2054
#ifdef _WIN32
__inline
#else
inline
#endif
void
InitSharedMemoryBlock(struct SharedMemoryBlock* sharedMemoryBlock)
{
sharedMemoryBlock->m_numClientCommands = 0;
sharedMemoryBlock->m_numServerCommands = 0;
sharedMemoryBlock->m_numProcessedClientCommands = 0;
sharedMemoryBlock->m_numProcessedServerCommands = 0;
sharedMemoryBlock->m_magicId = SHARED_MEMORY_MAGIC_NUMBER;
}
#define SHARED_MEMORY_SIZE sizeof(SharedMemoryBlock)
#endif //SHARED_MEMORY_BLOCK_H

View file

@ -0,0 +1,231 @@
#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;
SendActualStateSharedMemoryStorage m_cachedState;
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)
{
if ((m_data->m_testBlock1->m_magicId < 211705023) &&
(m_data->m_testBlock1->m_magicId >= 201705023))
{
b3Error("Error: physics server version mismatch (expected %d got %d)\n", SHARED_MEMORY_MAGIC_NUMBER, m_data->m_testBlock1->m_magicId);
}
else
{
b3Error("Error connecting to shared memory: 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)
{
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];
if (serverCmd.m_type == CMD_ACTUAL_STATE_UPDATE_COMPLETED)
{
SendActualStateSharedMemoryStorage* serverState = (SendActualStateSharedMemoryStorage*)m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor;
m_data->m_cachedState = *serverState;
//ideally we provided a 'getCachedState' but that would require changing the API, so we store a pointer instead.
m_data->m_testBlock1->m_serverCommands[0].m_sendActualStateArgs.m_stateDetails = &m_data->m_cachedState;
}
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(int renderFlags)
{
}
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;
}
void SharedMemoryCommandProcessor::setTimeOut(double /*timeOutInSeconds*/)
{
}

View file

@ -0,0 +1,36 @@
#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(int renderFlags);
virtual void physicsDebugDraw(int debugDrawFlags);
virtual void setGuiHelper(struct GUIHelperInterface* guiHelper);
void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem);
void setSharedMemoryKey(int key);
virtual void setTimeOut(double timeOutInSeconds);
virtual void reportNotifications() {}
};
#endif //SHARED_MEMORY_COMMAND_PROCESSOR_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,21 @@
#ifndef SHARED_MEMORY_COMMON_H
#define SHARED_MEMORY_COMMON_H
#include "../CommonInterfaces/CommonMultiBodyBase.h"
class SharedMemoryCommon : public CommonExampleInterface
{
protected:
struct GUIHelperInterface* m_guiHelper;
public:
SharedMemoryCommon(GUIHelperInterface* helper)
: m_guiHelper(helper)
{
}
virtual void setSharedMemoryKey(int key) = 0;
virtual bool wantsTermination() = 0;
virtual bool isConnected() = 0;
};
#endif //

View file

@ -0,0 +1,571 @@
#include "SharedMemoryInProcessPhysicsC_API.h"
#include "../Utils/b3Clock.h"
#include "PhysicsClientSharedMemory.h"
#include "../ExampleBrowser/InProcessExampleBrowser.h"
#include <stdio.h>
#include <string.h>
#include "PhysicsServerExampleBullet2.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "InProcessMemory.h"
#include "RemoteGUIHelper.h"
#include "Bullet3Common/b3Logging.h"
class InProcessPhysicsClientSharedMemoryMainThread : public PhysicsClientSharedMemory
{
btInProcessExampleBrowserMainThreadInternalData* m_data;
b3Clock m_clock;
public:
InProcessPhysicsClientSharedMemoryMainThread(int argc, char* argv[], bool useInProcessMemory)
{
int newargc = argc + 3;
char** newargv = (char**)malloc(sizeof(void*) * newargc);
char* t0 = (char*)"--unused";
newargv[0] = t0;
for (int i = 0; i < argc; i++)
newargv[i + 1] = argv[i];
newargv[argc + 1] = (char*)"--logtostderr";
newargv[argc + 2] = (char*)"--start_demo_name=Physics Server";
m_data = btCreateInProcessExampleBrowserMainThread(newargc, newargv, useInProcessMemory);
SharedMemoryInterface* shMem = btGetSharedMemoryInterfaceMainThread(m_data);
setSharedMemoryInterface(shMem);
}
virtual ~InProcessPhysicsClientSharedMemoryMainThread()
{
setSharedMemoryInterface(0);
btShutDownExampleBrowserMainThread(m_data);
}
// return non-null if there is a status, nullptr otherwise
virtual const struct SharedMemoryStatus* processServerStatus()
{
{
if (btIsExampleBrowserMainThreadTerminated(m_data))
{
PhysicsClientSharedMemory::disconnectSharedMemory();
}
}
{
unsigned long int ms = m_clock.getTimeMilliseconds();
if (ms > 2)
{
B3_PROFILE("m_clock.reset()");
btUpdateInProcessExampleBrowserMainThread(m_data);
m_clock.reset();
}
}
{
b3Clock::usleep(0);
}
const SharedMemoryStatus* stat = 0;
{
stat = PhysicsClientSharedMemory::processServerStatus();
}
return stat;
}
virtual bool submitClientCommand(const struct SharedMemoryCommand& command)
{
// btUpdateInProcessExampleBrowserMainThread(m_data);
return PhysicsClientSharedMemory::submitClientCommand(command);
}
};
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerAndConnectMainThread(int argc, char* argv[])
{
InProcessPhysicsClientSharedMemoryMainThread* cl = new InProcessPhysicsClientSharedMemoryMainThread(argc, argv, 1);
cl->setSharedMemoryKey(SHARED_MEMORY_KEY + 1);
cl->connect();
return (b3PhysicsClientHandle)cl;
}
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerAndConnectMainThreadSharedMemory(int argc, char* argv[])
{
InProcessPhysicsClientSharedMemoryMainThread* cl = new InProcessPhysicsClientSharedMemoryMainThread(argc, argv, 0);
cl->setSharedMemoryKey(SHARED_MEMORY_KEY + 1);
cl->connect();
return (b3PhysicsClientHandle)cl;
}
class InProcessPhysicsClientSharedMemory : public PhysicsClientSharedMemory
{
btInProcessExampleBrowserInternalData* m_data;
char** m_newargv;
public:
InProcessPhysicsClientSharedMemory(int argc, char* argv[], bool useInProcessMemory)
{
int newargc = argc + 2;
m_newargv = (char**)malloc(sizeof(void*) * newargc);
char* t0 = (char*)"--unused";
m_newargv[0] = t0;
for (int i = 0; i < argc; i++)
m_newargv[i + 1] = argv[i];
char* t1 = (char*)"--start_demo_name=Physics Server";
m_newargv[argc + 1] = t1;
m_data = btCreateInProcessExampleBrowser(newargc, m_newargv, useInProcessMemory);
SharedMemoryInterface* shMem = btGetSharedMemoryInterface(m_data);
setSharedMemoryInterface(shMem);
}
virtual ~InProcessPhysicsClientSharedMemory()
{
setSharedMemoryInterface(0);
btShutDownExampleBrowser(m_data);
free(m_newargv);
}
};
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerAndConnect(int argc, char* argv[])
{
InProcessPhysicsClientSharedMemory* cl = new InProcessPhysicsClientSharedMemory(argc, argv, 1);
cl->setSharedMemoryKey(SHARED_MEMORY_KEY + 1);
cl->connect();
return (b3PhysicsClientHandle)cl;
}
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerAndConnectSharedMemory(int argc, char* argv[])
{
InProcessPhysicsClientSharedMemory* cl = new InProcessPhysicsClientSharedMemory(argc, argv, 0);
cl->setSharedMemoryKey(SHARED_MEMORY_KEY + 1);
cl->connect();
return (b3PhysicsClientHandle)cl;
}
class InProcessPhysicsClientExistingExampleBrowser : public PhysicsClientSharedMemory
{
CommonExampleInterface* m_physicsServerExample;
SharedMemoryInterface* m_sharedMem;
b3Clock m_clock;
unsigned long long int m_prevTime;
struct GUIHelperInterface* m_guiHelper;
public:
InProcessPhysicsClientExistingExampleBrowser(struct GUIHelperInterface* guiHelper, bool useInProcessMemory, bool skipGraphicsUpdate, bool ownsGuiHelper)
{
m_guiHelper = 0;
if (ownsGuiHelper)
{
m_guiHelper = guiHelper;
}
m_sharedMem = 0;
CommonExampleOptions options(guiHelper);
if (useInProcessMemory)
{
m_sharedMem = new InProcessMemory;
options.m_sharedMem = m_sharedMem;
}
options.m_skipGraphicsUpdate = skipGraphicsUpdate;
m_physicsServerExample = PhysicsServerCreateFuncBullet2(options);
m_physicsServerExample->initPhysics();
//m_physicsServerExample->resetCamera();
setSharedMemoryInterface(m_sharedMem);
m_clock.reset();
m_prevTime = m_clock.getTimeMicroseconds();
}
virtual ~InProcessPhysicsClientExistingExampleBrowser()
{
m_physicsServerExample->exitPhysics();
//s_instancingRenderer->removeAllInstances();
delete m_physicsServerExample;
delete m_sharedMem;
delete m_guiHelper;
}
// return non-null if there is a status, nullptr otherwise
virtual const struct SharedMemoryStatus* processServerStatus()
{
m_physicsServerExample->updateGraphics();
unsigned long long int curTime = m_clock.getTimeMicroseconds();
unsigned long long int dtMicro = curTime - m_prevTime;
m_prevTime = curTime;
double dt = double(dtMicro) / 1000000.;
m_physicsServerExample->stepSimulation(dt);
{
b3Clock::usleep(0);
}
const SharedMemoryStatus* stat = 0;
{
stat = PhysicsClientSharedMemory::processServerStatus();
}
return stat;
}
virtual void renderScene()
{
m_physicsServerExample->renderScene();
}
virtual void debugDraw(int debugDrawMode)
{
m_physicsServerExample->physicsDebugDraw(debugDrawMode);
}
virtual bool mouseMoveCallback(float x, float y)
{
return m_physicsServerExample->mouseMoveCallback(x, y);
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
return m_physicsServerExample->mouseButtonCallback(button, state, x, y);
}
};
void b3InProcessDebugDrawInternal(b3PhysicsClientHandle clientHandle, int debugDrawMode)
{
InProcessPhysicsClientExistingExampleBrowser* cl = (InProcessPhysicsClientExistingExampleBrowser*)clientHandle;
cl->debugDraw(debugDrawMode);
}
void b3InProcessRenderSceneInternal(b3PhysicsClientHandle clientHandle)
{
InProcessPhysicsClientExistingExampleBrowser* cl = (InProcessPhysicsClientExistingExampleBrowser*)clientHandle;
cl->renderScene();
}
int b3InProcessMouseMoveCallback(b3PhysicsClientHandle clientHandle, float x, float y)
{
InProcessPhysicsClientExistingExampleBrowser* cl = (InProcessPhysicsClientExistingExampleBrowser*)clientHandle;
return cl->mouseMoveCallback(x, y);
}
int b3InProcessMouseButtonCallback(b3PhysicsClientHandle clientHandle, int button, int state, float x, float y)
{
InProcessPhysicsClientExistingExampleBrowser* cl = (InProcessPhysicsClientExistingExampleBrowser*)clientHandle;
return cl->mouseButtonCallback(button, state, x, y);
}
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect(void* guiHelperPtr)
{
static DummyGUIHelper noGfx;
GUIHelperInterface* guiHelper = (GUIHelperInterface*)guiHelperPtr;
if (!guiHelper)
{
guiHelper = &noGfx;
}
bool useInprocessMemory = true;
bool skipGraphicsUpdate = false;
InProcessPhysicsClientExistingExampleBrowser* cl = new InProcessPhysicsClientExistingExampleBrowser(guiHelper, useInprocessMemory, skipGraphicsUpdate, false);
cl->connect();
return (b3PhysicsClientHandle)cl;
}
extern int gSharedMemoryKey;
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect3(void* guiHelperPtr, int sharedMemoryKey)
{
static DummyGUIHelper noGfx;
gSharedMemoryKey = sharedMemoryKey;
GUIHelperInterface* guiHelper = (GUIHelperInterface*)guiHelperPtr;
if (!guiHelper)
{
guiHelper = &noGfx;
}
bool useInprocessMemory = false;
bool skipGraphicsUpdate = true;
InProcessPhysicsClientExistingExampleBrowser* cl = new InProcessPhysicsClientExistingExampleBrowser(guiHelper, useInprocessMemory, skipGraphicsUpdate, false);
cl->setSharedMemoryKey(sharedMemoryKey + 1);
cl->connect();
//backward compatiblity
gSharedMemoryKey = SHARED_MEMORY_KEY;
return (b3PhysicsClientHandle)cl;
}
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect4(void* guiHelperPtr, int sharedMemoryKey)
{
gSharedMemoryKey = sharedMemoryKey;
GUIHelperInterface* guiHelper = (GUIHelperInterface*)guiHelperPtr;
bool ownsGuiHelper = false;
if (!guiHelper)
{
guiHelper = new RemoteGUIHelper();
ownsGuiHelper = true;
}
bool useInprocessMemory = false;
bool skipGraphicsUpdate = false;
InProcessPhysicsClientExistingExampleBrowser* cl = new InProcessPhysicsClientExistingExampleBrowser(guiHelper, useInprocessMemory, skipGraphicsUpdate, ownsGuiHelper);
cl->setSharedMemoryKey(sharedMemoryKey + 1);
cl->connect();
//backward compatiblity
gSharedMemoryKey = SHARED_MEMORY_KEY;
return (b3PhysicsClientHandle)cl;
}
#ifdef BT_ENABLE_CLSOCKET
#include "RemoteGUIHelperTCP.h"
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnectTCP(const char* hostName, int port)
{
bool ownsGuiHelper = true;
GUIHelperInterface* guiHelper = new RemoteGUIHelperTCP(hostName, port);
bool useInprocessMemory = true;
bool skipGraphicsUpdate = false;
InProcessPhysicsClientExistingExampleBrowser* cl = new InProcessPhysicsClientExistingExampleBrowser(guiHelper, useInprocessMemory, skipGraphicsUpdate, ownsGuiHelper);
//cl->setSharedMemoryKey(sharedMemoryKey + 1);
cl->connect();
//backward compatiblity
gSharedMemoryKey = SHARED_MEMORY_KEY;
return (b3PhysicsClientHandle)cl;
}
//backward compatiblity
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect2(void* guiHelperPtr)
{
return b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect3(guiHelperPtr, SHARED_MEMORY_KEY);
}
#include "SharedMemoryCommands.h"
#include "PhysicsClientSharedMemory.h"
#include "GraphicsSharedMemoryBlock.h"
#include "PosixSharedMemory.h"
#include "Win32SharedMemory.h"
class InProcessGraphicsServerSharedMemory : public PhysicsClientSharedMemory
{
btInProcessExampleBrowserInternalData* m_data2;
char** m_newargv;
SharedMemoryCommand m_command;
GraphicsSharedMemoryBlock* m_testBlock1;
SharedMemoryInterface* m_sharedMemory;
public:
InProcessGraphicsServerSharedMemory(int port)
{
int newargc = 3;
m_newargv = (char**)malloc(sizeof(void*) * newargc);
char* t0 = (char*)"--unused";
m_newargv[0] = t0;
char* t1 = (char*)"--start_demo_name=Graphics Server";
char portArg[1024];
sprintf(portArg, "--port=%d", port);
m_newargv[1] = t1;
m_newargv[2] = portArg;
bool useInProcessMemory = false;
m_data2 = btCreateInProcessExampleBrowser(newargc, m_newargv, useInProcessMemory);
SharedMemoryInterface* shMem = btGetSharedMemoryInterface(m_data2);
setSharedMemoryInterface(shMem);
///////////////////
#ifdef _WIN32
m_sharedMemory = new Win32SharedMemoryServer();
#else
m_sharedMemory = new PosixSharedMemory();
#endif
/// server always has to create and initialize shared memory
bool allowCreation = false;
m_testBlock1 = (GraphicsSharedMemoryBlock*)m_sharedMemory->allocateSharedMemory(
GRAPHICS_SHARED_MEMORY_KEY, GRAPHICS_SHARED_MEMORY_SIZE, allowCreation);
}
virtual ~InProcessGraphicsServerSharedMemory()
{
m_sharedMemory->releaseSharedMemory(GRAPHICS_SHARED_MEMORY_KEY, GRAPHICS_SHARED_MEMORY_SIZE);
delete m_sharedMemory;
setSharedMemoryInterface(0);
btShutDownExampleBrowser(m_data2);
free(m_newargv);
}
virtual bool canSubmitCommand() const
{
if (m_testBlock1)
{
if (m_testBlock1->m_magicId != GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER)
{
return false;
}
}
return true;
}
virtual struct SharedMemoryCommand* getAvailableSharedMemoryCommand()
{
return &m_command;
}
virtual bool submitClientCommand(const struct SharedMemoryCommand& command)
{
switch (command.m_type)
{
default:
{
}
}
return true;
}
};
class InProcessGraphicsServerSharedMemoryMainThread : public PhysicsClientSharedMemory
{
btInProcessExampleBrowserMainThreadInternalData* m_data2;
char** m_newargv;
SharedMemoryCommand m_command;
GraphicsSharedMemoryBlock* m_testBlock1;
SharedMemoryInterface* m_sharedMemory;
b3Clock m_clock;
public:
InProcessGraphicsServerSharedMemoryMainThread(int port)
{
int newargc = 3;
m_newargv = (char**)malloc(sizeof(void*) * newargc);
char* t0 = (char*)"--unused";
m_newargv[0] = t0;
char* t1 = (char*)"--start_demo_name=Graphics Server";
m_newargv[1] = t1;
char portArg[1024];
sprintf(portArg, "--port=%d", port);
m_newargv[2] = portArg;
bool useInProcessMemory = false;
m_data2 = btCreateInProcessExampleBrowserMainThread(newargc, m_newargv, useInProcessMemory);
SharedMemoryInterface* shMem = btGetSharedMemoryInterfaceMainThread(m_data2);
setSharedMemoryInterface(shMem);
///////////////////
#ifdef _WIN32
m_sharedMemory = new Win32SharedMemoryServer();
#else
m_sharedMemory = new PosixSharedMemory();
#endif
/// server always has to create and initialize shared memory
bool allowCreation = false;
m_testBlock1 = (GraphicsSharedMemoryBlock*)m_sharedMemory->allocateSharedMemory(
GRAPHICS_SHARED_MEMORY_KEY, GRAPHICS_SHARED_MEMORY_SIZE, allowCreation);
m_clock.reset();
}
virtual ~InProcessGraphicsServerSharedMemoryMainThread()
{
m_sharedMemory->releaseSharedMemory(GRAPHICS_SHARED_MEMORY_KEY, GRAPHICS_SHARED_MEMORY_SIZE);
delete m_sharedMemory;
setSharedMemoryInterface(0);
btShutDownExampleBrowserMainThread(m_data2);
free(m_newargv);
}
virtual bool canSubmitCommand() const
{
btUpdateInProcessExampleBrowserMainThread(m_data2);
if (m_testBlock1)
{
if (m_testBlock1->m_magicId != GRAPHICS_SHARED_MEMORY_MAGIC_NUMBER)
{
return false;
}
}
return true;
}
virtual struct SharedMemoryCommand* getAvailableSharedMemoryCommand()
{
return &m_command;
}
virtual bool submitClientCommand(const struct SharedMemoryCommand& command)
{
switch (command.m_type)
{
default:
{
}
}
return true;
}
// return non-null if there is a status, nullptr otherwise
virtual const struct SharedMemoryStatus* processServerStatus()
{
{
if (btIsExampleBrowserMainThreadTerminated(m_data2))
{
PhysicsClientSharedMemory::disconnectSharedMemory();
}
}
{
unsigned long int ms = m_clock.getTimeMilliseconds();
if (ms > 2)
{
B3_PROFILE("m_clock.reset()");
btUpdateInProcessExampleBrowserMainThread(m_data2);
m_clock.reset();
}
}
{
b3Clock::usleep(0);
}
const SharedMemoryStatus* stat = 0;
{
stat = PhysicsClientSharedMemory::processServerStatus();
}
return stat;
}
};
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessGraphicsServerAndConnectSharedMemory(int port)
{
InProcessGraphicsServerSharedMemory* cl = new InProcessGraphicsServerSharedMemory(port);
cl->setSharedMemoryKey(SHARED_MEMORY_KEY + 1);
cl->connect();
return (b3PhysicsClientHandle)cl;
}
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessGraphicsServerAndConnectMainThreadSharedMemory(int port)
{
InProcessGraphicsServerSharedMemoryMainThread* cl = new InProcessGraphicsServerSharedMemoryMainThread(port);
cl->setSharedMemoryKey(SHARED_MEMORY_KEY + 1);
cl->connect();
return (b3PhysicsClientHandle)cl;
}
#endif

View file

@ -0,0 +1,43 @@
#ifndef IN_PROCESS_PHYSICS_C_API_H
#define IN_PROCESS_PHYSICS_C_API_H
#include "PhysicsClientC_API.h"
#ifdef __cplusplus
extern "C"
{
#endif
///think more about naming. The b3ConnectPhysicsLoopback
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerAndConnect(int argc, char* argv[]);
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerAndConnectMainThread(int argc, char* argv[]);
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerAndConnectSharedMemory(int argc, char* argv[]);
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerAndConnectMainThreadSharedMemory(int argc, char* argv[]);
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessGraphicsServerAndConnectSharedMemory(int port);
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessGraphicsServerAndConnectMainThreadSharedMemory(int port);
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect(void* guiHelperPtr);
//create a shared memory physics server, with a DummyGUIHelper (no graphics)
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect2(void* guiHelperPtr);
//create a shared memory physics server, with a DummyGUIHelper (no graphics) and allow to set shared memory key
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect3(void* guiHelperPtr, int sharedMemoryKey);
//create a shared memory physics server, with a RemoteGUIHelper (connect to remote graphics server) and allow to set shared memory key
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect4(void* guiHelperPtr, int sharedMemoryKey);
#ifdef BT_ENABLE_CLSOCKET
B3_SHARED_API b3PhysicsClientHandle b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnectTCP(const char* hostName, int port);
#endif
///ignore the following APIs, they are for internal use for example browser
void b3InProcessRenderSceneInternal(b3PhysicsClientHandle clientHandle);
void b3InProcessDebugDrawInternal(b3PhysicsClientHandle clientHandle, int debugDrawMode);
int b3InProcessMouseMoveCallback(b3PhysicsClientHandle clientHandle, float x, float y);
int b3InProcessMouseButtonCallback(b3PhysicsClientHandle clientHandle, int button, int state, float x, float y);
#ifdef __cplusplus
}
#endif
#endif //IN_PROCESS_PHYSICS_C_API_H

View file

@ -0,0 +1,15 @@
#ifndef SHARED_MEMORY_INTERFACE_H
#define SHARED_MEMORY_INTERFACE_H
class SharedMemoryInterface
{
public:
virtual ~SharedMemoryInterface()
{
}
virtual void* allocateSharedMemory(int key, int size, bool allowCreation) = 0;
virtual void releaseSharedMemory(int key, int size) = 0;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,96 @@
#ifndef SHARED_MEMORY_USER_DATA_H
#define SHARED_MEMORY_USER_DATA_H
#include <string>
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btHashMap.h"
#include "SharedMemoryPublic.h"
struct SharedMemoryUserData
{
std::string m_key;
int m_type;
int m_bodyUniqueId;
int m_linkIndex;
int m_visualShapeIndex;
btAlignedObjectArray<char> m_bytes;
SharedMemoryUserData()
: m_type(-1), m_bodyUniqueId(-1), m_linkIndex(-1), m_visualShapeIndex(-1)
{
}
SharedMemoryUserData(const char* key, int bodyUniqueId, int linkIndex, int visualShapeIndex)
: m_key(key), m_type(-1), m_bodyUniqueId(bodyUniqueId), m_linkIndex(linkIndex), m_visualShapeIndex(visualShapeIndex)
{
}
void replaceValue(const char* bytes, int len, int type)
{
m_type = type;
m_bytes.resize(len);
for (int i = 0; i < len; i++)
{
m_bytes[i] = bytes[i];
}
}
virtual ~SharedMemoryUserData()
{
}
void clear()
{
m_bytes.clear();
m_type = -1;
}
};
struct SharedMemoryUserDataHashKey
{
unsigned int m_hash;
btHashString m_key;
btHashInt m_bodyUniqueId;
btHashInt m_linkIndex;
btHashInt m_visualShapeIndex;
SIMD_FORCE_INLINE unsigned int getHash() const
{
return m_hash;
}
SharedMemoryUserDataHashKey() : m_hash(0) {}
SharedMemoryUserDataHashKey(const struct SharedMemoryUserData* userData)
: m_key(userData->m_key.c_str()),
m_bodyUniqueId(userData->m_bodyUniqueId),
m_linkIndex(userData->m_linkIndex),
m_visualShapeIndex(userData->m_visualShapeIndex)
{
calculateHash();
}
SharedMemoryUserDataHashKey(const char* key, int bodyUniqueId, int linkIndex, int visualShapeIndex)
: m_key(key), m_bodyUniqueId(bodyUniqueId), m_linkIndex(linkIndex), m_visualShapeIndex(visualShapeIndex)
{
calculateHash();
}
void calculateHash()
{
m_hash = m_key.getHash() ^ m_bodyUniqueId.getHash() ^ m_linkIndex.getHash() ^ m_visualShapeIndex.getHash();
}
bool equals(const SharedMemoryUserDataHashKey& other) const
{
return m_bodyUniqueId.equals(other.m_bodyUniqueId) &&
m_linkIndex.equals(other.m_linkIndex) &&
m_visualShapeIndex.equals(other.m_visualShapeIndex) &&
m_key.equals(other.m_key);
}
};
#endif //SHARED_MEMORY_USER_DATA_H

View file

@ -0,0 +1,164 @@
#ifdef _WIN32
#include "Win32SharedMemory.h"
#include "Bullet3Common/b3Logging.h"
#include "Bullet3Common/b3Scalar.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include <windows.h>
#include <stdio.h>
//see also https://msdn.microsoft.com/en-us/library/windows/desktop/aa366551%28v=vs.85%29.aspx
struct Win32SharedMemorySegment
{
int m_key;
HANDLE m_hMapFile;
void* m_buf;
TCHAR m_szName[1024];
Win32SharedMemorySegment()
: m_hMapFile(0),
m_buf(0),
m_key(-1)
{
m_szName[0] = 0;
}
};
struct Win32SharedMemoryInteralData
{
b3AlignedObjectArray<Win32SharedMemorySegment> m_segments;
Win32SharedMemoryInteralData()
{
}
};
Win32SharedMemory::Win32SharedMemory()
{
m_internalData = new Win32SharedMemoryInteralData;
}
Win32SharedMemory::~Win32SharedMemory()
{
delete m_internalData;
}
void* Win32SharedMemory::allocateSharedMemory(int key, int size, bool allowCreation)
{
{
Win32SharedMemorySegment* seg = 0;
int i = 0;
for (i = 0; i < m_internalData->m_segments.size(); i++)
{
if (m_internalData->m_segments[i].m_key == key)
{
seg = &m_internalData->m_segments[i];
break;
}
}
if (seg)
{
b3Error("already created shared memory segment using same key");
return seg->m_buf;
}
}
Win32SharedMemorySegment seg;
seg.m_key = key;
#ifdef UNICODE
swprintf_s(seg.m_szName, TEXT("MyFileMappingObject%d"), key);
#else
sprintf(seg.m_szName, "MyFileMappingObject%d", key);
#endif
seg.m_hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
seg.m_szName); // name of mapping object
if (seg.m_hMapFile == NULL)
{
if (allowCreation)
{
seg.m_hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
size, // maximum object size (low-order DWORD)
seg.m_szName); // name of mapping object
}
else
{
//b3Warning("Could not create file mapping object (%d).\n", GetLastError());
return 0;
}
}
seg.m_buf = MapViewOfFile(seg.m_hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
size);
if (seg.m_buf == NULL)
{
b3Warning("Could not map view of file (%d).\n", GetLastError());
CloseHandle(seg.m_hMapFile);
return 0;
}
m_internalData->m_segments.push_back(seg);
return seg.m_buf;
}
void Win32SharedMemory::releaseSharedMemory(int key, int size)
{
Win32SharedMemorySegment* seg = 0;
int i = 0;
for (i = 0; i < m_internalData->m_segments.size(); i++)
{
if (m_internalData->m_segments[i].m_key == key)
{
seg = &m_internalData->m_segments[i];
break;
}
}
if (seg == 0)
{
b3Error("Couldn't find shared memory segment");
return;
}
if (seg->m_buf)
{
UnmapViewOfFile(seg->m_buf);
seg->m_buf = 0;
}
if (seg->m_hMapFile)
{
CloseHandle(seg->m_hMapFile);
seg->m_hMapFile = 0;
}
m_internalData->m_segments.removeAtIndex(i);
}
Win32SharedMemoryServer::Win32SharedMemoryServer()
{
}
Win32SharedMemoryServer::~Win32SharedMemoryServer()
{
}
Win32SharedMemoryClient::Win32SharedMemoryClient()
{
}
Win32SharedMemoryClient::~Win32SharedMemoryClient()
{
}
#endif //_WIN32

View file

@ -0,0 +1,32 @@
#ifndef WIN32_SHARED_MEMORY_H
#define WIN32_SHARED_MEMORY_H
#include "SharedMemoryInterface.h"
class Win32SharedMemory : public SharedMemoryInterface
{
struct Win32SharedMemoryInteralData* m_internalData;
public:
Win32SharedMemory();
virtual ~Win32SharedMemory();
virtual void* allocateSharedMemory(int key, int size, bool allowCreation);
virtual void releaseSharedMemory(int key, int size);
};
class Win32SharedMemoryServer : public Win32SharedMemory
{
public:
Win32SharedMemoryServer();
virtual ~Win32SharedMemoryServer();
};
class Win32SharedMemoryClient : public Win32SharedMemory
{
public:
Win32SharedMemoryClient();
virtual ~Win32SharedMemoryClient();
};
#endif //WIN32_SHARED_MEMORY_H

View file

@ -0,0 +1,611 @@
#include "b3PluginManager.h"
#include "Bullet3Common/b3HashMap.h"
#include "Bullet3Common/b3ResizablePool.h"
#include "PhysicsClientC_API.h"
#include "PhysicsDirect.h"
#include "plugins/b3PluginContext.h"
#include "../Utils/b3BulletDefaultFileIO.h"
#include <string.h>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
#include <windows.h>
typedef HMODULE B3_DYNLIB_HANDLE;
#define B3_DYNLIB_OPEN LoadLibraryA
#define B3_DYNLIB_CLOSE FreeLibrary
#define B3_DYNLIB_IMPORT GetProcAddress
#else
#include <dlfcn.h>
typedef void* B3_DYNLIB_HANDLE;
#ifdef B3_USE_DLMOPEN
#define B3_DYNLIB_OPEN(path) dlmopen(LM_ID_NEWLM, path, RTLD_LAZY)
#else
#define B3_DYNLIB_OPEN(path) dlopen(path, RTLD_NOW | RTLD_GLOBAL)
#endif
#define B3_DYNLIB_CLOSE dlclose
#define B3_DYNLIB_IMPORT dlsym
#endif
struct b3Plugin
{
B3_DYNLIB_HANDLE m_pluginHandle;
bool m_ownsPluginHandle;
bool m_isInitialized;
std::string m_pluginPath;
std::string m_pluginPostFix;
int m_pluginUniqueId;
PFN_INIT m_initFunc;
PFN_EXIT m_exitFunc;
PFN_EXECUTE m_executeCommandFunc;
PFN_TICK m_preTickFunc;
PFN_TICK m_postTickFunc;
PFN_TICK m_processNotificationsFunc;
PFN_TICK m_processClientCommandsFunc;
PFN_GET_RENDER_INTERFACE m_getRendererFunc;
PFN_GET_COLLISION_INTERFACE m_getCollisionFunc;
PFN_GET_FILEIO_INTERFACE m_getFileIOFunc;
void* m_userPointer;
b3UserDataValue* m_returnData;
b3Plugin()
: m_pluginHandle(0),
m_ownsPluginHandle(false),
m_isInitialized(false),
m_pluginUniqueId(-1),
m_initFunc(0),
m_exitFunc(0),
m_executeCommandFunc(0),
m_preTickFunc(0),
m_postTickFunc(0),
m_processNotificationsFunc(0),
m_processClientCommandsFunc(0),
m_getRendererFunc(0),
m_getCollisionFunc(0),
m_getFileIOFunc(0),
m_userPointer(0),
m_returnData(0)
{
}
void clear()
{
if (m_ownsPluginHandle)
{
B3_DYNLIB_CLOSE(m_pluginHandle);
}
m_pluginHandle = 0;
m_initFunc = 0;
m_exitFunc = 0;
m_executeCommandFunc = 0;
m_preTickFunc = 0;
m_postTickFunc = 0;
m_processNotificationsFunc = 0;
m_processClientCommandsFunc = 0;
m_getRendererFunc = 0;
m_getCollisionFunc = 0;
m_getFileIOFunc = 0;
m_userPointer = 0;
m_returnData = 0;
m_isInitialized = false;
}
const char* GetMapKey() const
{
return GetMapKey(m_pluginPath.c_str(), m_pluginPostFix.c_str());
}
static const char* GetMapKey(const char* path, const char* postFix)
{
if (path != 0 && strlen(path) > 0)
{
return path;
}
else if (postFix != 0 && strlen(postFix) > 0)
{
return postFix;
}
return "";
}
};
typedef b3PoolBodyHandle<b3Plugin> b3PluginHandle;
struct b3PluginManagerInternalData
{
b3ResizablePool<b3PluginHandle> m_plugins;
b3HashMap<b3HashString, int> m_pluginMap;
PhysicsDirect* m_physicsDirect;
PhysicsCommandProcessorInterface* m_rpcCommandProcessorInterface;
b3AlignedObjectArray<b3KeyboardEvent> m_keyEvents;
b3AlignedObjectArray<b3VRControllerEvent> m_vrEvents;
b3AlignedObjectArray<b3MouseEvent> m_mouseEvents;
b3AlignedObjectArray<b3Notification> m_notifications[2];
int m_activeNotificationsBufferIndex;
int m_activeRendererPluginUid;
int m_activeCollisionPluginUid;
int m_numNotificationPlugins;
int m_activeFileIOPluginUid;
b3BulletDefaultFileIO m_defaultFileIO;
b3PluginManagerInternalData()
: m_physicsDirect(0), m_rpcCommandProcessorInterface(0), m_activeNotificationsBufferIndex(0), m_activeRendererPluginUid(-1), m_activeCollisionPluginUid(-1), m_numNotificationPlugins(0), m_activeFileIOPluginUid(-1)
{
}
};
b3PluginManager::b3PluginManager(class PhysicsCommandProcessorInterface* physSdk)
{
m_data = new b3PluginManagerInternalData;
m_data->m_rpcCommandProcessorInterface = physSdk;
m_data->m_physicsDirect = new PhysicsDirect(physSdk, false);
}
b3PluginManager::~b3PluginManager()
{
while (m_data->m_pluginMap.size())
{
int* pluginUidPtr = m_data->m_pluginMap.getAtIndex(0);
if (pluginUidPtr)
{
int pluginUid = *pluginUidPtr;
unloadPlugin(*pluginUidPtr);
}
}
delete m_data->m_physicsDirect;
m_data->m_pluginMap.clear();
m_data->m_plugins.exitHandles();
delete m_data;
}
void b3PluginManager::addEvents(const struct b3VRControllerEvent* vrControllerEvents, int numVRControllerEvents, const struct b3KeyboardEvent* keyEvents, int numKeyEvents, const struct b3MouseEvent* mouseEvents, int numMouseEvents)
{
for (int i = 0; i < numKeyEvents; i++)
{
m_data->m_keyEvents.push_back(keyEvents[i]);
}
for (int i = 0; i < numVRControllerEvents; i++)
{
m_data->m_vrEvents.push_back(vrControllerEvents[i]);
}
for (int i = 0; i < numMouseEvents; i++)
{
m_data->m_mouseEvents.push_back(mouseEvents[i]);
}
}
void b3PluginManager::clearEvents()
{
m_data->m_keyEvents.resize(0);
m_data->m_vrEvents.resize(0);
m_data->m_mouseEvents.resize(0);
}
void b3PluginManager::addNotification(const struct b3Notification& notification)
{
if (m_data->m_numNotificationPlugins > 0)
{
m_data->m_notifications[m_data->m_activeNotificationsBufferIndex].push_back(notification);
}
}
int b3PluginManager::loadPlugin(const char* pluginPath, const char* postFixStr)
{
int pluginUniqueId = -1;
int* pluginUidPtr = m_data->m_pluginMap.find(b3Plugin::GetMapKey(pluginPath, postFixStr));
if (pluginUidPtr)
{
//already loaded
pluginUniqueId = *pluginUidPtr;
b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
if (!plugin->m_isInitialized)
{
b3PluginContext context = {0};
context.m_userPointer = 0;
context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
context.m_rpcCommandProcessorInterface = m_data->m_rpcCommandProcessorInterface;
int result = plugin->m_initFunc(&context);
plugin->m_isInitialized = true;
plugin->m_userPointer = context.m_userPointer;
}
}
else
{
pluginUniqueId = m_data->m_plugins.allocHandle();
b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
plugin->m_pluginUniqueId = pluginUniqueId;
B3_DYNLIB_HANDLE pluginHandle = B3_DYNLIB_OPEN(pluginPath);
bool ok = false;
if (pluginHandle)
{
std::string postFix = postFixStr;
std::string initStr = std::string("initPlugin") + postFix;
std::string exitStr = std::string("exitPlugin") + postFix;
std::string executePluginCommandStr = std::string("executePluginCommand") + postFix;
std::string preTickPluginCallbackStr = std::string("preTickPluginCallback") + postFix;
std::string postTickPluginCallback = std::string("postTickPluginCallback") + postFix;
std::string processNotificationsStr = std::string("processNotifications") + postFix;
std::string processClientCommandsStr = std::string("processClientCommands") + postFix;
std::string getRendererStr = std::string("getRenderInterface") + postFix;
std::string getCollisionStr = std::string("getCollisionInterface") + postFix;
std::string getFileIOStr = std::string("getFileIOInterface") + postFix;
plugin->m_initFunc = (PFN_INIT)B3_DYNLIB_IMPORT(pluginHandle, initStr.c_str());
plugin->m_exitFunc = (PFN_EXIT)B3_DYNLIB_IMPORT(pluginHandle, exitStr.c_str());
plugin->m_executeCommandFunc = (PFN_EXECUTE)B3_DYNLIB_IMPORT(pluginHandle, executePluginCommandStr.c_str());
plugin->m_preTickFunc = (PFN_TICK)B3_DYNLIB_IMPORT(pluginHandle, preTickPluginCallbackStr.c_str());
plugin->m_postTickFunc = (PFN_TICK)B3_DYNLIB_IMPORT(pluginHandle, postTickPluginCallback.c_str());
plugin->m_processNotificationsFunc = (PFN_TICK)B3_DYNLIB_IMPORT(pluginHandle, processNotificationsStr.c_str());
if (plugin->m_processNotificationsFunc)
{
m_data->m_numNotificationPlugins++;
}
plugin->m_processClientCommandsFunc = (PFN_TICK)B3_DYNLIB_IMPORT(pluginHandle, processClientCommandsStr.c_str());
plugin->m_getRendererFunc = (PFN_GET_RENDER_INTERFACE)B3_DYNLIB_IMPORT(pluginHandle, getRendererStr.c_str());
plugin->m_getCollisionFunc = (PFN_GET_COLLISION_INTERFACE)B3_DYNLIB_IMPORT(pluginHandle, getCollisionStr.c_str());
plugin->m_getFileIOFunc = (PFN_GET_FILEIO_INTERFACE)B3_DYNLIB_IMPORT(pluginHandle, getFileIOStr.c_str());
if (plugin->m_initFunc && plugin->m_exitFunc && plugin->m_executeCommandFunc)
{
b3PluginContext context;
context.m_userPointer = plugin->m_userPointer;
context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
context.m_rpcCommandProcessorInterface = m_data->m_rpcCommandProcessorInterface;
int version = plugin->m_initFunc(&context);
plugin->m_isInitialized = true;
//keep the user pointer persistent
plugin->m_userPointer = context.m_userPointer;
if (version == SHARED_MEMORY_MAGIC_NUMBER)
{
ok = true;
plugin->m_ownsPluginHandle = true;
plugin->m_pluginHandle = pluginHandle;
plugin->m_pluginPath = pluginPath;
plugin->m_pluginPostFix = postFixStr;
m_data->m_pluginMap.insert(plugin->GetMapKey(), pluginUniqueId);
}
else
{
int expect = SHARED_MEMORY_MAGIC_NUMBER;
b3Warning("Warning: plugin is wrong version: expected %d, got %d\n", expect, version);
}
}
else
{
b3Warning("Loaded plugin but couldn't bind functions");
}
if (!ok)
{
B3_DYNLIB_CLOSE(pluginHandle);
}
}
else
{
b3Warning("Warning: couldn't load plugin %s\n", pluginPath);
#ifdef _WIN32
#else
b3Warning("Error: %s\n", dlerror());
#endif
}
if (!ok)
{
m_data->m_plugins.freeHandle(pluginUniqueId);
pluginUniqueId = -1;
}
}
//for now, automatically select the loaded plugin as active renderer.
if (pluginUniqueId >= 0)
{
b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
if (plugin && plugin->m_getRendererFunc)
{
selectPluginRenderer(pluginUniqueId);
}
}
//for now, automatically select the loaded plugin as active collision plugin.
if (pluginUniqueId >= 0)
{
b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
if (plugin && plugin->m_getCollisionFunc)
{
selectCollisionPlugin(pluginUniqueId);
}
}
//for now, automatically select the loaded plugin as active fileIO plugin.
if (pluginUniqueId >= 0)
{
b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
if (plugin && plugin->m_getFileIOFunc)
{
selectFileIOPlugin(pluginUniqueId);
}
}
return pluginUniqueId;
}
void b3PluginManager::unloadPlugin(int pluginUniqueId)
{
b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
if (plugin)
{
if (plugin->m_processNotificationsFunc)
{
m_data->m_numNotificationPlugins--;
}
b3PluginContext context = {0};
context.m_userPointer = plugin->m_userPointer;
context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
if (plugin->m_isInitialized)
{
plugin->m_exitFunc(&context);
plugin->m_userPointer = 0;
plugin->m_returnData = 0;
plugin->m_isInitialized = false;
}
m_data->m_pluginMap.remove(plugin->GetMapKey());
m_data->m_plugins.freeHandle(pluginUniqueId);
}
}
void b3PluginManager::tickPlugins(double timeStep, b3PluginManagerTickMode tickMode)
{
for (int i = 0; i < m_data->m_pluginMap.size(); i++)
{
int* pluginUidPtr = m_data->m_pluginMap.getAtIndex(i);
b3PluginHandle* plugin = 0;
if (pluginUidPtr)
{
int pluginUid = *pluginUidPtr;
plugin = m_data->m_plugins.getHandle(pluginUid);
}
else
{
continue;
}
PFN_TICK tick = 0;
switch (tickMode)
{
case B3_PRE_TICK_MODE:
{
tick = plugin->m_preTickFunc;
break;
}
case B3_POST_TICK_MODE:
{
tick = plugin->m_postTickFunc;
break;
}
case B3_PROCESS_CLIENT_COMMANDS_TICK:
{
tick = plugin->m_processClientCommandsFunc;
break;
}
default:
{
}
}
if (tick)
{
b3PluginContext context = {0};
context.m_userPointer = plugin->m_userPointer;
context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
context.m_numMouseEvents = m_data->m_mouseEvents.size();
context.m_mouseEvents = m_data->m_mouseEvents.size() ? &m_data->m_mouseEvents[0] : 0;
context.m_numKeyEvents = m_data->m_keyEvents.size();
context.m_keyEvents = m_data->m_keyEvents.size() ? &m_data->m_keyEvents[0] : 0;
context.m_numVRControllerEvents = m_data->m_vrEvents.size();
context.m_vrControllerEvents = m_data->m_vrEvents.size() ? &m_data->m_vrEvents[0] : 0;
if (tickMode == B3_PROCESS_CLIENT_COMMANDS_TICK)
{
context.m_rpcCommandProcessorInterface = m_data->m_rpcCommandProcessorInterface;
}
int result = tick(&context);
plugin->m_userPointer = context.m_userPointer;
}
}
}
void b3PluginManager::reportNotifications()
{
b3AlignedObjectArray<b3Notification>& notifications = m_data->m_notifications[m_data->m_activeNotificationsBufferIndex];
if (notifications.size() == 0)
{
return;
}
// Swap notification buffers.
m_data->m_activeNotificationsBufferIndex = 1 - m_data->m_activeNotificationsBufferIndex;
for (int i = 0; i < m_data->m_pluginMap.size(); i++)
{
int* pluginUidPtr = m_data->m_pluginMap.getAtIndex(i);
b3PluginHandle* plugin = 0;
if (pluginUidPtr)
{
int pluginUid = *pluginUidPtr;
plugin = m_data->m_plugins.getHandle(pluginUid);
}
else
{
continue;
}
if (plugin->m_processNotificationsFunc)
{
b3PluginContext context = {0};
context.m_userPointer = plugin->m_userPointer;
context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
context.m_numNotifications = notifications.size();
context.m_notifications = notifications.size() ? &notifications[0] : 0;
plugin->m_processNotificationsFunc(&context);
}
}
notifications.resize(0);
}
int b3PluginManager::executePluginCommand(int pluginUniqueId, const b3PluginArguments* arguments)
{
int result = -1;
b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
if (plugin)
{
b3PluginContext context = {0};
context.m_userPointer = plugin->m_userPointer;
context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
context.m_rpcCommandProcessorInterface = m_data->m_rpcCommandProcessorInterface;
result = plugin->m_executeCommandFunc(&context, arguments);
plugin->m_userPointer = context.m_userPointer;
plugin->m_returnData = context.m_returnData;
}
return result;
}
int b3PluginManager::registerStaticLinkedPlugin(const char* pluginPath, b3PluginFunctions& functions, bool initPlugin)
{
b3Plugin orgPlugin;
int pluginUniqueId = m_data->m_plugins.allocHandle();
b3PluginHandle* pluginHandle = m_data->m_plugins.getHandle(pluginUniqueId);
pluginHandle->m_pluginHandle = 0;
pluginHandle->m_ownsPluginHandle = false;
pluginHandle->m_pluginUniqueId = pluginUniqueId;
pluginHandle->m_executeCommandFunc = functions.m_executeCommandFunc;
pluginHandle->m_exitFunc = functions.m_exitFunc;
pluginHandle->m_initFunc = functions.m_initFunc;
pluginHandle->m_preTickFunc = functions.m_preTickFunc;
pluginHandle->m_postTickFunc = functions.m_postTickFunc;
pluginHandle->m_getRendererFunc = functions.m_getRendererFunc;
pluginHandle->m_getCollisionFunc = functions.m_getCollisionFunc;
pluginHandle->m_processClientCommandsFunc = functions.m_processClientCommandsFunc;
pluginHandle->m_getFileIOFunc = functions.m_fileIoFunc;
pluginHandle->m_pluginHandle = 0;
pluginHandle->m_pluginPath = pluginPath;
pluginHandle->m_pluginPostFix = "";
pluginHandle->m_userPointer = 0;
pluginHandle->m_returnData = 0;
if (pluginHandle->m_processNotificationsFunc)
{
m_data->m_numNotificationPlugins++;
}
m_data->m_pluginMap.insert(pluginHandle->GetMapKey(), pluginUniqueId);
if (initPlugin)
{
b3PluginContext context = {0};
context.m_userPointer = 0;
context.m_returnData = 0;
context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
context.m_rpcCommandProcessorInterface = m_data->m_rpcCommandProcessorInterface;
int result = pluginHandle->m_initFunc(&context);
pluginHandle->m_isInitialized = true;
pluginHandle->m_userPointer = context.m_userPointer;
pluginHandle->m_returnData = 0;
}
return pluginUniqueId;
}
void b3PluginManager::selectPluginRenderer(int pluginUniqueId)
{
m_data->m_activeRendererPluginUid = pluginUniqueId;
}
UrdfRenderingInterface* b3PluginManager::getRenderInterface()
{
UrdfRenderingInterface* renderer = 0;
if (m_data->m_activeRendererPluginUid >= 0)
{
b3PluginHandle* plugin = m_data->m_plugins.getHandle(m_data->m_activeRendererPluginUid);
if (plugin && plugin->m_getRendererFunc)
{
b3PluginContext context = {0};
context.m_userPointer = plugin->m_userPointer;
context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
renderer = plugin->m_getRendererFunc(&context);
}
}
return renderer;
}
void b3PluginManager::selectFileIOPlugin(int pluginUniqueId)
{
m_data->m_activeFileIOPluginUid = pluginUniqueId;
}
struct CommonFileIOInterface* b3PluginManager::getFileIOInterface()
{
CommonFileIOInterface* fileIOInterface = 0;
if (m_data->m_activeFileIOPluginUid >= 0)
{
b3PluginHandle* plugin = m_data->m_plugins.getHandle(m_data->m_activeFileIOPluginUid);
if (plugin && plugin->m_getFileIOFunc)
{
b3PluginContext context = {0};
context.m_userPointer = plugin->m_userPointer;
context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
fileIOInterface = plugin->m_getFileIOFunc(&context);
}
}
if (fileIOInterface==0)
{
return &m_data->m_defaultFileIO;
}
return fileIOInterface;
}
void b3PluginManager::selectCollisionPlugin(int pluginUniqueId)
{
m_data->m_activeCollisionPluginUid = pluginUniqueId;
}
struct b3PluginCollisionInterface* b3PluginManager::getCollisionInterface()
{
b3PluginCollisionInterface* collisionInterface = 0;
if (m_data->m_activeCollisionPluginUid >= 0)
{
b3PluginHandle* plugin = m_data->m_plugins.getHandle(m_data->m_activeCollisionPluginUid);
if (plugin && plugin->m_getCollisionFunc)
{
b3PluginContext context = {0};
context.m_userPointer = plugin->m_userPointer;
context.m_physClient = (b3PhysicsClientHandle)m_data->m_physicsDirect;
collisionInterface = plugin->m_getCollisionFunc(&context);
}
}
return collisionInterface;
}
const struct b3UserDataValue* b3PluginManager::getReturnData(int pluginUniqueId)
{
b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId);
if (plugin)
{
return plugin->m_returnData;
}
return 0;
}

View file

@ -0,0 +1,77 @@
#ifndef B3_PLUGIN_MANAGER_H
#define B3_PLUGIN_MANAGER_H
#include "plugins/b3PluginAPI.h"
enum b3PluginManagerTickMode
{
B3_PRE_TICK_MODE = 1,
B3_POST_TICK_MODE,
B3_PROCESS_CLIENT_COMMANDS_TICK,
};
struct b3PluginFunctions
{
//required
PFN_INIT m_initFunc;
PFN_EXIT m_exitFunc;
PFN_EXECUTE m_executeCommandFunc;
//optional
PFN_TICK m_preTickFunc;
PFN_TICK m_postTickFunc;
PFN_GET_RENDER_INTERFACE m_getRendererFunc;
PFN_TICK m_processClientCommandsFunc;
PFN_TICK m_processNotificationsFunc;
PFN_GET_COLLISION_INTERFACE m_getCollisionFunc;
PFN_GET_FILEIO_INTERFACE m_fileIoFunc;
b3PluginFunctions(PFN_INIT initFunc, PFN_EXIT exitFunc, PFN_EXECUTE executeCommandFunc)
:m_initFunc(initFunc),
m_exitFunc(exitFunc),
m_executeCommandFunc(executeCommandFunc),
m_preTickFunc(0),
m_postTickFunc(0),
m_getRendererFunc(0),
m_processClientCommandsFunc(0),
m_processNotificationsFunc(0),
m_getCollisionFunc(0),
m_fileIoFunc(0)
{
}
};
class b3PluginManager
{
struct b3PluginManagerInternalData* m_data;
public:
b3PluginManager(class PhysicsCommandProcessorInterface* physSdk);
virtual ~b3PluginManager();
int loadPlugin(const char* pluginPath, const char* postFixStr = "");
void unloadPlugin(int pluginUniqueId);
int executePluginCommand(int pluginUniqueId, const struct b3PluginArguments* arguments);
void addEvents(const struct b3VRControllerEvent* vrControllerEvents, int numVRControllerEvents, const struct b3KeyboardEvent* keyEvents, int numKeyEvents, const struct b3MouseEvent* mouseEvents, int numMouseEvents);
void clearEvents();
void addNotification(const struct b3Notification& notification);
void reportNotifications();
void tickPlugins(double timeStep, b3PluginManagerTickMode tickMode);
int registerStaticLinkedPlugin(const char* pluginPath, b3PluginFunctions& functions, bool initPlugin = true);
void selectPluginRenderer(int pluginUniqueId);
struct UrdfRenderingInterface* getRenderInterface();
void selectFileIOPlugin(int pluginUniqueId);
struct CommonFileIOInterface* getFileIOInterface();
void selectCollisionPlugin(int pluginUniqueId);
struct b3PluginCollisionInterface* getCollisionInterface();
const struct b3UserDataValue* getReturnData(int pluginUniqueId);
};
#endif //B3_PLUGIN_MANAGER_H

View file

@ -0,0 +1,18 @@
#ifndef B3_ROBOT_SIMULATOR_CLIENT_API_INTERNAL_DATA_H
#define B3_ROBOT_SIMULATOR_CLIENT_API_INTERNAL_DATA_H
#include "../SharedMemory/PhysicsClientC_API.h"
struct b3RobotSimulatorClientAPI_InternalData
{
b3PhysicsClientHandle m_physicsClientHandle;
struct GUIHelperInterface* m_guiHelper;
b3RobotSimulatorClientAPI_InternalData()
: m_physicsClientHandle(0),
m_guiHelper(0)
{
}
};
#endif //B3_ROBOT_SIMULATOR_CLIENT_API_INTERNAL_DATA_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,914 @@
#ifndef B3_ROBOT_SIMULATOR_CLIENT_API_NO_DIRECT_H
#define B3_ROBOT_SIMULATOR_CLIENT_API_NO_DIRECT_H
///The b3RobotSimulatorClientAPI is pretty much the C++ version of pybullet
///as documented in the pybullet Quickstart Guide
///https://docs.google.com/document/d/10sXEhzFRSnvFcl3XxNGhnD4N2SedqwdAvK3dsihxVUA
#include "SharedMemoryPublic.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btQuaternion.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btAlignedObjectArray.h"
#include <string>
struct b3RobotSimulatorLoadUrdfFileArgs
{
btVector3 m_startPosition;
btQuaternion m_startOrientation;
bool m_forceOverrideFixedBase;
bool m_useMultiBody;
int m_flags;
b3RobotSimulatorLoadUrdfFileArgs(const btVector3 &startPos, const btQuaternion &startOrn)
: m_startPosition(startPos),
m_startOrientation(startOrn),
m_forceOverrideFixedBase(false),
m_useMultiBody(true),
m_flags(0)
{
}
b3RobotSimulatorLoadUrdfFileArgs()
: m_startPosition(btVector3(0, 0, 0)),
m_startOrientation(btQuaternion(0, 0, 0, 1)),
m_forceOverrideFixedBase(false),
m_useMultiBody(true),
m_flags(0)
{
}
};
struct b3RobotSimulatorLoadSdfFileArgs
{
bool m_forceOverrideFixedBase;
bool m_useMultiBody;
b3RobotSimulatorLoadSdfFileArgs()
: m_forceOverrideFixedBase(false),
m_useMultiBody(true)
{
}
};
struct b3RobotSimulatorLoadSoftBodyArgs
{
btVector3 m_startPosition;
btQuaternion m_startOrientation;
double m_scale;
double m_mass;
double m_collisionMargin;
b3RobotSimulatorLoadSoftBodyArgs(const btVector3 &startPos, const btQuaternion &startOrn, const double &scale, const double &mass, const double &collisionMargin)
: m_startPosition(startPos),
m_startOrientation(startOrn),
m_scale(scale),
m_mass(mass),
m_collisionMargin(collisionMargin)
{
}
b3RobotSimulatorLoadSoftBodyArgs(const btVector3 &startPos, const btQuaternion &startOrn)
{
b3RobotSimulatorLoadSoftBodyArgs(startPos, startOrn, 1.0, 1.0, 0.02);
}
b3RobotSimulatorLoadSoftBodyArgs()
{
b3RobotSimulatorLoadSoftBodyArgs(btVector3(0, 0, 0), btQuaternion(0, 0, 0, 1));
}
b3RobotSimulatorLoadSoftBodyArgs(double scale, double mass, double collisionMargin)
: m_startPosition(btVector3(0, 0, 0)),
m_startOrientation(btQuaternion(0, 0, 0, 1)),
m_scale(scale),
m_mass(mass),
m_collisionMargin(collisionMargin)
{
}
};
struct b3RobotSimulatorLoadDeformableBodyArgs
{
btVector3 m_startPosition;
btQuaternion m_startOrientation;
double m_scale;
double m_mass;
double m_collisionMargin;
double m_springElasticStiffness;
double m_springDampingStiffness;
double m_springBendingStiffness;
double m_NeoHookeanMu;
double m_NeoHookeanLambda;
double m_NeoHookeanDamping;
bool m_useSelfCollision;
bool m_useFaceContact;
bool m_useBendingSprings;
double m_frictionCoeff;
b3RobotSimulatorLoadDeformableBodyArgs(const btVector3 &startPos, const btQuaternion &startOrn, const double &scale, const double &mass, const double &collisionMargin)
: m_startPosition(startPos),
m_startOrientation(startOrn),
m_scale(scale),
m_mass(mass),
m_collisionMargin(collisionMargin),
m_springElasticStiffness(-1),
m_springDampingStiffness(-1),
m_springBendingStiffness(-1),
m_NeoHookeanMu(-1),
m_NeoHookeanDamping(-1),
m_useSelfCollision(false),
m_useFaceContact(false),
m_useBendingSprings(false),
m_frictionCoeff(0)
{
}
b3RobotSimulatorLoadDeformableBodyArgs(const btVector3 &startPos, const btQuaternion &startOrn)
{
b3RobotSimulatorLoadSoftBodyArgs(startPos, startOrn, 1.0, 1.0, 0.02);
}
b3RobotSimulatorLoadDeformableBodyArgs()
{
b3RobotSimulatorLoadSoftBodyArgs(btVector3(0, 0, 0), btQuaternion(0, 0, 0, 1));
}
b3RobotSimulatorLoadDeformableBodyArgs(double scale, double mass, double collisionMargin)
: m_startPosition(btVector3(0, 0, 0)),
m_startOrientation(btQuaternion(0, 0, 0, 1)),
m_scale(scale),
m_mass(mass),
m_collisionMargin(collisionMargin)
{
}
};
struct b3RobotSimulatorLoadFileResults
{
btAlignedObjectArray<int> m_uniqueObjectIds;
b3RobotSimulatorLoadFileResults()
{
}
};
struct b3RobotSimulatorChangeVisualShapeArgs
{
int m_objectUniqueId;
int m_linkIndex;
int m_shapeIndex;
int m_textureUniqueId;
btVector4 m_rgbaColor;
bool m_hasRgbaColor;
btVector3 m_specularColor;
bool m_hasSpecularColor;
b3RobotSimulatorChangeVisualShapeArgs()
: m_objectUniqueId(-1),
m_linkIndex(-1),
m_shapeIndex(-1),
m_textureUniqueId(-2),
m_rgbaColor(0, 0, 0, 1),
m_hasRgbaColor(false),
m_specularColor(1, 1, 1),
m_hasSpecularColor(false)
{
}
};
struct b3RobotSimulatorJointMotorArgs
{
int m_controlMode;
double m_targetPosition;
double m_kp;
double m_targetVelocity;
double m_kd;
double m_maxTorqueValue;
b3RobotSimulatorJointMotorArgs(int controlMode)
: m_controlMode(controlMode),
m_targetPosition(0),
m_kp(0.1),
m_targetVelocity(0),
m_kd(0.9),
m_maxTorqueValue(1000)
{
}
};
enum b3RobotSimulatorInverseKinematicsFlags
{
B3_HAS_IK_TARGET_ORIENTATION = 1,
B3_HAS_NULL_SPACE_VELOCITY = 2,
B3_HAS_JOINT_DAMPING = 4,
B3_HAS_CURRENT_POSITIONS = 8,
};
struct b3RobotSimulatorInverseKinematicArgs
{
int m_bodyUniqueId;
double m_endEffectorTargetPosition[3];
double m_endEffectorTargetOrientation[4];
int m_endEffectorLinkIndex;
int m_flags;
int m_numDegreeOfFreedom;
btAlignedObjectArray<double> m_lowerLimits;
btAlignedObjectArray<double> m_upperLimits;
btAlignedObjectArray<double> m_jointRanges;
btAlignedObjectArray<double> m_restPoses;
btAlignedObjectArray<double> m_jointDamping;
btAlignedObjectArray<double> m_currentJointPositions;
b3RobotSimulatorInverseKinematicArgs()
: m_bodyUniqueId(-1),
m_endEffectorLinkIndex(-1),
m_flags(0)
{
m_endEffectorTargetPosition[0] = 0;
m_endEffectorTargetPosition[1] = 0;
m_endEffectorTargetPosition[2] = 0;
m_endEffectorTargetOrientation[0] = 0;
m_endEffectorTargetOrientation[1] = 0;
m_endEffectorTargetOrientation[2] = 0;
m_endEffectorTargetOrientation[3] = 1;
}
};
struct b3RobotSimulatorInverseKinematicsResults
{
int m_bodyUniqueId;
btAlignedObjectArray<double> m_calculatedJointPositions;
};
struct b3JointStates2
{
int m_bodyUniqueId;
int m_numDegreeOfFreedomQ;
int m_numDegreeOfFreedomU;
btTransform m_rootLocalInertialFrame;
btAlignedObjectArray<double> m_actualStateQ;
btAlignedObjectArray<double> m_actualStateQdot;
btAlignedObjectArray<double> m_jointReactionForces;
};
struct b3RobotSimulatorJointMotorArrayArgs
{
int m_controlMode;
int m_numControlledDofs;
int *m_jointIndices;
double *m_targetPositions;
double *m_kps;
double *m_targetVelocities;
double *m_kds;
double *m_forces;
b3RobotSimulatorJointMotorArrayArgs(int controlMode, int numControlledDofs)
: m_controlMode(controlMode),
m_numControlledDofs(numControlledDofs),
m_jointIndices(NULL),
m_targetPositions(NULL),
m_kps(NULL),
m_targetVelocities(NULL),
m_kds(NULL),
m_forces(NULL)
{
}
};
struct b3RobotSimulatorGetCameraImageArgs
{
int m_width;
int m_height;
float *m_viewMatrix;
float *m_projectionMatrix;
float *m_lightDirection;
float *m_lightColor;
float m_lightDistance;
int m_hasShadow;
float m_lightAmbientCoeff;
float m_lightDiffuseCoeff;
float m_lightSpecularCoeff;
int m_renderer;
b3RobotSimulatorGetCameraImageArgs(int width, int height)
: m_width(width),
m_height(height),
m_viewMatrix(NULL),
m_projectionMatrix(NULL),
m_lightDirection(NULL),
m_lightColor(NULL),
m_lightDistance(-1),
m_hasShadow(-1),
m_lightAmbientCoeff(-1),
m_lightDiffuseCoeff(-1),
m_lightSpecularCoeff(-1),
m_renderer(-1)
{
}
};
struct b3RobotSimulatorSetPhysicsEngineParameters : b3PhysicsSimulationParameters
{
b3RobotSimulatorSetPhysicsEngineParameters()
{
m_deltaTime = -1;
m_gravityAcceleration[0] = 0;
m_gravityAcceleration[1] = 0;
m_gravityAcceleration[2] = 0;
m_numSimulationSubSteps = -1;
m_numSolverIterations = -1;
m_useRealTimeSimulation = -1;
m_useSplitImpulse = -1;
m_splitImpulsePenetrationThreshold = -1;
m_contactBreakingThreshold = -1;
m_internalSimFlags = -1;
m_defaultContactERP = -1;
m_collisionFilterMode = -1;
m_enableFileCaching = -1;
m_restitutionVelocityThreshold = -1;
m_defaultNonContactERP = -1;
m_frictionERP = -1;
m_defaultGlobalCFM = -1;
m_frictionCFM = -1;
m_enableConeFriction = -1;
m_deterministicOverlappingPairs = -1;
m_allowedCcdPenetration = -1;
m_jointFeedbackMode = -1;
m_solverResidualThreshold = -1;
m_contactSlop = -1;
m_collisionFilterMode = -1;
m_contactBreakingThreshold = -1;
m_enableFileCaching = -1;
m_restitutionVelocityThreshold = -1;
m_frictionERP = -1;
m_solverResidualThreshold = -1;
m_constraintSolverType = -1;
m_minimumSolverIslandSize = -1;
}
};
struct b3RobotSimulatorChangeDynamicsArgs
{
double m_mass;
double m_lateralFriction;
double m_spinningFriction;
double m_rollingFriction;
double m_restitution;
double m_linearDamping;
double m_angularDamping;
double m_contactStiffness;
double m_contactDamping;
int m_frictionAnchor;
int m_activationState;
b3RobotSimulatorChangeDynamicsArgs()
: m_mass(-1),
m_lateralFriction(-1),
m_spinningFriction(-1),
m_rollingFriction(-1),
m_restitution(-1),
m_linearDamping(-1),
m_angularDamping(-1),
m_contactStiffness(-1),
m_contactDamping(-1),
m_frictionAnchor(-1),
m_activationState(-1)
{
}
};
struct b3RobotSimulatorAddUserDebugLineArgs
{
double m_colorRGB[3];
double m_lineWidth;
double m_lifeTime;
int m_parentObjectUniqueId;
int m_parentLinkIndex;
b3RobotSimulatorAddUserDebugLineArgs()
: m_lineWidth(1),
m_lifeTime(0),
m_parentObjectUniqueId(-1),
m_parentLinkIndex(-1)
{
m_colorRGB[0] = 1;
m_colorRGB[1] = 1;
m_colorRGB[2] = 1;
}
};
enum b3AddUserDebugTextFlags
{
DEBUG_TEXT_HAS_ORIENTATION = 1
};
struct b3RobotSimulatorAddUserDebugTextArgs
{
double m_colorRGB[3];
double m_size;
double m_lifeTime;
double m_textOrientation[4];
int m_parentObjectUniqueId;
int m_parentLinkIndex;
int m_flags;
b3RobotSimulatorAddUserDebugTextArgs()
: m_size(1),
m_lifeTime(0),
m_parentObjectUniqueId(-1),
m_parentLinkIndex(-1),
m_flags(0)
{
m_colorRGB[0] = 1;
m_colorRGB[1] = 1;
m_colorRGB[2] = 1;
m_textOrientation[0] = 0;
m_textOrientation[1] = 0;
m_textOrientation[2] = 0;
m_textOrientation[3] = 1;
}
};
struct b3RobotSimulatorGetContactPointsArgs
{
int m_bodyUniqueIdA;
int m_bodyUniqueIdB;
int m_linkIndexA;
int m_linkIndexB;
b3RobotSimulatorGetContactPointsArgs()
: m_bodyUniqueIdA(-1),
m_bodyUniqueIdB(-1),
m_linkIndexA(-2),
m_linkIndexB(-2)
{
}
};
struct b3RobotSimulatorCreateCollisionShapeArgs
{
int m_shapeType;
double m_radius;
btVector3 m_halfExtents;
double m_height;
char *m_fileName;
btVector3 m_meshScale;
btVector3 m_planeNormal;
int m_flags;
double m_heightfieldTextureScaling;
btAlignedObjectArray<float> m_heightfieldData;
int m_numHeightfieldRows;
int m_numHeightfieldColumns;
int m_replaceHeightfieldIndex;
b3RobotSimulatorCreateCollisionShapeArgs()
: m_shapeType(-1),
m_radius(0.5),
m_height(1),
m_fileName(NULL),
m_flags(0),
m_heightfieldTextureScaling(1),
m_numHeightfieldRows(0),
m_numHeightfieldColumns(0),
m_replaceHeightfieldIndex(-1)
{
m_halfExtents.m_floats[0] = 1;
m_halfExtents.m_floats[1] = 1;
m_halfExtents.m_floats[2] = 1;
m_meshScale.m_floats[0] = 1;
m_meshScale.m_floats[1] = 1;
m_meshScale.m_floats[2] = 1;
m_planeNormal.m_floats[0] = 0;
m_planeNormal.m_floats[1] = 0;
m_planeNormal.m_floats[2] = 1;
}
};
struct b3RobotSimulatorCreateVisualShapeArgs
{
int m_shapeType;
double m_radius;
btVector3 m_halfExtents;
double m_height;
char* m_fileName;
btVector3 m_meshScale;
btVector3 m_planeNormal;
int m_flags;
b3RobotSimulatorCreateVisualShapeArgs()
: m_shapeType(-1),
m_radius(0.5),
m_height(1),
m_fileName(NULL),
m_flags(0)
{
m_halfExtents.m_floats[0] = 1;
m_halfExtents.m_floats[1] = 1;
m_halfExtents.m_floats[2] = 1;
m_meshScale.m_floats[0] = 1;
m_meshScale.m_floats[1] = 1;
m_meshScale.m_floats[2] = 1;
m_planeNormal.m_floats[0] = 0;
m_planeNormal.m_floats[1] = 0;
m_planeNormal.m_floats[2] = 1;
}
};
struct b3RobotSimulatorCreateMultiBodyArgs
{
double m_baseMass;
int m_baseCollisionShapeIndex;
int m_baseVisualShapeIndex;
btVector3 m_basePosition;
btQuaternion m_baseOrientation;
btVector3 m_baseInertialFramePosition;
btQuaternion m_baseInertialFrameOrientation;
int m_numLinks;
double *m_linkMasses;
int *m_linkCollisionShapeIndices;
int *m_linkVisualShapeIndices;
btVector3 *m_linkPositions;
btQuaternion *m_linkOrientations;
btVector3 *m_linkInertialFramePositions;
btQuaternion *m_linkInertialFrameOrientations;
int *m_linkParentIndices;
int *m_linkJointTypes;
btVector3 *m_linkJointAxes;
btAlignedObjectArray<btVector3> m_batchPositions;
int m_useMaximalCoordinates;
b3RobotSimulatorCreateMultiBodyArgs()
: m_baseMass(0), m_baseCollisionShapeIndex(-1), m_baseVisualShapeIndex(-1), m_numLinks(0), m_linkMasses(NULL), m_linkCollisionShapeIndices(NULL), m_linkVisualShapeIndices(NULL), m_linkPositions(NULL), m_linkOrientations(NULL), m_linkInertialFramePositions(NULL), m_linkInertialFrameOrientations(NULL), m_linkParentIndices(NULL), m_linkJointTypes(NULL), m_linkJointAxes(NULL), m_useMaximalCoordinates(0)
{
m_basePosition.setValue(0, 0, 0);
m_baseOrientation.setValue(0, 0, 0, 1);
m_baseInertialFramePosition.setValue(0, 0, 0);
m_baseInertialFrameOrientation.setValue(0, 0, 0, 1);
}
};
struct b3RobotUserConstraint : public b3UserConstraint
{
int m_userUpdateFlags;//see EnumUserConstraintFlags
void setErp(double erp)
{
m_erp = erp;
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_ERP;
}
void setMaxAppliedForce(double maxForce)
{
m_maxAppliedForce = maxForce;
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_MAX_FORCE;
}
void setGearRatio(double gearRatio)
{
m_gearRatio = gearRatio;
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_GEAR_RATIO;
}
void setGearAuxLink(int link)
{
m_gearAuxLink = link;
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_GEAR_AUX_LINK;
}
void setRelativePositionTarget(double target)
{
m_relativePositionTarget = target;
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_RELATIVE_POSITION_TARGET;
}
void setChildPivot(double pivot[3])
{
m_childFrame[0] = pivot[0];
m_childFrame[1] = pivot[1];
m_childFrame[2] = pivot[2];
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_PIVOT_IN_B;
}
void setChildFrameOrientation(double orn[4])
{
m_childFrame[3] = orn[0];
m_childFrame[4] = orn[1];
m_childFrame[5] = orn[2];
m_childFrame[6] = orn[3];
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_FRAME_ORN_IN_B;
}
b3RobotUserConstraint()
:m_userUpdateFlags(0)
{
m_parentBodyIndex = -1;
m_parentJointIndex = -1;
m_childBodyIndex = -1;
m_childJointIndex = -1;
//position
m_parentFrame[0] = 0;
m_parentFrame[1] = 0;
m_parentFrame[2] = 0;
//orientation quaternion [x,y,z,w]
m_parentFrame[3] = 0;
m_parentFrame[4] = 0;
m_parentFrame[5] = 0;
m_parentFrame[6] = 1;
//position
m_childFrame[0] = 0;
m_childFrame[1] = 0;
m_childFrame[2] = 0;
//orientation quaternion [x,y,z,w]
m_childFrame[3] = 0;
m_childFrame[4] = 0;
m_childFrame[5] = 0;
m_childFrame[6] = 1;
m_jointAxis[0] = 0;
m_jointAxis[1] = 0;
m_jointAxis[2] = 1;
m_jointType = eFixedType;
m_maxAppliedForce = 500;
m_userConstraintUniqueId = -1;
m_gearRatio = -1;
m_gearAuxLink = -1;
m_relativePositionTarget = 0;
m_erp = 0;
}
};
struct b3RobotJointInfo : public b3JointInfo
{
b3RobotJointInfo()
{
m_linkName[0] = 0;
m_jointName[0] = 0;
m_jointType = eFixedType;
m_qIndex = -1;
m_uIndex = -1;
m_jointIndex = -1;
m_flags = 0;
m_jointDamping = 0;
m_jointFriction = 0;
m_jointLowerLimit = 1;
m_jointUpperLimit = -1;
m_jointMaxForce = 500;
m_jointMaxVelocity = 100;
m_parentIndex = -1;
//position
m_parentFrame[0] = 0;
m_parentFrame[1] = 0;
m_parentFrame[2] = 0;
//orientation quaternion [x,y,z,w]
m_parentFrame[3] = 0;
m_parentFrame[4] = 0;
m_parentFrame[5] = 0;
m_parentFrame[6] = 1;
//position
m_childFrame[0] = 0;
m_childFrame[1] = 0;
m_childFrame[2] = 0;
//orientation quaternion [x,y,z,w]
m_childFrame[3] = 0;
m_childFrame[4] = 0;
m_childFrame[5] = 0;
m_childFrame[6] = 1;
m_jointAxis[0] = 0;
m_jointAxis[1] = 0;
m_jointAxis[2] = 1;
}
};
class b3RobotSimulatorClientAPI_NoDirect
{
protected:
struct b3RobotSimulatorClientAPI_InternalData *m_data;
public:
b3RobotSimulatorClientAPI_NoDirect();
virtual ~b3RobotSimulatorClientAPI_NoDirect();
//No 'connect', use setInternalData to bypass the connect method, pass an existing client
virtual void setInternalData(struct b3RobotSimulatorClientAPI_InternalData *data);
void disconnect();
bool isConnected() const;
void setTimeOut(double timeOutInSec);
void syncBodies();
void resetSimulation();
void resetSimulation(int flag);
btQuaternion getQuaternionFromEuler(const btVector3 &rollPitchYaw);
btVector3 getEulerFromQuaternion(const btQuaternion &quat);
int loadURDF(const std::string &fileName, const struct b3RobotSimulatorLoadUrdfFileArgs &args = b3RobotSimulatorLoadUrdfFileArgs());
bool loadSDF(const std::string &fileName, b3RobotSimulatorLoadFileResults &results, const struct b3RobotSimulatorLoadSdfFileArgs &args = b3RobotSimulatorLoadSdfFileArgs());
bool loadMJCF(const std::string &fileName, b3RobotSimulatorLoadFileResults &results);
bool loadBullet(const std::string &fileName, b3RobotSimulatorLoadFileResults &results);
bool saveBullet(const std::string &fileName);
int loadTexture(const std::string &fileName);
bool changeVisualShape(const struct b3RobotSimulatorChangeVisualShapeArgs &args);
bool savePythonWorld(const std::string &fileName);
bool getBodyInfo(int bodyUniqueId, struct b3BodyInfo *bodyInfo);
bool getBasePositionAndOrientation(int bodyUniqueId, btVector3 &basePosition, btQuaternion &baseOrientation) const;
bool resetBasePositionAndOrientation(int bodyUniqueId, const btVector3 &basePosition, const btQuaternion &baseOrientation);
bool getBaseVelocity(int bodyUniqueId, btVector3 &baseLinearVelocity, btVector3 &baseAngularVelocity) const;
bool resetBaseVelocity(int bodyUniqueId, const btVector3 &linearVelocity, const btVector3 &angularVelocity) const;
int getNumJoints(int bodyUniqueId) const;
bool getJointInfo(int bodyUniqueId, int jointIndex, b3JointInfo *jointInfo);
int createConstraint(int parentBodyIndex, int parentJointIndex, int childBodyIndex, int childJointIndex, b3JointInfo *jointInfo);
int changeConstraint(int constraintId, b3RobotUserConstraint*jointInfo);
void removeConstraint(int constraintId);
bool getConstraintInfo(int constraintUniqueId, struct b3UserConstraint &constraintInfo);
bool getJointState(int bodyUniqueId, int jointIndex, struct b3JointSensorState *state);
bool getJointStates(int bodyUniqueId, b3JointStates2 &state);
bool resetJointState(int bodyUniqueId, int jointIndex, double targetValue);
void setJointMotorControl(int bodyUniqueId, int jointIndex, const struct b3RobotSimulatorJointMotorArgs &args);
bool setJointMotorControlArray(int bodyUniqueId, int controlMode, int numControlledDofs,
int *jointIndices, double *targetVelocities, double *targetPositions,
double *forces, double *kps, double *kds);
void stepSimulation();
bool canSubmitCommand() const;
void setRealTimeSimulation(bool enableRealTimeSimulation);
void setInternalSimFlags(int flags);
void setGravity(const btVector3 &gravityAcceleration);
void setTimeStep(double timeStepInSeconds);
void setNumSimulationSubSteps(int numSubSteps);
void setNumSolverIterations(int numIterations);
void setContactBreakingThreshold(double threshold);
int computeDofCount(int bodyUniqueId) const;
bool calculateInverseKinematics(const struct b3RobotSimulatorInverseKinematicArgs &args, struct b3RobotSimulatorInverseKinematicsResults &results);
int calculateMassMatrix(int bodyUniqueId, const double* jointPositions, int numJointPositions, double* massMatrix, int flags);
bool getBodyJacobian(int bodyUniqueId, int linkIndex, const double *localPosition, const double *jointPositions, const double *jointVelocities, const double *jointAccelerations, double *linearJacobian, double *angularJacobian);
void configureDebugVisualizer(enum b3ConfigureDebugVisualizerEnum flag, int enable);
void resetDebugVisualizerCamera(double cameraDistance, double cameraPitch, double cameraYaw, const btVector3 &targetPos);
int startStateLogging(b3StateLoggingType loggingType, const std::string &fileName, const btAlignedObjectArray<int> &objectUniqueIds = btAlignedObjectArray<int>(), int maxLogDof = -1);
void stopStateLogging(int stateLoggerUniqueId);
void getVREvents(b3VREventsData *vrEventsData, int deviceTypeFilter);
void getKeyboardEvents(b3KeyboardEventsData *keyboardEventsData);
void submitProfileTiming(const std::string &profileName);
// JFC: added these 24 methods
void getMouseEvents(b3MouseEventsData *mouseEventsData);
bool getLinkState(int bodyUniqueId, int linkIndex, int computeLinkVelocity, int computeForwardKinematics, b3LinkState *linkState);
bool getCameraImage(int width, int height, struct b3RobotSimulatorGetCameraImageArgs args, b3CameraImageData &imageData);
bool calculateInverseDynamics(int bodyUniqueId, double *jointPositions, double *jointVelocities, double *jointAccelerations, double *jointForcesOutput);
int getNumBodies() const;
int getBodyUniqueId(int bodyId) const;
bool removeBody(int bodyUniqueId);
bool getDynamicsInfo(int bodyUniqueId, int linkIndex, b3DynamicsInfo *dynamicsInfo);
bool changeDynamics(int bodyUniqueId, int linkIndex, struct b3RobotSimulatorChangeDynamicsArgs &args);
int addUserDebugParameter(const char *paramName, double rangeMin, double rangeMax, double startValue);
double readUserDebugParameter(int itemUniqueId);
bool removeUserDebugItem(int itemUniqueId);
int addUserDebugText(const char *text, double *textPosition, struct b3RobotSimulatorAddUserDebugTextArgs &args);
int addUserDebugText(const char *text, btVector3 &textPosition, struct b3RobotSimulatorAddUserDebugTextArgs &args);
int addUserDebugLine(double *fromXYZ, double *toXYZ, struct b3RobotSimulatorAddUserDebugLineArgs &args);
int addUserDebugLine(btVector3 &fromXYZ, btVector3 &toXYZ, struct b3RobotSimulatorAddUserDebugLineArgs &args);
bool setJointMotorControlArray(int bodyUniqueId, struct b3RobotSimulatorJointMotorArrayArgs &args);
bool setPhysicsEngineParameter(const struct b3RobotSimulatorSetPhysicsEngineParameters &args);
bool getPhysicsEngineParameters(struct b3RobotSimulatorSetPhysicsEngineParameters &args);
bool applyExternalForce(int objectUniqueId, int linkIndex, double *force, double *position, int flags);
bool applyExternalForce(int objectUniqueId, int linkIndex, btVector3 &force, btVector3 &position, int flags);
bool applyExternalTorque(int objectUniqueId, int linkIndex, double *torque, int flags);
bool applyExternalTorque(int objectUniqueId, int linkIndex, btVector3 &torque, int flags);
bool enableJointForceTorqueSensor(int bodyUniqueId, int jointIndex, bool enable);
bool getDebugVisualizerCamera(struct b3OpenGLVisualizerCameraInfo *cameraInfo);
bool getContactPoints(struct b3RobotSimulatorGetContactPointsArgs &args, struct b3ContactInformation *contactInfo);
bool getClosestPoints(struct b3RobotSimulatorGetContactPointsArgs &args, double distance, struct b3ContactInformation *contactInfo);
bool getOverlappingObjects(double *aabbMin, double *aabbMax, struct b3AABBOverlapData *overlapData);
bool getOverlappingObjects(btVector3 &aabbMin, btVector3 &aabbMax, struct b3AABBOverlapData *overlapData);
bool getAABB(int bodyUniqueId, int linkIndex, double *aabbMin, double *aabbMax);
bool getAABB(int bodyUniqueId, int linkIndex, btVector3 &aabbMin, btVector3 &aabbMax);
int createVisualShape(int shapeType, struct b3RobotSimulatorCreateVisualShapeArgs& args);
int createCollisionShape(int shapeType, struct b3RobotSimulatorCreateCollisionShapeArgs &args);
int createMultiBody(struct b3RobotSimulatorCreateMultiBodyArgs &args);
int getNumConstraints() const;
int getConstraintUniqueId(int serialIndex);
void loadSoftBody(const std::string &fileName, const struct b3RobotSimulatorLoadSoftBodyArgs &args);
void loadDeformableBody(const std::string &fileName, const struct b3RobotSimulatorLoadDeformableBodyArgs &args);
virtual void setGuiHelper(struct GUIHelperInterface *guiHelper);
virtual struct GUIHelperInterface *getGuiHelper();
bool getCollisionShapeData(int bodyUniqueId, int linkIndex, b3CollisionShapeInformation &collisionShapeInfo);
bool getVisualShapeData(int bodyUniqueId, struct b3VisualShapeInformation &visualShapeInfo);
int saveStateToMemory();
void restoreStateFromMemory(int stateId);
void removeState(int stateUniqueId);
int getAPIVersion() const
{
return SHARED_MEMORY_MAGIC_NUMBER;
}
void setAdditionalSearchPath(const std::string &path);
void setCollisionFilterGroupMask(int bodyUniqueIdA, int linkIndexA, int collisionFilterGroup, int collisionFilterMask);
};
#endif //B3_ROBOT_SIMULATOR_CLIENT_API_NO_DIRECT_H

View file

@ -0,0 +1,107 @@
#include "b3RobotSimulatorClientAPI_NoGUI.h"
#include "PhysicsClientC_API.h"
#include "b3RobotSimulatorClientAPI_InternalData.h"
#ifdef BT_ENABLE_ENET
#include "PhysicsClientUDP_C_API.h"
#endif //PHYSICS_UDP
#ifdef BT_ENABLE_CLSOCKET
#include "PhysicsClientTCP_C_API.h"
#endif //PHYSICS_TCP
#ifndef BT_DISABLE_PHYSICS_DIRECT
#include "PhysicsDirectC_API.h"
#endif //BT_DISABLE_PHYSICS_DIRECT
#include "SharedMemoryPublic.h"
#include "Bullet3Common/b3Logging.h"
b3RobotSimulatorClientAPI_NoGUI::b3RobotSimulatorClientAPI_NoGUI()
{
}
b3RobotSimulatorClientAPI_NoGUI::~b3RobotSimulatorClientAPI_NoGUI()
{
}
bool b3RobotSimulatorClientAPI_NoGUI::connect(int mode, const std::string& hostName, int portOrKey)
{
if (m_data->m_physicsClientHandle)
{
b3Warning("Already connected, disconnect first.");
return false;
}
b3PhysicsClientHandle sm = 0;
int udpPort = 1234;
int tcpPort = 6667;
int key = SHARED_MEMORY_KEY;
switch (mode)
{
case eCONNECT_DIRECT:
{
#ifndef BT_DISABLE_PHYSICS_DIRECT
sm = b3ConnectPhysicsDirect();
#endif //BT_DISABLE_PHYSICS_DIRECT
break;
}
case eCONNECT_SHARED_MEMORY:
{
if (portOrKey >= 0)
{
key = portOrKey;
}
sm = b3ConnectSharedMemory(key);
break;
}
case eCONNECT_UDP:
{
if (portOrKey >= 0)
{
udpPort = portOrKey;
}
#ifdef BT_ENABLE_ENET
sm = b3ConnectPhysicsUDP(hostName.c_str(), udpPort);
#else
b3Warning("UDP is not enabled in this build");
#endif //BT_ENABLE_ENET
break;
}
case eCONNECT_TCP:
{
if (portOrKey >= 0)
{
tcpPort = portOrKey;
}
#ifdef BT_ENABLE_CLSOCKET
sm = b3ConnectPhysicsTCP(hostName.c_str(), tcpPort);
#else
b3Warning("TCP is not enabled in this pybullet build");
#endif //BT_ENABLE_CLSOCKET
break;
}
default:
{
b3Warning("connectPhysicsServer unexpected argument");
}
};
if (sm)
{
m_data->m_physicsClientHandle = sm;
if (!b3CanSubmitCommand(m_data->m_physicsClientHandle))
{
disconnect();
return false;
}
return true;
}
return false;
}

View file

@ -0,0 +1,18 @@
#ifndef B3_ROBOT_SIMULATOR_CLIENT_API_H
#define B3_ROBOT_SIMULATOR_CLIENT_API_H
#include "b3RobotSimulatorClientAPI_NoDirect.h"
///The b3RobotSimulatorClientAPI is pretty much the C++ version of pybullet
///as documented in the pybullet Quickstart Guide
///https://docs.google.com/document/d/10sXEhzFRSnvFcl3XxNGhnD4N2SedqwdAvK3dsihxVUA
class b3RobotSimulatorClientAPI_NoGUI : public b3RobotSimulatorClientAPI_NoDirect
{
public:
b3RobotSimulatorClientAPI_NoGUI();
virtual ~b3RobotSimulatorClientAPI_NoGUI();
bool connect(int mode, const std::string& hostName = "localhost", int portOrKey = -1);
};
#endif //B3_ROBOT_SIMULATOR_CLIENT_API_H

View file

@ -0,0 +1,16 @@
#ifdef BT_ENABLE_DART
#include "DARTPhysicsC_API.h"
#include "DARTPhysicsServerCommandProcessor.h"
#include "DARTPhysicsClient.h"
//think more about naming. The b3ConnectPhysicsLoopback
B3_SHARED_API b3PhysicsClientHandle b3ConnectPhysicsDART()
{
DARTPhysicsServerCommandProcessor* sdk = new DARTPhysicsServerCommandProcessor;
DARTPhysicsClient* direct = new DARTPhysicsClient(sdk, true);
bool connected;
connected = direct->connect();
return (b3PhysicsClientHandle)direct;
}
#endif //BT_ENABLE_DART

View file

@ -0,0 +1,21 @@
#ifndef DART_PHYSICS_C_API_H
#define DART_PHYSICS_C_API_H
#ifdef BT_ENABLE_DART
#include "../PhysicsClientC_API.h"
#ifdef __cplusplus
extern "C"
{
#endif
//think more about naming. The b3ConnectPhysicsLoopback
B3_SHARED_API b3PhysicsClientHandle b3ConnectPhysicsDART();
#ifdef __cplusplus
}
#endif
#endif //BT_ENABLE_DART
#endif //DART_PHYSICS_C_API_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,121 @@
#ifndef DART_PHYSICS_CLIENT_H
#define DART_PHYSICS_CLIENT_H
#include "../PhysicsClient.h"
///PhysicsDirect executes the commands directly, without transporting them or having a separate server executing commands
class DARTPhysicsClient : public PhysicsClient
{
protected:
struct DARTPhysicsDirectInternalData* m_data;
bool processDebugLines(const struct SharedMemoryCommand& orgCommand);
bool processCamera(const struct SharedMemoryCommand& orgCommand);
bool processContactPointData(const struct SharedMemoryCommand& orgCommand);
bool processOverlappingObjects(const struct SharedMemoryCommand& orgCommand);
bool processVisualShapeData(const struct SharedMemoryCommand& orgCommand);
void processBodyJointInfo(int bodyUniqueId, const struct SharedMemoryStatus& serverCmd);
void processAddUserData(const struct SharedMemoryStatus& serverCmd);
void postProcessStatus(const struct SharedMemoryStatus& serverCmd);
void resetData();
void removeCachedBody(int bodyUniqueId);
public:
DARTPhysicsClient(class PhysicsCommandProcessorInterface* physSdk, bool passSdkOwnership);
virtual ~DARTPhysicsClient();
// return true if connection succesfull, can also check 'isConnected'
//it is OK to pass a null pointer for the gui helper
virtual bool connect();
////todo: rename to 'disconnect'
virtual void disconnectSharedMemory();
virtual bool isConnected() const;
// return non-null if there is a status, nullptr otherwise
virtual const SharedMemoryStatus* processServerStatus();
virtual SharedMemoryCommand* getAvailableSharedMemoryCommand();
virtual bool canSubmitCommand() const;
virtual bool submitClientCommand(const struct SharedMemoryCommand& command);
virtual int getNumBodies() const;
virtual int getBodyUniqueId(int serialIndex) const;
virtual bool getBodyInfo(int bodyUniqueId, struct b3BodyInfo& info) const;
virtual int getNumJoints(int bodyIndex) const;
virtual bool getJointInfo(int bodyIndex, int jointIndex, struct b3JointInfo& info) const;
virtual int getNumUserConstraints() const;
virtual int getUserConstraintInfo(int constraintUniqueId, struct b3UserConstraint& info) const;
virtual int getUserConstraintId(int serialIndex) const;
///todo: move this out of the
virtual void setSharedMemoryKey(int key);
void uploadBulletFileToSharedMemory(const char* data, int len);
virtual void uploadRaysToSharedMemory(struct SharedMemoryCommand& command, const double* rayFromWorldArray, const double* rayToWorldArray, int numRays);
virtual int getNumDebugLines() const;
virtual const float* getDebugLinesFrom() const;
virtual const float* getDebugLinesTo() const;
virtual const float* getDebugLinesColor() const;
virtual void getCachedCameraImage(b3CameraImageData* cameraData);
virtual void getCachedContactPointInformation(struct b3ContactInformation* contactPointData);
virtual void getCachedOverlappingObjects(struct b3AABBOverlapData* overlappingObjects);
virtual void getCachedVisualShapeInformation(struct b3VisualShapeInformation* visualShapesInfo);
virtual void getCachedCollisionShapeInformation(struct b3CollisionShapeInformation* collisionShapesInfo);
virtual void getCachedVREvents(struct b3VREventsData* vrEventsData);
virtual void getCachedKeyboardEvents(struct b3KeyboardEventsData* keyboardEventsData);
virtual void getCachedMouseEvents(struct b3MouseEventsData* mouseEventsData);
virtual void getCachedRaycastHits(struct b3RaycastInformation* raycastHits);
virtual void getCachedMassMatrix(int dofCountCheck, double* massMatrix);
//the following APIs are for internal use for visualization:
virtual bool connect(struct GUIHelperInterface* guiHelper);
virtual void renderScene();
virtual void debugDraw(int debugDrawMode);
virtual void setTimeOut(double timeOutInSeconds);
virtual double getTimeOut() const;
virtual bool getCachedUserData(int bodyUniqueId, int linkIndex, int userDataId, struct b3UserDataValue& valueOut) const;
virtual int getCachedUserDataId(int bodyUniqueId, int linkIndex, const char* key) const;
virtual int getNumUserData(int bodyUniqueId, int linkIndex) const;
virtual void getUserDataInfo(int bodyUniqueId, int linkIndex, int userDataIndex, const char** keyOut, int* userDataIdOut) const;
virtual void pushProfileTiming(const char* timingName);
virtual void popProfileTiming();
};
#endif //DART_PHYSICS__H

View file

@ -0,0 +1,33 @@
#include "DARTPhysicsServerCommandProcessor.h"
DARTPhysicsServerCommandProcessor::DARTPhysicsServerCommandProcessor()
{
}
DARTPhysicsServerCommandProcessor::~DARTPhysicsServerCommandProcessor()
{
}
bool DARTPhysicsServerCommandProcessor::connect()
{
return false;
}
void DARTPhysicsServerCommandProcessor::disconnect()
{
}
bool DARTPhysicsServerCommandProcessor::isConnected() const
{
return false;
}
bool DARTPhysicsServerCommandProcessor::processCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
{
return false;
}
bool DARTPhysicsServerCommandProcessor::receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
{
return false;
}

View file

@ -0,0 +1,29 @@
#ifndef DART_PHYSICS_SERVER_COMMAND_PROCESSOR_H
#define DART_PHYSICS_SERVER_COMMAND_PROCESSOR_H
#include "../PhysicsCommandProcessorInterface.h"
class DARTPhysicsServerCommandProcessor : public PhysicsCommandProcessorInterface
{
public:
DARTPhysicsServerCommandProcessor();
virtual ~DARTPhysicsServerCommandProcessor();
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(int renderFlags) {}
virtual void physicsDebugDraw(int debugDrawFlags) {}
virtual void setGuiHelper(struct GUIHelperInterface* guiHelper) {}
virtual void setTimeOut(double timeOutInSeconds) {}
};
#endif //DART_PHYSICS_COMMAND_PROCESSOR_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,21 @@
#ifndef BT_CONVERT_GRPC_BULLET_H
#define BT_CONVERT_GRPC_BULLET_H
#include "../PhysicsClientC_API.h"
namespace pybullet_grpc
{
class PyBulletCommand;
class PyBulletStatus;
}; // namespace pybullet_grpc
struct SharedMemoryCommand* convertGRPCToBulletCommand(const pybullet_grpc::PyBulletCommand& grpcCommand, struct SharedMemoryCommand& cmd);
pybullet_grpc::PyBulletCommand* convertBulletToGRPCCommand(const struct SharedMemoryCommand& clientCmd, pybullet_grpc::PyBulletCommand& grpcCommand);
bool convertGRPCToStatus(const pybullet_grpc::PyBulletStatus& grpcReply, struct SharedMemoryStatus& serverStatus, char* bufferServerToClient, int bufferSizeInBytes);
bool convertStatusToGRPC(const struct SharedMemoryStatus& serverStatus, char* bufferServerToClient, int bufferSizeInBytes, pybullet_grpc::PyBulletStatus& grpcReply);
#endif //BT_CONVERT_GRPC_BULLET_H

View file

@ -0,0 +1,298 @@
///PyBullet / BulletRobotics GRPC server.
///works as standalone GRPC server as as a GRPC server bridge,
///connecting to a local physics server using shared memory
#include <stdio.h>
#include "../../CommonInterfaces/CommonGUIHelperInterface.h"
#include "Bullet3Common/b3CommandLineArgs.h"
#include "PhysicsClientC_API.h"
#ifdef NO_SHARED_MEMORY
#include "PhysicsServerCommandProcessor.h"
typedef PhysicsServerCommandProcessor MyCommandProcessor;
#else
#include "SharedMemoryCommandProcessor.h"
typedef SharedMemoryCommandProcessor MyCommandProcessor;
#endif //NO_SHARED_MEMORY
#include "SharedMemoryCommands.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "PhysicsServerCommandProcessor.h"
#include "../Utils/b3Clock.h"
#include <memory>
#include <iostream>
#include <string>
#include <thread>
#include <grpc++/grpc++.h>
#include <grpc/support/log.h>
#include "SharedMemory/grpc/proto/pybullet.grpc.pb.h"
using grpc::Server;
using grpc::ServerAsyncResponseWriter;
using grpc::ServerBuilder;
using grpc::ServerCompletionQueue;
using grpc::ServerContext;
using grpc::Status;
using pybullet_grpc::PyBulletAPI;
using pybullet_grpc::PyBulletCommand;
using pybullet_grpc::PyBulletStatus;
bool gVerboseNetworkMessagesServer = true;
#include "ConvertGRPCBullet.h"
class ServerImpl final
{
public:
~ServerImpl()
{
server_->Shutdown();
// Always shutdown the completion queue after the server.
cq_->Shutdown();
}
void Run(MyCommandProcessor* comProc, const std::string& hostNamePort)
{
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(hostNamePort, grpc::InsecureServerCredentials());
// Register "service_" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *asynchronous* service.
builder.RegisterService(&service_);
// Get hold of the completion queue used for the asynchronous communication
// with the gRPC runtime.
cq_ = builder.AddCompletionQueue();
// Finally assemble the server.
server_ = builder.BuildAndStart();
std::cout << "Standalone Bullet Physics GRPC server listening on " << hostNamePort << std::endl;
// Proceed to the server's main loop.
HandleRpcs(comProc);
}
private:
// Class encompasing the state and logic needed to serve a request.
class CallData
{
public:
// Take in the "service" instance (in this case representing an asynchronous
// server) and the completion queue "cq" used for asynchronous communication
// with the gRPC runtime.
CallData(PyBulletAPI::AsyncService* service, ServerCompletionQueue* cq, MyCommandProcessor* comProc)
: service_(service), cq_(cq), responder_(&ctx_), status_(CREATE), m_finished(false), m_comProc(comProc)
{
// Invoke the serving logic right away.
Proceed();
}
enum CallStatus
{
CREATE,
PROCESS,
FINISH,
TERMINATE
};
CallStatus Proceed()
{
if (status_ == CREATE)
{
// Make this instance progress to the PROCESS state.
status_ = PROCESS;
// As part of the initial CREATE state, we *request* that the system
// start processing SayHello requests. In this request, "this" acts are
// the tag uniquely identifying the request (so that different CallData
// instances can serve different requests concurrently), in this case
// the memory address of this CallData instance.
service_->RequestSubmitCommand(&ctx_, &m_command, &responder_, cq_, cq_,
this);
}
else if (status_ == PROCESS)
{
// Spawn a new CallData instance to serve new clients while we process
// the one for this CallData. The instance will deallocate itself as
// part of its FINISH state.
new CallData(service_, cq_, m_comProc);
status_ = FINISH;
std::string replyString;
// The actual processing.
SharedMemoryStatus serverStatus;
b3AlignedObjectArray<char> buffer;
buffer.resize(SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
SharedMemoryCommand cmd;
SharedMemoryCommand* cmdPtr = 0;
m_status.set_statustype(CMD_UNKNOWN_COMMAND_FLUSHED);
if (m_command.has_checkversioncommand())
{
m_status.set_statustype(CMD_CLIENT_COMMAND_COMPLETED);
m_status.mutable_checkversionstatus()->set_serverversion(SHARED_MEMORY_MAGIC_NUMBER);
}
else
{
cmdPtr = convertGRPCToBulletCommand(m_command, cmd);
if (cmdPtr)
{
bool hasStatus = m_comProc->processCommand(*cmdPtr, serverStatus, &buffer[0], buffer.size());
m_comProc->reportNotifications();
double timeOutInSeconds = 10;
b3Clock clock;
double startTimeSeconds = clock.getTimeInSeconds();
double curTimeSeconds = clock.getTimeInSeconds();
while ((!hasStatus) && ((curTimeSeconds - startTimeSeconds) < timeOutInSeconds))
{
hasStatus = m_comProc->receiveStatus(serverStatus, &buffer[0], buffer.size());
curTimeSeconds = clock.getTimeInSeconds();
}
if (gVerboseNetworkMessagesServer)
{
//printf("buffer.size = %d\n", buffer.size());
printf("serverStatus.m_numDataStreamBytes = %d\n", serverStatus.m_numDataStreamBytes);
}
if (hasStatus)
{
b3AlignedObjectArray<unsigned char> packetData;
unsigned char* statBytes = (unsigned char*)&serverStatus;
convertStatusToGRPC(serverStatus, &buffer[0], buffer.size(), m_status);
}
}
if (m_command.has_terminateservercommand())
{
status_ = TERMINATE;
}
}
// And we are done! Let the gRPC runtime know we've finished, using the
// memory address of this instance as the uniquely identifying tag for
// the event.
responder_.Finish(m_status, Status::OK, this);
}
else
{
GPR_ASSERT(status_ == FINISH);
// Once in the FINISH state, deallocate ourselves (CallData).
delete this;
}
return status_;
}
private:
// The means of communication with the gRPC runtime for an asynchronous
// server.
PyBulletAPI::AsyncService* service_;
// The producer-consumer queue where for asynchronous server notifications.
ServerCompletionQueue* cq_;
// Context for the rpc, allowing to tweak aspects of it such as the use
// of compression, authentication, as well as to send metadata back to the
// client.
ServerContext ctx_;
// What we get from the client.
PyBulletCommand m_command;
// What we send back to the client.
PyBulletStatus m_status;
// The means to get back to the client.
ServerAsyncResponseWriter<PyBulletStatus> responder_;
// Let's implement a tiny state machine with the following states.
CallStatus status_; // The current serving state.
bool m_finished;
MyCommandProcessor* m_comProc; //physics server command processor
};
// This can be run in multiple threads if needed.
void HandleRpcs(MyCommandProcessor* comProc)
{
// Spawn a new CallData instance to serve new clients.
new CallData(&service_, cq_.get(), comProc);
void* tag; // uniquely identifies a request.
bool ok;
bool finished = false;
CallData::CallStatus status = CallData::CallStatus::CREATE;
while (status != CallData::CallStatus::TERMINATE)
{
// Block waiting to read the next event from the completion queue. The
// event is uniquely identified by its tag, which in this case is the
// memory address of a CallData instance.
// The return value of Next should always be checked. This return value
// tells us whether there is any kind of event or cq_ is shutting down.
grpc::CompletionQueue::NextStatus nextStatus = cq_->AsyncNext(&tag, &ok, gpr_now(GPR_CLOCK_MONOTONIC));
if (nextStatus == grpc::CompletionQueue::NextStatus::GOT_EVENT)
{
//GPR_ASSERT(cq_->Next(&tag, &ok));
GPR_ASSERT(ok);
status = static_cast<CallData*>(tag)->Proceed();
}
}
}
std::unique_ptr<ServerCompletionQueue> cq_;
PyBulletAPI::AsyncService service_;
std::unique_ptr<Server> server_;
};
int main(int argc, char** argv)
{
b3CommandLineArgs parseArgs(argc, argv);
b3Clock clock;
double timeOutInSeconds = 10;
DummyGUIHelper guiHelper;
MyCommandProcessor* sm = new MyCommandProcessor;
sm->setGuiHelper(&guiHelper);
int port = 6667;
parseArgs.GetCmdLineArgument("port", port);
std::string hostName = "localhost";
std::string hostNamePort = hostName;
if (port >= 0)
{
hostNamePort += ":" + std::to_string(port);
}
gVerboseNetworkMessagesServer = parseArgs.CheckCmdLineFlag("verbose");
#ifndef NO_SHARED_MEMORY
int key = 0;
if (parseArgs.GetCmdLineArgument("sharedMemoryKey", key))
{
sm->setSharedMemoryKey(key);
}
#endif //NO_SHARED_MEMORY
bool isPhysicsClientConnected = sm->connect();
bool exitRequested = false;
if (isPhysicsClientConnected)
{
ServerImpl server;
server.Run(sm, hostNamePort);
}
else
{
printf("Couldn't connect to physics server\n");
}
delete sm;
return 0;
}

View file

@ -0,0 +1,128 @@
project ("App_PhysicsServerSharedMemoryBridgeGRPC")
language "C++"
kind "ConsoleApp"
includedirs {"../../../src",".."}
initGRPC()
links {
"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",
"../../Utils/b3Clock.cpp",
"../../Utils/b3Clock.h",
}
project "App_PhysicsServerGRPC"
if _OPTIONS["ios"] then
kind "WindowedApp"
else
kind "ConsoleApp"
end
defines { "NO_SHARED_MEMORY" }
includedirs {"..","../../../src", "../../ThirdPartyLibs","../../ThirdPartyLibs/clsocket/src"}
links {
"clsocket","Bullet3Common","BulletInverseDynamicsUtils", "BulletInverseDynamics", "BulletSoftBody", "BulletDynamics","BulletCollision", "LinearMath", "BussIK"
}
initGRPC()
language "C++"
myfiles =
{
"../IKTrajectoryHelper.cpp",
"../IKTrajectoryHelper.h",
"../SharedMemoryCommands.h",
"../SharedMemoryPublic.h",
"../PhysicsServerCommandProcessor.cpp",
"../PhysicsServerCommandProcessor.h",
"../b3PluginManager.cpp",
"../PhysicsDirect.cpp",
"../PhysicsClientC_API.cpp",
"../PhysicsClient.cpp",
"../plugins/collisionFilterPlugin/collisionFilterPlugin.cpp",
"../plugins/pdControlPlugin/pdControlPlugin.cpp",
"../plugins/pdControlPlugin/pdControlPlugin.h",
"../b3RobotSimulatorClientAPI_NoDirect.cpp",
"../b3RobotSimulatorClientAPI_NoDirect.h",
"../plugins/tinyRendererPlugin/tinyRendererPlugin.cpp",
"../plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp",
"../../TinyRenderer/geometry.cpp",
"../../TinyRenderer/model.cpp",
"../../TinyRenderer/tgaimage.cpp",
"../../TinyRenderer/our_gl.cpp",
"../../TinyRenderer/TinyRenderer.cpp",
"../../OpenGLWindow/SimpleCamera.cpp",
"../../OpenGLWindow/SimpleCamera.h",
"../../Importers/ImportURDFDemo/ConvertRigidBodies2MultiBody.h",
"../../Importers/ImportURDFDemo/MultiBodyCreationInterface.h",
"../../Importers/ImportURDFDemo/MyMultiBodyCreator.cpp",
"../../Importers/ImportURDFDemo/MyMultiBodyCreator.h",
"../../Importers/ImportMJCFDemo/BulletMJCFImporter.cpp",
"../../Importers/ImportMJCFDemo/BulletMJCFImporter.h",
"../../Importers/ImportURDFDemo/BulletUrdfImporter.cpp",
"../../Importers/ImportURDFDemo/BulletUrdfImporter.h",
"../../Importers/ImportURDFDemo/UrdfParser.cpp",
"../../Importers/ImportURDFDemo/urdfStringSplit.cpp",
"../../Importers/ImportURDFDemo/UrdfParser.cpp",
"../../Importers/ImportURDFDemo/UrdfParser.h",
"../../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../../Importers/ImportURDFDemo/URDF2Bullet.h",
"../../Utils/b3ResourcePath.cpp",
"../../Utils/b3Clock.cpp",
"../../Utils/ChromeTraceUtil.cpp",
"../../Utils/ChromeTraceUtil.h",
"../../Utils/RobotLoggingUtil.cpp",
"../../Utils/RobotLoggingUtil.h",
"../../../Extras/Serialize/BulletWorldImporter/*",
"../../../Extras/Serialize/BulletFileLoader/*",
"../../Importers/ImportURDFDemo/URDFImporterInterface.h",
"../../Importers/ImportURDFDemo/URDFJointTypes.h",
"../../Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp",
"../../Importers/ImportObjDemo/LoadMeshFromObj.cpp",
"../../Importers/ImportSTLDemo/ImportSTLSetup.h",
"../../Importers/ImportSTLDemo/LoadMeshFromSTL.h",
"../../Importers/ImportColladaDemo/LoadMeshFromCollada.cpp",
"../../Importers/ImportColladaDemo/ColladaGraphicsInstance.h",
"../../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp",
"../../ThirdPartyLibs/tinyxml2/tinyxml2.cpp",
"../../Importers/ImportMeshUtility/b3ImportMeshUtility.cpp",
"../../ThirdPartyLibs/stb_image/stb_image.cpp",
}
files {
myfiles,
"main.cpp",
}

View file

@ -0,0 +1,16 @@
del pybullet.pb.cpp
del pybullet.pb.h
del pybullet.grpc.pb.cpp
del pybullet.grpc.pb.h
..\..\..\ThirdPartyLibs\grpc\lib\win32\protoc --proto_path=. --cpp_out=. pybullet.proto
..\..\..\ThirdPartyLibs\grpc\lib\win32\protoc.exe --plugin=protoc-gen-grpc="..\..\..\ThirdPartyLibs\grpc\lib\win32\grpc_cpp_plugin.exe" --grpc_out=. pybullet.proto
rename pybullet.grpc.pb.cc pybullet.grpc.pb.cpp
rename pybullet.pb.cc pybullet.pb.cpp
del pybullet_pb2.py
del pybullet_pb2_grpc.py
..\..\..\ThirdPartyLibs\grpc\lib\win32\protoc --proto_path=. --python_out=. pybullet.proto
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. pybullet.proto

View file

@ -0,0 +1,15 @@
rm pybullet.pb.cpp
rm pybullet.pb.h
rm pybullet.grpc.pb.cpp
rm pybullet.grpc.pb.h
protoc --proto_path=. --cpp_out=. pybullet.proto
protoc --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` --grpc_out=. pybullet.proto
mv pybullet.grpc.pb.cc pybullet.grpc.pb.cpp
mv pybullet.pb.cc pybullet.pb.cpp
rm pybullet_pb2.py
rm pybullet_pb2_grpc.py
protoc --proto_path=. --python_out=. pybullet.proto
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. pybullet.proto

View file

@ -0,0 +1,467 @@
syntax = "proto3";
//for why oneof everywhere, see the sad decision here:
//https://github.com/protocolbuffers/protobuf/issues/1606
option java_multiple_files = true;
option java_package = "io.grpc.pybullet_grpc";
option java_outer_classname = "PyBulletProto";
option objc_class_prefix = "PBG";
package pybullet_grpc;
service PyBulletAPI {
// Sends a greeting
rpc SubmitCommand (PyBulletCommand) returns (PyBulletStatus) {}
}
message vec3
{
double x=1;
double y=2;
double z=3;
};
message quat4
{
double x=1;
double y=2;
double z=3;
double w=4;
};
message vec4
{
double x=1;
double y=2;
double z=3;
double w=4;
};
message transform
{
vec3 origin=1;
quat4 orientation=2;
};
message matrix4x4
{
//assume 16 elements, with translation in 12,13,14,
//'right' vector is elements 0,1,3 and 4
repeated double elems=1;
};
message CheckVersionCommand
{
int32 clientVersion=1;
};
message CheckVersionStatus
{
int32 serverVersion=1;
};
message TerminateServerCommand
{
string exitReason=1;
};
message StepSimulationCommand
{
};
message SyncBodiesCommand
{
};
message SyncBodiesStatus
{
repeated int32 bodyUniqueIds=1;
repeated int32 userConstraintUniqueIds=2;
};
message RequestBodyInfoCommand
{
int32 bodyUniqueId=1;
};
message RequestBodyInfoStatus
{
int32 bodyUniqueId=1;
string bodyName=2;
};
message LoadUrdfCommand {
string fileName=1;
vec3 initialPosition=2;
quat4 initialOrientation=3;
//for why oneof here, see the sad decision here:
//https://github.com/protocolbuffers/protobuf/issues/1606
oneof hasUseMultiBody { int32 useMultiBody=4; }
oneof hasUseFixedBase{ bool useFixedBase=5; }
int32 flags=6;
oneof hasGlobalScaling { double globalScaling=7;
}
};
message LoadUrdfStatus {
int32 bodyUniqueId=1;
string bodyName=2;
string fileName=3;
}
message LoadSdfCommand {
string fileName=1;
oneof hasUseMultiBody { int32 useMultiBody=2; }
oneof hasGlobalScaling { double globalScaling=3;
}
};
message SdfLoadedStatus
{
repeated int32 bodyUniqueIds=2;
}
message LoadMjcfCommand {
string fileName=1;
int32 flags=2;
};
message MjcfLoadedStatus
{
repeated int32 bodyUniqueIds=2;
}
message ChangeDynamicsCommand
{
int32 bodyUniqueId=1;
int32 linkIndex=2;
oneof hasMass { double mass=3;}
oneof hasLateralFriction { double lateralFriction=5;}
oneof hasSpinningFriction {double spinningFriction=6;}
oneof hasRollingFriction {double rollingFriction=7;}
oneof hasRestitution { double restitution=8;}
oneof haslinearDamping { double linearDamping=9;}
oneof hasangularDamping { double angularDamping=10;}
oneof hasContactStiffness { double contactStiffness=11;}
oneof hasContactDamping { double contactDamping=12;}
oneof hasLocalInertiaDiagonal { vec3 localInertiaDiagonal=13;}
oneof hasFrictionAnchor { int32 frictionAnchor=14;}
oneof hasccdSweptSphereRadius { double ccdSweptSphereRadius=15;}
oneof hasContactProcessingThreshold { double contactProcessingThreshold=16;}
oneof hasActivationState { int32 activationState=17;}
};
message GetDynamicsCommand
{
int32 bodyUniqueId=1;
int32 linkIndex=2;
};
message GetDynamicsStatus
{
double mass=3;
double lateralFriction=5;
double spinningFriction=6;
double rollingFriction=7;
double restitution=8;
double linearDamping=9;
double angularDamping=10;
double contactStiffness=11;
double contactDamping=12;
vec3 localInertiaDiagonal=13;
int32 frictionAnchor=14;
double ccdSweptSphereRadius=15;
double contactProcessingThreshold=16;
int32 activationState=17;
};
message InitPoseCommand
{
int32 bodyUniqueId=1;
int32 updateflags=2;
repeated int32 hasInitialStateQ=3;
repeated double initialStateQ=4;
repeated int32 hasInitialStateQdot=5;
repeated double initialStateQdot=6;
};
message RequestActualStateCommand
{
int32 bodyUniqueId=1;
bool computeForwardKinematics=2;
bool computeLinkVelocities=3;
};
message SendActualStateStatus
{
int32 bodyUniqueId=1;
int32 numLinks=2;
int32 numDegreeOfFreedomQ=3;
int32 numDegreeOfFreedomU=4;
repeated double rootLocalInertialFrame=5;
//actual state is only written by the server, read-only access by client is expected
repeated double actualStateQ=6;
repeated double actualStateQdot=7;
//measured 6DOF force/torque sensors: force[x,y,z] and torque[x,y,z]
repeated double jointReactionForces=8;
repeated double jointMotorForce=9;
repeated double linkState=10;
repeated double linkWorldVelocities=11;//linear velocity and angular velocity in world space (x/y/z each).
repeated double linkLocalInertialFrames=12;
};
message ConfigureOpenGLVisualizerCommand
{
int32 updateFlags=1;
double cameraDistance=2;
double cameraPitch=3;
double cameraYaw=4;
vec3 cameraTargetPosition=5;
int32 setFlag=6;
int32 setEnabled=7;
};
message PhysicsSimulationParameters
{
double deltaTime=1;
vec3 gravityAcceleration=2;
int32 numSimulationSubSteps=3;
int32 numSolverIterations=4;
int32 useRealTimeSimulation=5;
int32 useSplitImpulse=6;
double splitImpulsePenetrationThreshold=7;
double contactBreakingThreshold=8;
int32 internalSimFlags=9;
double defaultContactERP=10;
int32 collisionFilterMode=11;
int32 enableFileCaching=12;
double restitutionVelocityThreshold=13;
double defaultNonContactERP=14;
double frictionERP=15;
double defaultGlobalCFM=16;
double frictionCFM=17;
int32 enableConeFriction=18;
int32 deterministicOverlappingPairs=19;
double allowedCcdPenetration=20;
int32 jointFeedbackMode=21;
double solverResidualThreshold=22;
double contactSlop=23;
int32 enableSAT=24;
int32 constraintSolverType=25;
int32 minimumSolverIslandSize=26;
};
message PhysicsSimulationParametersCommand
{
int32 updateFlags=1;
PhysicsSimulationParameters params=2;
};
message JointMotorControlCommand
{
int32 bodyUniqueId=1;
int32 controlMode=2;
int32 updateFlags=3;
//PD parameters in case controlMode == CONTROL_MODE_POSITION_VELOCITY_PD
repeated double Kp=4;//indexed by degree of freedom, 6 for base, and then the dofs for each link
repeated double Kd=5;//indexed by degree of freedom, 6 for base, and then the dofs for each link
repeated double maxVelocity=6;
repeated int32 hasDesiredStateFlags=7;
//desired state is only written by the client, read-only access by server is expected
//desiredStateQ is indexed by position variables,
//starting with 3 base position variables, 4 base orientation variables (quaternion), then link position variables
repeated double desiredStateQ=8;
//desiredStateQdot is index by velocity degrees of freedom, 3 linear and 3 angular variables for the base and then link velocity variables
repeated double desiredStateQdot=9;
//desiredStateForceTorque is either the actual applied force/torque (in CONTROL_MODE_TORQUE) or
//or the maximum applied force/torque for the PD/motor/constraint to reach the desired velocity in CONTROL_MODE_VELOCITY and CONTROL_MODE_POSITION_VELOCITY_PD mode
//indexed by degree of freedom, 6 dof base, and then dofs for each link
repeated double desiredStateForceTorque=10;
};
message UserConstraintCommand
{
int32 parentBodyIndex=1;
int32 parentJointIndex=2;
int32 childBodyIndex=3;
int32 childJointIndex=4;
transform parentFrame=5;
transform childFrame=6;
vec3 jointAxis=7;
int32 jointType=8;
double maxAppliedForce=9;
int32 userConstraintUniqueId=10;
double gearRatio=11;
int32 gearAuxLink=12;
double relativePositionTarget=13;
double erp=14;
int32 updateFlags=15;
};
message UserConstraintStatus
{
double maxAppliedForce=9;
int32 userConstraintUniqueId=10;
};
message UserConstraintStateStatus
{
vec3 appliedConstraintForcesLinear=1;
vec3 appliedConstraintForcesAngular=2;
int32 numDofs=3;
};
message RequestKeyboardEventsCommand
{
};
message KeyboardEvent
{
int32 keyCode=1;//ascii
int32 keyState=2;// see b3VRButtonInfo
};
message KeyboardEventsStatus
{
repeated KeyboardEvent keyboardEvents=1;
};
message RequestCameraImageCommand
{
int32 updateFlags=1;
int32 cameraFlags=2;
matrix4x4 viewMatrix=3;
matrix4x4 projectionMatrix=4;
int32 startPixelIndex=5;
int32 pixelWidth=6;
int32 pixelHeight=7;
vec3 lightDirection=8;
vec3 lightColor=9;
double lightDistance=10;
double lightAmbientCoeff=11;
double lightDiffuseCoeff=12;
double lightSpecularCoeff=13;
int32 hasShadow=14;
matrix4x4 projectiveTextureViewMatrix=15;
matrix4x4 projectiveTextureProjectionMatrix=16;
};
message RequestCameraImageStatus
{
int32 imageWidth=1;
int32 imageHeight=2;
int32 startingPixelIndex=3;
int32 numPixelsCopied=4;
int32 numRemainingPixels=5;
};
message ResetSimulationCommand
{
};
// The request message containing the command
message PyBulletCommand {
int32 commandType=1;
repeated bytes binaryBlob=2;
repeated bytes unknownCommandBinaryBlob=3;
oneof commands {
LoadUrdfCommand loadUrdfCommand = 4;
TerminateServerCommand terminateServerCommand=5;
StepSimulationCommand stepSimulationCommand= 6;
LoadSdfCommand loadSdfCommand=7;
LoadMjcfCommand loadMjcfCommand=8;
ChangeDynamicsCommand changeDynamicsCommand=9;
GetDynamicsCommand getDynamicsCommand=10;
InitPoseCommand initPoseCommand=11;
RequestActualStateCommand requestActualStateCommand=12;
ConfigureOpenGLVisualizerCommand configureOpenGLVisualizerCommand =13;
SyncBodiesCommand syncBodiesCommand=14;
RequestBodyInfoCommand requestBodyInfoCommand=15;
PhysicsSimulationParametersCommand setPhysicsSimulationParametersCommand=16;
JointMotorControlCommand jointMotorControlCommand=17;
UserConstraintCommand userConstraintCommand=18;
CheckVersionCommand checkVersionCommand=19;
RequestKeyboardEventsCommand requestKeyboardEventsCommand=20;
RequestCameraImageCommand requestCameraImageCommand=21;
ResetSimulationCommand resetSimulationCommand=22;
}
}
// The response message containing the status
message PyBulletStatus {
int32 statusType=1;
repeated bytes binaryBlob=2;
repeated bytes unknownStatusBinaryBlob=3;
oneof status
{
LoadUrdfStatus urdfStatus = 4;
SdfLoadedStatus sdfStatus = 5;
MjcfLoadedStatus mjcfStatus = 6;
GetDynamicsStatus getDynamicsStatus = 7;
SendActualStateStatus actualStateStatus = 8;
SyncBodiesStatus syncBodiesStatus=9;
RequestBodyInfoStatus requestBodyInfoStatus = 10;
PhysicsSimulationParameters requestPhysicsSimulationParametersStatus=11;
CheckVersionStatus checkVersionStatus=12;
UserConstraintStatus userConstraintStatus=13;
UserConstraintStateStatus userConstraintStateStatus=14;
KeyboardEventsStatus keyboardEventsStatus=15;
RequestCameraImageStatus requestCameraImageStatus=16;
}
}

View file

@ -0,0 +1,95 @@
"""The Python implementation of the PyBullet GRPC client."""
from __future__ import print_function
import grpc
import pybullet_pb2
import pybullet_pb2_grpc
#todo: how to add this?
MJCF_COLORS_FROM_FILE = 512
def run():
print("grpc.insecure_channel")
channel = grpc.insecure_channel('localhost:6667')
print("pybullet_pb2_grpc.PyBulletAPIStub")
stub = pybullet_pb2_grpc.PyBulletAPIStub(channel)
response = 0
print("submit CheckVersionCommand")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(checkVersionCommand=pybullet_pb2.CheckVersionCommand(
clientVersion=123)))
print("PyBullet client received: ", response)
print("submit_ResetSimulationCommand")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(resetSimulationCommand=pybullet_pb2.ResetSimulationCommand()))
print("PyBullet client received: ", response)
print("submit LoadUrdfCommand ")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(loadUrdfCommand=pybullet_pb2.LoadUrdfCommand(
fileName="door.urdf",
initialPosition=pybullet_pb2.vec3(x=0, y=0, z=0),
useMultiBody=True,
useFixedBase=True,
globalScaling=2,
flags=1)))
print("PyBullet client received: ", response)
bodyUniqueId = response.urdfStatus.bodyUniqueId
print("submit LoadSdfCommand")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(loadSdfCommand=pybullet_pb2.LoadSdfCommand(
fileName="two_cubes.sdf", useMultiBody=True, globalScaling=2)))
print("PyBullet client received: ", response)
print("submit LoadMjcfCommand")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(loadMjcfCommand=pybullet_pb2.LoadMjcfCommand(
fileName="mjcf/humanoid.xml", flags=MJCF_COLORS_FROM_FILE)))
print("PyBullet client received: ", response)
print("submit ChangeDynamicsCommand ")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(changeDynamicsCommand=pybullet_pb2.ChangeDynamicsCommand(
bodyUniqueId=bodyUniqueId, linkIndex=-1, mass=10)))
print("PyBullet client received: ", response)
print("submit GetDynamicsCommand ")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(getDynamicsCommand=pybullet_pb2.GetDynamicsCommand(
bodyUniqueId=bodyUniqueId, linkIndex=-1)))
print("PyBullet client received: ", response)
print("submit InitPoseCommand")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(initPoseCommand=pybullet_pb2.InitPoseCommand(
bodyUniqueId=bodyUniqueId, initialStateQ=[1, 2, 3], hasInitialStateQ=[1, 1, 1])))
print("PyBullet client received: ", response)
print("submit RequestActualStateCommand")
response = stub.SubmitCommand(
pybullet_pb2.
PyBulletCommand(requestActualStateCommand=pybullet_pb2.RequestActualStateCommand(
bodyUniqueId=bodyUniqueId, computeForwardKinematics=True, computeLinkVelocities=True)))
print("PyBullet client received: ", response)
i = 0
while (True):
i = i + 1
print("submit StepSimulationCommand: ", i)
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(stepSimulationCommand=pybullet_pb2.StepSimulationCommand()))
print("PyBullet client received: ", response.statusType)
#print("TerminateServerCommand")
#response = stub.SubmitCommand(pybullet_pb2.PyBulletCommand(terminateServerCommand=pybullet_pb2.TerminateServerCommand()))
#print("PyBullet client received: " , response.statusType)
if __name__ == '__main__':
run()

View file

@ -0,0 +1,94 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2015 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "PhysicsServerExampleBullet2.h"
#include "Bullet3Common/b3CommandLineArgs.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
#include "SharedMemoryCommon.h"
#include <stdlib.h>
int gSharedMemoryKey = -1;
static SharedMemoryCommon* example = NULL;
static bool interrupted = false;
#ifndef _WIN32
#include <signal.h>
#include <err.h>
#include <unistd.h>
static void cleanup(int signo)
{
if (interrupted)
{ // this is the second time, we're hanging somewhere
// if (example) {
// example->abort();
// }
b3Printf("Aborting and deleting SharedMemoryCommon object");
sleep(1);
delete example;
errx(EXIT_FAILURE, "aborted example on signal %d", signo);
}
interrupted = true;
warnx("caught signal %d", signo);
}
#endif //_WIN32
int main(int argc, char* argv[])
{
#ifndef _WIN32
struct sigaction action;
memset(&action, 0x0, sizeof(action));
action.sa_handler = cleanup;
static const int signos[] = {SIGHUP, SIGINT, SIGQUIT, SIGABRT, SIGSEGV, SIGPIPE, SIGTERM};
for (int ii(0); ii < sizeof(signos) / sizeof(*signos); ++ii)
{
if (0 != sigaction(signos[ii], &action, NULL))
{
err(EXIT_FAILURE, "signal %d", signos[ii]);
}
}
#endif
b3CommandLineArgs args(argc, argv);
DummyGUIHelper noGfx;
CommonExampleOptions options(&noGfx);
args.GetCmdLineArgument("shared_memory_key", gSharedMemoryKey);
args.GetCmdLineArgument("sharedMemoryKey", gSharedMemoryKey);
// options.m_option |= PHYSICS_SERVER_ENABLE_COMMAND_LOGGING;
// options.m_option |= PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG;
example = (SharedMemoryCommon*)PhysicsServerCreateFuncBullet2(options);
example->initPhysics();
while (example->isConnected() && !(example->wantsTermination() || interrupted))
{
example->stepSimulation(1.f / 60.f);
}
example->exitPhysics();
delete example;
return 0;
}

Some files were not shown because too many files have changed in this diff Show more