From c3b7f39aaf37eaa5069f1395cc3ffcce41c47794 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Wed, 19 Jun 2019 09:01:16 -0700 Subject: [PATCH 1/2] expose shadowMapResolution (texture resolution) and shadowMapWorldSize (size in meters in world space) expose pybullet.ConfigureOpenGLVisualizerRequest(lightPosition=[x,y,z], shadowMapWorldSize=10.5, shadowMapResolution=16384) See examples/pybullet/examples/configureDebugVisualizer.py for an example. This reimplements https://github.com/bulletphysics/bullet3/pull/2295 but without creating a new command/status and explicitly referring to the debug visualizer (since the 'getCameraImage' also has a lightPosition) --- .../CommonInterfaces/CommonRenderInterface.h | 3 + .../OpenGLWindow/GLInstancingRenderer.cpp | 60 ++++++++++++++----- examples/OpenGLWindow/GLInstancingRenderer.h | 2 + examples/OpenGLWindow/SimpleOpenGL2Renderer.h | 3 +- .../GraphicsSharedMemoryCommands.h | 2 +- examples/SharedMemory/PhysicsClientC_API.cpp | 39 ++++++++++++ examples/SharedMemory/PhysicsClientC_API.h | 4 ++ .../PhysicsServerCommandProcessor.cpp | 16 +++++ examples/SharedMemory/SharedMemoryCommands.h | 7 ++- .../examples/configureDebugVisualizer.py | 20 +++++++ examples/pybullet/pybullet.c | 34 +++++++++-- 11 files changed, 166 insertions(+), 24 deletions(-) create mode 100644 examples/pybullet/examples/configureDebugVisualizer.py diff --git a/examples/CommonInterfaces/CommonRenderInterface.h b/examples/CommonInterfaces/CommonRenderInterface.h index 3acf416b8..37787ab4b 100644 --- a/examples/CommonInterfaces/CommonRenderInterface.h +++ b/examples/CommonInterfaces/CommonRenderInterface.h @@ -49,6 +49,9 @@ struct CommonRenderInterface virtual void setLightPosition(const float lightPos[3]) = 0; virtual void setLightPosition(const double lightPos[3]) = 0; + virtual void setShadowMapResolution(int shadowMapResolution) = 0; + virtual void setShadowMapWorldSize(float worldSize) = 0; + virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]){}; virtual void setProjectiveTexture(bool useProjectiveTexture){}; diff --git a/examples/OpenGLWindow/GLInstancingRenderer.cpp b/examples/OpenGLWindow/GLInstancingRenderer.cpp index ef8bc68c1..809d87b1f 100644 --- a/examples/OpenGLWindow/GLInstancingRenderer.cpp +++ b/examples/OpenGLWindow/GLInstancingRenderer.cpp @@ -16,9 +16,8 @@ subject to the following restrictions: ///todo: make this configurable in the gui bool useShadowMap = true; // true;//false;//true; -int shadowMapWidth = 4096; -int shadowMapHeight = 4096; -float shadowMapWorldSize = 10; + + #include struct caster2 @@ -244,11 +243,22 @@ struct InternalDataRenderer : public GLInstanceRendererInternalData b3ResizablePool m_publicGraphicsInstances; + int m_shadowMapWidth; + int m_shadowMapHeight; + float m_shadowMapWorldSize; + bool m_updateShadowMap; + InternalDataRenderer() : m_activeCamera(&m_defaultCamera1), m_shadowMap(0), m_shadowTexture(0), - m_renderFrameBuffer(0) + m_renderFrameBuffer(0), + m_shadowMapWidth(4096), + m_shadowMapHeight(4096), + m_shadowMapWorldSize(10), + m_updateShadowMap(true) + { + m_lightPos = b3MakeVector3(-50, 30, 40); m_lightSpecularIntensity.setValue(1, 1, 1); @@ -1449,6 +1459,19 @@ void GLInstancingRenderer::setLightPosition(const float lightPos[3]) m_data->m_lightPos[2] = lightPos[2]; } +void GLInstancingRenderer::setShadowMapResolution(int shadowMapResolution) +{ + m_data->m_shadowMapWidth = shadowMapResolution; + m_data->m_shadowMapHeight = shadowMapResolution; + m_data->m_updateShadowMap = true; +} + +void GLInstancingRenderer::setShadowMapWorldSize(float worldSize) +{ + m_data->m_shadowMapWorldSize = worldSize; + m_data->m_updateShadowMap = true; +} + void GLInstancingRenderer::setLightPosition(const double lightPos[3]) { m_data->m_lightPos[0] = lightPos[0]; @@ -2071,6 +2094,13 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode) glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); + if (m_data->m_shadowMap && m_data->m_updateShadowMap) + { + m_data->m_updateShadowMap = false; + glDeleteTextures(1, &m_data->m_shadowTexture); + delete m_data->m_shadowMap; + m_data->m_shadowMap = 0; + } if (!m_data->m_shadowMap) { glActiveTexture(GL_TEXTURE0); @@ -2088,27 +2118,27 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode) int size; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); - if (size < shadowMapWidth) + if (size < m_data->m_shadowMapWidth) { - shadowMapWidth = size; + m_data->m_shadowMapWidth = size; } - if (size < shadowMapHeight) + if (size < m_data->m_shadowMapHeight) { - shadowMapHeight = size; + m_data->m_shadowMapHeight = size; } GLuint err; do { glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, - shadowMapWidth, shadowMapHeight, + m_data->m_shadowMapWidth, m_data->m_shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); err = glGetError(); if (err != GL_NO_ERROR) { - shadowMapHeight >>= 1; - shadowMapWidth >>= 1; + m_data->m_shadowMapHeight >>= 1; + m_data->m_shadowMapWidth >>= 1; } - } while (err != GL_NO_ERROR && shadowMapWidth > 0); + } while (err != GL_NO_ERROR && m_data->m_shadowMapWidth > 0); #endif //OLD_SHADOWMAP_INIT glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -2124,10 +2154,10 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); m_data->m_shadowMap = new GLRenderToTexture(); - m_data->m_shadowMap->init(shadowMapWidth, shadowMapHeight, m_data->m_shadowTexture, RENDERTEXTURE_DEPTH); + m_data->m_shadowMap->init(m_data->m_shadowMapWidth, m_data->m_shadowMapHeight, m_data->m_shadowTexture, RENDERTEXTURE_DEPTH); } m_data->m_shadowMap->enable(); - glViewport(0, 0, shadowMapWidth, shadowMapHeight); + glViewport(0, 0, m_data->m_shadowMapWidth, m_data->m_shadowMapHeight); //glClearColor(1,1,1,1); glClear(GL_DEPTH_BUFFER_BIT); //glClearColor(0.3,0.3,0.3,1); @@ -2145,7 +2175,7 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode) glCullFace(GL_BACK); } - b3CreateOrtho(-shadowMapWorldSize, shadowMapWorldSize, -shadowMapWorldSize, shadowMapWorldSize, 1, 300, depthProjectionMatrix); //-14,14,-14,14,1,200, depthProjectionMatrix); + b3CreateOrtho(-m_data->m_shadowMapWorldSize, m_data->m_shadowMapWorldSize, -m_data->m_shadowMapWorldSize, m_data->m_shadowMapWorldSize, 1, 300, depthProjectionMatrix); //-14,14,-14,14,1,200, depthProjectionMatrix); float depthViewMatrix[4][4]; b3Vector3 center = b3MakeVector3(0, 0, 0); m_data->m_activeCamera->getCameraTargetPosition(center); diff --git a/examples/OpenGLWindow/GLInstancingRenderer.h b/examples/OpenGLWindow/GLInstancingRenderer.h index d5c14fc53..821da5263 100644 --- a/examples/OpenGLWindow/GLInstancingRenderer.h +++ b/examples/OpenGLWindow/GLInstancingRenderer.h @@ -120,6 +120,8 @@ public: virtual void setLightPosition(const float lightPos[3]); virtual void setLightPosition(const double lightPos[3]); + virtual void setShadowMapResolution(int shadowMapResolution); + virtual void setShadowMapWorldSize(float worldSize); void setLightSpecularIntensity(const float lightSpecularIntensity[3]); virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]); virtual void setProjectiveTexture(bool useProjectiveTexture); diff --git a/examples/OpenGLWindow/SimpleOpenGL2Renderer.h b/examples/OpenGLWindow/SimpleOpenGL2Renderer.h index f1c30ab24..320184d7c 100644 --- a/examples/OpenGLWindow/SimpleOpenGL2Renderer.h +++ b/examples/OpenGLWindow/SimpleOpenGL2Renderer.h @@ -26,7 +26,8 @@ public: virtual void setLightPosition(const float lightPos[3]); virtual void setLightPosition(const double lightPos[3]); - + virtual void setShadowMapResolution(int shadowMapResolution) {} + virtual void setShadowMapWorldSize(float worldSize) {} virtual void resize(int width, int height); virtual void removeAllInstances(); diff --git a/examples/SharedMemory/GraphicsSharedMemoryCommands.h b/examples/SharedMemory/GraphicsSharedMemoryCommands.h index 7c06c84a5..e72d1d049 100644 --- a/examples/SharedMemory/GraphicsSharedMemoryCommands.h +++ b/examples/SharedMemory/GraphicsSharedMemoryCommands.h @@ -26,7 +26,7 @@ typedef unsigned long long int smUint64a_t; #ifdef __APPLE__ #define GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE (512 * 1024) #else -#define GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE (4 * 1024 * 1024) + #define GRAPHICS_SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE (4 * 1024 * 1024) #endif struct GraphicsCommand0 diff --git a/examples/SharedMemory/PhysicsClientC_API.cpp b/examples/SharedMemory/PhysicsClientC_API.cpp index 4a08c5e6d..4ad76abb4 100644 --- a/examples/SharedMemory/PhysicsClientC_API.cpp +++ b/examples/SharedMemory/PhysicsClientC_API.cpp @@ -5462,6 +5462,45 @@ B3_SHARED_API void b3ConfigureOpenGLVisualizerSetVisualizationFlags(b3SharedMemo } } +B3_SHARED_API void b3ConfigureOpenGLVisualizerSetLightPosition(b3SharedMemoryCommandHandle commandHandle, const float lightPosition[3]) +{ + struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle; + b3Assert(command); + b3Assert(command->m_type == CMD_CONFIGURE_OPENGL_VISUALIZER); + if (command->m_type == CMD_CONFIGURE_OPENGL_VISUALIZER) + { + command->m_updateFlags |= COV_SET_LIGHT_POSITION; + command->m_configureOpenGLVisualizerArguments.m_lightPosition[0] = lightPosition[0]; + command->m_configureOpenGLVisualizerArguments.m_lightPosition[1] = lightPosition[1]; + command->m_configureOpenGLVisualizerArguments.m_lightPosition[2] = lightPosition[2]; + } +} + +B3_SHARED_API void b3ConfigureOpenGLVisualizerSetShadowMapResolution(b3SharedMemoryCommandHandle commandHandle, int shadowMapResolution) +{ + struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle; + b3Assert(command); + b3Assert(command->m_type == CMD_CONFIGURE_OPENGL_VISUALIZER); + if (command->m_type == CMD_CONFIGURE_OPENGL_VISUALIZER) + { + command->m_updateFlags |= COV_SET_SHADOWMAP_RESOLUTION; + command->m_configureOpenGLVisualizerArguments.m_shadowMapResolution = shadowMapResolution; + } +} + +B3_SHARED_API void b3ConfigureOpenGLVisualizerSetShadowMapWorldSize(b3SharedMemoryCommandHandle commandHandle, int shadowMapWorldSize) +{ + struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle; + b3Assert(command); + b3Assert(command->m_type == CMD_CONFIGURE_OPENGL_VISUALIZER); + if (command->m_type == CMD_CONFIGURE_OPENGL_VISUALIZER) + { + command->m_updateFlags |= COV_SET_SHADOWMAP_WORLD_SIZE; + command->m_configureOpenGLVisualizerArguments.m_shadowMapWorldSize = shadowMapWorldSize; + } +} + + B3_SHARED_API void b3ConfigureOpenGLVisualizerSetViewMatrix(b3SharedMemoryCommandHandle commandHandle, float cameraDistance, float cameraPitch, float cameraYaw, const float cameraTargetPosition[3]) { struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle; diff --git a/examples/SharedMemory/PhysicsClientC_API.h b/examples/SharedMemory/PhysicsClientC_API.h index ec50a838a..2ddac17b3 100644 --- a/examples/SharedMemory/PhysicsClientC_API.h +++ b/examples/SharedMemory/PhysicsClientC_API.h @@ -207,6 +207,10 @@ extern "C" 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 b3ConfigureOpenGLVisualizerSetShadowMapWorldSize(b3SharedMemoryCommandHandle commandHandle, int shadowMapWorldSize); + B3_SHARED_API void b3ConfigureOpenGLVisualizerSetViewMatrix(b3SharedMemoryCommandHandle commandHandle, float cameraDistance, float cameraPitch, float cameraYaw, const float cameraTargetPosition[/*3*/]); B3_SHARED_API b3SharedMemoryCommandHandle b3InitRequestOpenGLVisualizerCameraCommand(b3PhysicsClientHandle physClient); diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp index 93a5f1d3d..690c25798 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp @@ -9058,6 +9058,22 @@ bool PhysicsServerCommandProcessor::processConfigureOpenGLVisualizerCommand(cons clientCmd.m_configureOpenGLVisualizerArguments.m_cameraTargetPosition[1], clientCmd.m_configureOpenGLVisualizerArguments.m_cameraTargetPosition[2]); } + if (m_data->m_guiHelper->getRenderInterface()) + { + if (clientCmd.m_updateFlags & COV_SET_LIGHT_POSITION) + { + m_data->m_guiHelper->getRenderInterface()->setLightPosition(clientCmd.m_configureOpenGLVisualizerArguments.m_lightPosition); + } + if (clientCmd.m_updateFlags & COV_SET_SHADOWMAP_RESOLUTION) + { + m_data->m_guiHelper->getRenderInterface()->setShadowMapResolution(clientCmd.m_configureOpenGLVisualizerArguments.m_shadowMapResolution); + } + if (clientCmd.m_updateFlags & COV_SET_SHADOWMAP_WORLD_SIZE) + { + float worldSize = clientCmd.m_configureOpenGLVisualizerArguments.m_shadowMapWorldSize; + m_data->m_guiHelper->getRenderInterface()->setShadowMapWorldSize(worldSize); + } + } return hasStatus; } diff --git a/examples/SharedMemory/SharedMemoryCommands.h b/examples/SharedMemory/SharedMemoryCommands.h index 21aefba50..06ca9ab81 100644 --- a/examples/SharedMemory/SharedMemoryCommands.h +++ b/examples/SharedMemory/SharedMemoryCommands.h @@ -905,6 +905,9 @@ enum InternalOpenGLVisualizerUpdateFlags { COV_SET_CAMERA_VIEW_MATRIX = 1, COV_SET_FLAGS = 2, + COV_SET_LIGHT_POSITION = 4, + COV_SET_SHADOWMAP_RESOLUTION = 8, + COV_SET_SHADOWMAP_WORLD_SIZE = 16, }; struct ConfigureOpenGLVisualizerRequest @@ -913,7 +916,9 @@ struct ConfigureOpenGLVisualizerRequest double m_cameraPitch; double m_cameraYaw; double m_cameraTargetPosition[3]; - + double m_lightPosition[3]; + int m_shadowMapResolution; + int m_shadowMapWorldSize; int m_setFlag; int m_setEnabled; }; diff --git a/examples/pybullet/examples/configureDebugVisualizer.py b/examples/pybullet/examples/configureDebugVisualizer.py new file mode 100644 index 000000000..e307504d3 --- /dev/null +++ b/examples/pybullet/examples/configureDebugVisualizer.py @@ -0,0 +1,20 @@ +import pybullet as p +import math +import time +dt = 1./240. + +p.connect(p.GUI) +p.loadURDF("r2d2.urdf",[0,0,1]) +p.loadURDF("plane.urdf") +p.setGravity(0,0,-10) + +radius=5 +t = 0 +p.configureDebugVisualizer(shadowMapWorldSize=5) +p.configureDebugVisualizer(shadowMapResolution=8192) +while (1): + t+=dt + p.configureDebugVisualizer(lightPosition=[radius*math.sin(t),radius*math.cos(t),3]) + + p.stepSimulation() + time.sleep(dt) \ No newline at end of file diff --git a/examples/pybullet/pybullet.c b/examples/pybullet/pybullet.c index 5ee53bd5c..cf8afeb1d 100644 --- a/examples/pybullet/pybullet.c +++ b/examples/pybullet/pybullet.c @@ -5869,15 +5869,17 @@ static PyObject* pybullet_getDebugVisualizerCamera(PyObject* self, PyObject* arg static PyObject* pybullet_configureDebugVisualizer(PyObject* self, PyObject* args, PyObject* keywds) { - int flag = 1; + int flag = -1; int enable = -1; - + int shadowMapResolution = -1; + int shadowMapWorldSize = -1; int physicsClientId = 0; + PyObject* pyLightPosition = 0; b3PhysicsClientHandle sm = 0; - static char* kwlist[] = {"flag", "enable", "physicsClientId", NULL}; + static char* kwlist[] = {"flag", "enable", "lightPosition", "shadowMapResolution", "shadowMapWorldSize", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "ii|i", kwlist, - &flag, &enable, &physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "|iiOiii", kwlist, + &flag, &enable, &pyLightPosition, &shadowMapResolution, &shadowMapWorldSize, &physicsClientId)) return NULL; sm = getPhysicsClient(physicsClientId); @@ -5889,7 +5891,27 @@ static PyObject* pybullet_configureDebugVisualizer(PyObject* self, PyObject* arg { b3SharedMemoryCommandHandle commandHandle = b3InitConfigureOpenGLVisualizer(sm); - b3ConfigureOpenGLVisualizerSetVisualizationFlags(commandHandle, flag, enable); + if (flag >= 0) + { + b3ConfigureOpenGLVisualizerSetVisualizationFlags(commandHandle, flag, enable); + } + if (pyLightPosition) + { + float lightPosition[3]; + if (pybullet_internalSetVector(pyLightPosition, lightPosition)) + { + b3ConfigureOpenGLVisualizerSetLightPosition(commandHandle, lightPosition); + } + } + if (shadowMapResolution > 0) + { + b3ConfigureOpenGLVisualizerSetShadowMapResolution(commandHandle, shadowMapResolution); + } + if (shadowMapWorldSize > 0) + { + b3ConfigureOpenGLVisualizerSetShadowMapWorldSize(commandHandle, shadowMapWorldSize); + } + b3SubmitClientCommandAndWaitStatus(sm, commandHandle); } Py_INCREF(Py_None); From ed4515ae17cbc45289052d183b3d8920c2835ebf Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Wed, 19 Jun 2019 09:45:29 -0700 Subject: [PATCH 2/2] for the GraphicsServer, expose a sync transform interval: only synchronize the transform once the stepSimulation exceeds this time interval. (for example, run the simulation at 1kHz but sync the graphics transforms to remove graphics server at 30Hz) --- examples/SharedMemory/PhysicsClientC_API.cpp | 13 ++ examples/SharedMemory/PhysicsClientC_API.h | 1 + .../PhysicsServerCommandProcessor.cpp | 174 ++++++++++-------- examples/SharedMemory/SharedMemoryCommands.h | 2 + .../examples/configureDebugVisualizer.py | 1 + examples/pybullet/pybullet.c | 11 +- 6 files changed, 120 insertions(+), 82 deletions(-) diff --git a/examples/SharedMemory/PhysicsClientC_API.cpp b/examples/SharedMemory/PhysicsClientC_API.cpp index 4ad76abb4..24d690713 100644 --- a/examples/SharedMemory/PhysicsClientC_API.cpp +++ b/examples/SharedMemory/PhysicsClientC_API.cpp @@ -5501,6 +5501,19 @@ B3_SHARED_API void b3ConfigureOpenGLVisualizerSetShadowMapWorldSize(b3SharedMemo } +B3_SHARED_API void b3ConfigureOpenGLVisualizerSetRemoteSyncTransformInterval(b3SharedMemoryCommandHandle commandHandle, double remoteSyncTransformInterval) +{ + struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle; + b3Assert(command); + b3Assert(command->m_type == CMD_CONFIGURE_OPENGL_VISUALIZER); + if (command->m_type == CMD_CONFIGURE_OPENGL_VISUALIZER) + { + command->m_updateFlags |= COV_SET_REMOTE_SYNC_TRANSFORM_INTERVAL; + command->m_configureOpenGLVisualizerArguments.m_remoteSyncTransformInterval = remoteSyncTransformInterval; + } +} + + B3_SHARED_API void b3ConfigureOpenGLVisualizerSetViewMatrix(b3SharedMemoryCommandHandle commandHandle, float cameraDistance, float cameraPitch, float cameraYaw, const float cameraTargetPosition[3]) { struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle; diff --git a/examples/SharedMemory/PhysicsClientC_API.h b/examples/SharedMemory/PhysicsClientC_API.h index 2ddac17b3..406b949ef 100644 --- a/examples/SharedMemory/PhysicsClientC_API.h +++ b/examples/SharedMemory/PhysicsClientC_API.h @@ -210,6 +210,7 @@ extern "C" B3_SHARED_API void b3ConfigureOpenGLVisualizerSetLightPosition(b3SharedMemoryCommandHandle commandHandle, const float lightPosition[3]); B3_SHARED_API void b3ConfigureOpenGLVisualizerSetShadowMapResolution(b3SharedMemoryCommandHandle commandHandle, int shadowMapResolution); 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*/]); diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp index 690c25798..33c47e493 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp @@ -1595,7 +1595,7 @@ struct PhysicsServerCommandProcessorInternalData btScalar m_physicsDeltaTime; btScalar m_numSimulationSubSteps; - btScalar m_simulationTimestamp; + btScalar m_simulationTimestamp; btAlignedObjectArray m_multiBodyJointFeedbacks; b3HashMap m_inverseDynamicsBodies; b3HashMap m_inverseKinematicsHelpers; @@ -1672,6 +1672,9 @@ struct PhysicsServerCommandProcessorInternalData b3ThreadPool* m_threadPool; btScalar m_defaultCollisionMargin; + double m_remoteSyncTransformTime; + double m_remoteSyncTransformInterval; + PhysicsServerCommandProcessorInternalData(PhysicsCommandProcessorInterface* proc) : m_pluginManager(proc), m_useRealTimeSimulation(false), @@ -1681,7 +1684,7 @@ struct PhysicsServerCommandProcessorInternalData m_logPlaybackUid(-1), m_physicsDeltaTime(1. / 240.), m_numSimulationSubSteps(0), - m_simulationTimestamp(0), + m_simulationTimestamp(0), m_userConstraintUIDGenerator(1), m_broadphaseCollisionFilterCallback(0), m_pairCache(0), @@ -1705,72 +1708,72 @@ struct PhysicsServerCommandProcessorInternalData m_collisionFilterPlugin(-1), m_grpcPlugin(-1), m_threadPool(0), - m_defaultCollisionMargin(0.001) + m_defaultCollisionMargin(0.001), + m_remoteSyncTransformTime(1. / 30.), + m_remoteSyncTransformInterval(1. / 30.) { { //register static plugins: #ifdef STATIC_LINK_VR_PLUGIN - b3PluginFunctions funcs(initPlugin_vrSyncPlugin,exitPlugin_vrSyncPlugin, executePluginCommand_vrSyncPlugin); + b3PluginFunctions funcs(initPlugin_vrSyncPlugin, exitPlugin_vrSyncPlugin, executePluginCommand_vrSyncPlugin); funcs.m_preTickFunc = preTickPluginCallback_vrSyncPlugin; m_pluginManager.registerStaticLinkedPlugin("vrSyncPlugin", funcs); #endif //STATIC_LINK_VR_PLUGIN } #ifndef SKIP_STATIC_PD_CONTROL_PLUGIN - { - //int b3PluginManager::registerStaticLinkedPlugin(const char* pluginPath, PFN_INIT initFunc, PFN_EXIT exitFunc, PFN_EXECUTE executeCommandFunc, PFN_TICK preTickFunc, PFN_TICK postTickFunc, PFN_GET_RENDER_INTERFACE getRendererFunc, PFN_TICK processClientCommandsFunc, PFN_GET_COLLISION_INTERFACE getCollisionFunc, bool initPlugin) - b3PluginFunctions funcs(initPlugin_pdControlPlugin,exitPlugin_pdControlPlugin,executePluginCommand_pdControlPlugin); - funcs.m_preTickFunc = preTickPluginCallback_pdControlPlugin; - m_pdControlPlugin = m_pluginManager.registerStaticLinkedPlugin("pdControlPlugin", funcs); - } + { + //int b3PluginManager::registerStaticLinkedPlugin(const char* pluginPath, PFN_INIT initFunc, PFN_EXIT exitFunc, PFN_EXECUTE executeCommandFunc, PFN_TICK preTickFunc, PFN_TICK postTickFunc, PFN_GET_RENDER_INTERFACE getRendererFunc, PFN_TICK processClientCommandsFunc, PFN_GET_COLLISION_INTERFACE getCollisionFunc, bool initPlugin) + b3PluginFunctions funcs(initPlugin_pdControlPlugin, exitPlugin_pdControlPlugin, executePluginCommand_pdControlPlugin); + funcs.m_preTickFunc = preTickPluginCallback_pdControlPlugin; + m_pdControlPlugin = m_pluginManager.registerStaticLinkedPlugin("pdControlPlugin", funcs); + } #endif //SKIP_STATIC_PD_CONTROL_PLUGIN #ifndef SKIP_COLLISION_FILTER_PLUGIN - { - b3PluginFunctions funcs(initPlugin_collisionFilterPlugin,exitPlugin_collisionFilterPlugin, executePluginCommand_collisionFilterPlugin); - funcs.m_getCollisionFunc = getCollisionInterface_collisionFilterPlugin; - m_collisionFilterPlugin = m_pluginManager.registerStaticLinkedPlugin("collisionFilterPlugin", funcs ); - m_pluginManager.selectCollisionPlugin(m_collisionFilterPlugin); - } + { + b3PluginFunctions funcs(initPlugin_collisionFilterPlugin, exitPlugin_collisionFilterPlugin, executePluginCommand_collisionFilterPlugin); + funcs.m_getCollisionFunc = getCollisionInterface_collisionFilterPlugin; + m_collisionFilterPlugin = m_pluginManager.registerStaticLinkedPlugin("collisionFilterPlugin", funcs); + m_pluginManager.selectCollisionPlugin(m_collisionFilterPlugin); + } #endif #ifdef ENABLE_STATIC_GRPC_PLUGIN - { - b3PluginFunctions funcs(initPlugin_grpcPlugin, exitPlugin_grpcPlugin, executePluginCommand_grpcPlugin); - funcs.m_processClientCommandsFunc = processClientCommands_grpcPlugin; - m_grpcPlugin = m_pluginManager.registerStaticLinkedPlugin("grpcPlugin", funcs); - } + { + b3PluginFunctions funcs(initPlugin_grpcPlugin, exitPlugin_grpcPlugin, executePluginCommand_grpcPlugin); + funcs.m_processClientCommandsFunc = processClientCommands_grpcPlugin; + m_grpcPlugin = m_pluginManager.registerStaticLinkedPlugin("grpcPlugin", funcs); + } #endif //ENABLE_STATIC_GRPC_PLUGIN #ifdef STATIC_EGLRENDERER_PLUGIN - { - bool initPlugin = false; - b3PluginFunctions funcs(initPlugin_eglRendererPlugin, exitPlugin_eglRendererPlugin, executePluginCommand_eglRendererPlugin); - funcs.m_getRendererFunc = getRenderInterface_eglRendererPlugin; - int renderPluginId = m_pluginManager.registerStaticLinkedPlugin("eglRendererPlugin", funcs, initPlugin); - m_pluginManager.selectPluginRenderer(renderPluginId); - } + { + bool initPlugin = false; + b3PluginFunctions funcs(initPlugin_eglRendererPlugin, exitPlugin_eglRendererPlugin, executePluginCommand_eglRendererPlugin); + funcs.m_getRendererFunc = getRenderInterface_eglRendererPlugin; + int renderPluginId = m_pluginManager.registerStaticLinkedPlugin("eglRendererPlugin", funcs, initPlugin); + m_pluginManager.selectPluginRenderer(renderPluginId); + } #endif //STATIC_EGLRENDERER_PLUGIN #ifndef SKIP_STATIC_TINYRENDERER_PLUGIN - { - b3PluginFunctions funcs(initPlugin_tinyRendererPlugin, exitPlugin_tinyRendererPlugin, executePluginCommand_tinyRendererPlugin); - funcs.m_getRendererFunc=getRenderInterface_tinyRendererPlugin; - int renderPluginId = m_pluginManager.registerStaticLinkedPlugin("tinyRendererPlugin", funcs); - m_pluginManager.selectPluginRenderer(renderPluginId); - } + { + b3PluginFunctions funcs(initPlugin_tinyRendererPlugin, exitPlugin_tinyRendererPlugin, executePluginCommand_tinyRendererPlugin); + funcs.m_getRendererFunc = getRenderInterface_tinyRendererPlugin; + int renderPluginId = m_pluginManager.registerStaticLinkedPlugin("tinyRendererPlugin", funcs); + m_pluginManager.selectPluginRenderer(renderPluginId); + } #endif #ifdef B3_ENABLE_FILEIO_PLUGIN - { - b3PluginFunctions funcs(initPlugin_fileIOPlugin, exitPlugin_fileIOPlugin, executePluginCommand_fileIOPlugin); - funcs.m_fileIoFunc = getFileIOFunc_fileIOPlugin; - int renderPluginId = m_pluginManager.registerStaticLinkedPlugin("fileIOPlugin", funcs); - m_pluginManager.selectFileIOPlugin(renderPluginId); - } + { + b3PluginFunctions funcs(initPlugin_fileIOPlugin, exitPlugin_fileIOPlugin, executePluginCommand_fileIOPlugin); + funcs.m_fileIoFunc = getFileIOFunc_fileIOPlugin; + int renderPluginId = m_pluginManager.registerStaticLinkedPlugin("fileIOPlugin", funcs); + m_pluginManager.selectFileIOPlugin(renderPluginId); + } #endif - - m_vrControllerEvents.init(); m_bodyHandles.exitHandles(); @@ -1812,7 +1815,7 @@ struct PhysicsServerCommandProcessorInternalData Eigen::VectorXd pose, vel; pose.resize(7 + multiBody->getNumPosVars()); - vel.resize(7 + multiBody->getNumPosVars()); //?? + vel.resize(7 + multiBody->getNumPosVars()); //?? btTransform tr = multiBody->getBaseWorldTransform(); int dofsrc = 0; @@ -1868,49 +1871,48 @@ struct PhysicsServerCommandProcessorInternalData int dof = 7; int veldof = 7; - for (int l = 0; l < multiBody->getNumLinks(); l++) { switch (multiBody->getLink(l).m_jointType) { - case btMultibodyLink::eRevolute: - case btMultibodyLink::ePrismatic: - { - pose[dof++] = jointPositionsQ[dofsrc++]; - vel[veldof++] = jointVelocitiesQdot[velsrcdof++]; - break; - } - case btMultibodyLink::eSpherical: - { - double quatXYZW[4]; - quatXYZW[0] = jointPositionsQ[dofsrc++]; - quatXYZW[1] = jointPositionsQ[dofsrc++]; - quatXYZW[2] = jointPositionsQ[dofsrc++]; - quatXYZW[3] = jointPositionsQ[dofsrc++]; + case btMultibodyLink::eRevolute: + case btMultibodyLink::ePrismatic: + { + pose[dof++] = jointPositionsQ[dofsrc++]; + vel[veldof++] = jointVelocitiesQdot[velsrcdof++]; + break; + } + case btMultibodyLink::eSpherical: + { + double quatXYZW[4]; + quatXYZW[0] = jointPositionsQ[dofsrc++]; + quatXYZW[1] = jointPositionsQ[dofsrc++]; + quatXYZW[2] = jointPositionsQ[dofsrc++]; + quatXYZW[3] = jointPositionsQ[dofsrc++]; - pose[dof++] = quatXYZW[3]; - pose[dof++] = quatXYZW[0]; - pose[dof++] = quatXYZW[1]; - pose[dof++] = quatXYZW[2]; - vel[veldof++] = jointVelocitiesQdot[velsrcdof++]; - vel[veldof++] = jointVelocitiesQdot[velsrcdof++]; - vel[veldof++] = jointVelocitiesQdot[velsrcdof++]; - vel[veldof++] = jointVelocitiesQdot[velsrcdof++]; - break; - } - case btMultibodyLink::eFixed: - { - break; - } - default: - { - assert(0); - } + pose[dof++] = quatXYZW[3]; + pose[dof++] = quatXYZW[0]; + pose[dof++] = quatXYZW[1]; + pose[dof++] = quatXYZW[2]; + vel[veldof++] = jointVelocitiesQdot[velsrcdof++]; + vel[veldof++] = jointVelocitiesQdot[velsrcdof++]; + vel[veldof++] = jointVelocitiesQdot[velsrcdof++]; + vel[veldof++] = jointVelocitiesQdot[velsrcdof++]; + break; + } + case btMultibodyLink::eFixed: + { + break; + } + default: + { + assert(0); + } } } btVector3 gravOrg = m_dynamicsWorld->getGravity(); - tVector grav (gravOrg[0], gravOrg[1], gravOrg[2], 0); + tVector grav(gravOrg[0], gravOrg[1], gravOrg[2], 0); rbdModel->SetGravity(grav); rbdModel->Update(pose, vel); @@ -7763,7 +7765,13 @@ bool PhysicsServerCommandProcessor::processForwardDynamicsCommand(const struct S } serverCmd.m_type = CMD_STEP_FORWARD_SIMULATION_COMPLETED; - syncPhysicsToGraphics2(); + m_data->m_remoteSyncTransformTime += deltaTimeScaled; + if (m_data->m_remoteSyncTransformTime >= m_data->m_remoteSyncTransformInterval) + { + m_data->m_remoteSyncTransformTime = 0; + syncPhysicsToGraphics2(); + } + return hasStatus; } @@ -9074,6 +9082,13 @@ bool PhysicsServerCommandProcessor::processConfigureOpenGLVisualizerCommand(cons m_data->m_guiHelper->getRenderInterface()->setShadowMapWorldSize(worldSize); } } + + if (clientCmd.m_updateFlags & COV_SET_REMOTE_SYNC_TRANSFORM_INTERVAL) + { + m_data->m_remoteSyncTransformInterval = clientCmd.m_configureOpenGLVisualizerArguments.m_remoteSyncTransformInterval; + } + + return hasStatus; } @@ -12047,7 +12062,8 @@ void PhysicsServerCommandProcessor::addTransformChangedNotifications() void PhysicsServerCommandProcessor::resetSimulation() { //clean up all data - + m_data->m_remoteSyncTransformTime = m_data->m_remoteSyncTransformInterval; + m_data->m_simulationTimestamp = 0; m_data->m_cachedVUrdfisualShapes.clear(); diff --git a/examples/SharedMemory/SharedMemoryCommands.h b/examples/SharedMemory/SharedMemoryCommands.h index 06ca9ab81..ed0bfaca7 100644 --- a/examples/SharedMemory/SharedMemoryCommands.h +++ b/examples/SharedMemory/SharedMemoryCommands.h @@ -908,6 +908,7 @@ enum InternalOpenGLVisualizerUpdateFlags COV_SET_LIGHT_POSITION = 4, COV_SET_SHADOWMAP_RESOLUTION = 8, COV_SET_SHADOWMAP_WORLD_SIZE = 16, + COV_SET_REMOTE_SYNC_TRANSFORM_INTERVAL = 32, }; struct ConfigureOpenGLVisualizerRequest @@ -919,6 +920,7 @@ struct ConfigureOpenGLVisualizerRequest double m_lightPosition[3]; int m_shadowMapResolution; int m_shadowMapWorldSize; + double m_remoteSyncTransformInterval; int m_setFlag; int m_setEnabled; }; diff --git a/examples/pybullet/examples/configureDebugVisualizer.py b/examples/pybullet/examples/configureDebugVisualizer.py index e307504d3..e513161b9 100644 --- a/examples/pybullet/examples/configureDebugVisualizer.py +++ b/examples/pybullet/examples/configureDebugVisualizer.py @@ -12,6 +12,7 @@ radius=5 t = 0 p.configureDebugVisualizer(shadowMapWorldSize=5) p.configureDebugVisualizer(shadowMapResolution=8192) + while (1): t+=dt p.configureDebugVisualizer(lightPosition=[radius*math.sin(t),radius*math.cos(t),3]) diff --git a/examples/pybullet/pybullet.c b/examples/pybullet/pybullet.c index cf8afeb1d..a86e3f3c9 100644 --- a/examples/pybullet/pybullet.c +++ b/examples/pybullet/pybullet.c @@ -5874,12 +5874,13 @@ static PyObject* pybullet_configureDebugVisualizer(PyObject* self, PyObject* arg int shadowMapResolution = -1; int shadowMapWorldSize = -1; int physicsClientId = 0; + double remoteSyncTransformInterval = -1; PyObject* pyLightPosition = 0; b3PhysicsClientHandle sm = 0; - static char* kwlist[] = {"flag", "enable", "lightPosition", "shadowMapResolution", "shadowMapWorldSize", "physicsClientId", NULL}; + static char* kwlist[] = {"flag", "enable", "lightPosition", "shadowMapResolution", "shadowMapWorldSize", "remoteSyncTransformInterval", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "|iiOiii", kwlist, - &flag, &enable, &pyLightPosition, &shadowMapResolution, &shadowMapWorldSize, &physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "|iiOiidi", kwlist, + &flag, &enable, &pyLightPosition, &shadowMapResolution, &shadowMapWorldSize, &remoteSyncTransformInterval, &physicsClientId)) return NULL; sm = getPhysicsClient(physicsClientId); @@ -5911,6 +5912,10 @@ static PyObject* pybullet_configureDebugVisualizer(PyObject* self, PyObject* arg { b3ConfigureOpenGLVisualizerSetShadowMapWorldSize(commandHandle, shadowMapWorldSize); } + if (remoteSyncTransformInterval >= 0) + { + b3ConfigureOpenGLVisualizerSetRemoteSyncTransformInterval(commandHandle, remoteSyncTransformInterval); + } b3SubmitClientCommandAndWaitStatus(sm, commandHandle); }