diff --git a/docs/pybullet_quickstartguide.pdf b/docs/pybullet_quickstartguide.pdf index c86339c54..d1305dd45 100644 Binary files a/docs/pybullet_quickstartguide.pdf and b/docs/pybullet_quickstartguide.pdf differ diff --git a/examples/ExampleBrowser/OpenGLGuiHelper.cpp b/examples/ExampleBrowser/OpenGLGuiHelper.cpp index 51c3c1d93..634004d84 100644 --- a/examples/ExampleBrowser/OpenGLGuiHelper.cpp +++ b/examples/ExampleBrowser/OpenGLGuiHelper.cpp @@ -51,6 +51,10 @@ public: { + } + + virtual ~MyDebugDrawer() + { } virtual DefaultColors getDefaultColors() const { diff --git a/examples/Importers/ImportMeshUtility/b3ImportMeshUtility.cpp b/examples/Importers/ImportMeshUtility/b3ImportMeshUtility.cpp index 442a2f777..c14658ab9 100644 --- a/examples/Importers/ImportMeshUtility/b3ImportMeshUtility.cpp +++ b/examples/Importers/ImportMeshUtility/b3ImportMeshUtility.cpp @@ -7,7 +7,7 @@ #include "../../Utils/b3ResourcePath.h" #include "Bullet3Common/b3FileUtils.h" #include "../../ThirdPartyLibs/stb_image/stb_image.h" - +#include "../ImportObjDemo/LoadMeshFromObj.h" bool b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(const std::string& fileName, b3ImportMeshData& meshData) { B3_PROFILE("loadAndRegisterMeshFromFileInternal"); @@ -28,7 +28,8 @@ bool b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(const std::string& std::vector shapes; { B3_PROFILE("tinyobj::LoadObj"); - std::string err = tinyobj::LoadObj(shapes, relativeFileName, pathPrefix); + std::string err = LoadFromCachedOrFromObj(shapes, relativeFileName, pathPrefix); + //std::string err = tinyobj::LoadObj(shapes, relativeFileName, pathPrefix); } GLInstanceGraphicsShape* gfxShape = btgCreateGraphicsShapeFromWavefrontObj(shapes); diff --git a/examples/Importers/ImportObjDemo/LoadMeshFromObj.cpp b/examples/Importers/ImportObjDemo/LoadMeshFromObj.cpp index 158d3456b..a7cf426cd 100644 --- a/examples/Importers/ImportObjDemo/LoadMeshFromObj.cpp +++ b/examples/Importers/ImportObjDemo/LoadMeshFromObj.cpp @@ -1,11 +1,56 @@ #include "LoadMeshFromObj.h" -#include"../../ThirdPartyLibs/Wavefront/tiny_obj_loader.h" + #include "../../OpenGLWindow/GLInstanceGraphicsShape.h" #include //fopen #include "Bullet3Common/b3AlignedObjectArray.h" #include #include #include "Wavefront2GLInstanceGraphicsShape.h" +#include "Bullet3Common/b3HashMap.h" + +struct CachedObjResult +{ + std::string m_msg; + std::vector m_shapes; +}; + +static b3HashMap gCachedObjResults; +static int gEnableFileCaching = 1; + +void b3EnableFileCaching(int enable) +{ + gEnableFileCaching = enable; + if (enable==0) + { + gCachedObjResults.clear(); + } +} + + +std::string LoadFromCachedOrFromObj( + std::vector& shapes, // [output] + const char* filename, + const char* mtl_basepath) +{ + CachedObjResult* resultPtr = gCachedObjResults[filename]; + if (resultPtr) + { + const CachedObjResult& result = *resultPtr; + shapes = result.m_shapes; + return result.m_msg; + } + + std::string err = tinyobj::LoadObj(shapes, filename, mtl_basepath); + CachedObjResult result; + result.m_msg = err; + result.m_shapes = shapes; + if (gEnableFileCaching) + { + gCachedObjResults.insert(filename,result); + } + return err; +} + GLInstanceGraphicsShape* LoadMeshFromObj(const char* relativeFileName, const char* materialPrefixPath) { @@ -13,7 +58,7 @@ GLInstanceGraphicsShape* LoadMeshFromObj(const char* relativeFileName, const cha std::vector shapes; { B3_PROFILE("tinyobj::LoadObj2"); - std::string err = tinyobj::LoadObj(shapes, relativeFileName, materialPrefixPath); + std::string err = LoadFromCachedOrFromObj(shapes, relativeFileName, materialPrefixPath); } { diff --git a/examples/Importers/ImportObjDemo/LoadMeshFromObj.h b/examples/Importers/ImportObjDemo/LoadMeshFromObj.h index 72533dfd8..4d23eea8d 100644 --- a/examples/Importers/ImportObjDemo/LoadMeshFromObj.h +++ b/examples/Importers/ImportObjDemo/LoadMeshFromObj.h @@ -4,6 +4,14 @@ struct GLInstanceGraphicsShape; +#include"../../ThirdPartyLibs/Wavefront/tiny_obj_loader.h" + +void b3EnableFileCaching(int enable); + +std::string LoadFromCachedOrFromObj( + std::vector& shapes, // [output] + const char* filename, + const char* mtl_basepath); GLInstanceGraphicsShape* LoadMeshFromObj(const char* relativeFileName, const char* materialPrefixPath); diff --git a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp index 9080f8954..2a43dc739 100644 --- a/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp +++ b/examples/Importers/ImportURDFDemo/BulletUrdfImporter.cpp @@ -634,8 +634,15 @@ btCollisionShape* convertURDFToCollisionShape(const UrdfCollision* collision, co case UrdfGeometry::FILE_OBJ: if (collision->m_flags & URDF_FORCE_CONCAVE_TRIMESH) { - - glmesh = LoadMeshFromObj(collision->m_geometry.m_meshFileName.c_str(), 0); + char relativeFileName[1024]; + char pathPrefix[1024]; + pathPrefix[0] = 0; + if (b3ResourcePath::findResourcePath(collision->m_geometry.m_meshFileName.c_str(), relativeFileName, 1024)) + { + + b3FileUtils::extractPath(relativeFileName, pathPrefix, 1024); + } + glmesh = LoadMeshFromObj(collision->m_geometry.m_meshFileName.c_str(), pathPrefix); } else { diff --git a/examples/Importers/ImportURDFDemo/UrdfParser.h b/examples/Importers/ImportURDFDemo/UrdfParser.h index 0bb291e58..de96885e5 100644 --- a/examples/Importers/ImportURDFDemo/UrdfParser.h +++ b/examples/Importers/ImportURDFDemo/UrdfParser.h @@ -87,7 +87,16 @@ struct UrdfGeometry UrdfGeometry() :m_type(URDF_GEOM_UNKNOWN), - m_hasFromTo(false), + m_sphereRadius(1), + m_boxSize(1,1,1), + m_capsuleRadius(1), + m_capsuleHeight(1), + m_hasFromTo(0), + m_capsuleFrom(0,1,0), + m_capsuleTo(1,0,0), + m_planeNormal(0,0,1), + m_meshFileType(0), + m_meshScale(1,1,1), m_hasLocalMaterial(false) { } diff --git a/examples/OpenGLWindow/GLInstancingRenderer.cpp b/examples/OpenGLWindow/GLInstancingRenderer.cpp index 39a8c8a5b..8974cf24a 100644 --- a/examples/OpenGLWindow/GLInstancingRenderer.cpp +++ b/examples/OpenGLWindow/GLInstancingRenderer.cpp @@ -893,17 +893,25 @@ int GLInstancingRenderer::registerShape(const float* vertices, int numvertices, gfxObj->m_numVertices = numvertices; - glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo); + int vertexStrideInBytes = 9*sizeof(float); int sz = numvertices*vertexStrideInBytes; + int totalUsed = vertexStrideInBytes*gfxObj->m_vertexArrayOffset+sz; + b3Assert(totalUsedm_maxShapeCapacityInBytes); + if (totalUsed>=m_data->m_maxShapeCapacityInBytes) + { + return -1; + } + + glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo); + #if 0 char* dest= (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_WRITE_ONLY);//GL_WRITE_ONLY #ifdef B3_DEBUG - int totalUsed = vertexStrideInBytes*gfxObj->m_vertexArrayOffset+sz; - b3Assert(totalUsedm_maxShapeCapacityInBytes); + #endif//B3_DEBUG memcpy(dest+vertexStrideInBytes*gfxObj->m_vertexArrayOffset,vertices,sz); @@ -1613,6 +1621,11 @@ static void b3CreateLookAt(const b3Vector3& eye, const b3Vector3& center,cons void GLInstancingRenderer::renderSceneInternal(int renderMode) { + if (!useShadowMap) + { + renderMode = B3_DEFAULT_RENDERMODE; + } + // glEnable(GL_DEPTH_TEST); GLint dims[4]; diff --git a/examples/RoboticsLearning/R2D2GraspExample.cpp b/examples/RoboticsLearning/R2D2GraspExample.cpp index 7cae8046d..ad14ceec5 100644 --- a/examples/RoboticsLearning/R2D2GraspExample.cpp +++ b/examples/RoboticsLearning/R2D2GraspExample.cpp @@ -92,7 +92,7 @@ public: m_robotSim.loadSDF("kiva_shelf/model.sdf",results); } { - m_robotSim.loadURDF("results"); + m_robotSim.loadURDF("plane.urdf"); } m_robotSim.setGravity(b3MakeVector3(0,0,-10)); diff --git a/examples/SharedMemory/PhysicsClientC_API.cpp b/examples/SharedMemory/PhysicsClientC_API.cpp index 7a353bbf7..6a4023c58 100644 --- a/examples/SharedMemory/PhysicsClientC_API.cpp +++ b/examples/SharedMemory/PhysicsClientC_API.cpp @@ -381,6 +381,17 @@ int b3PhysicsParamSetMaxNumCommandsPer1ms(b3SharedMemoryCommandHandle commandHan } +int b3PhysicsParamSetEnableFileCaching(b3SharedMemoryCommandHandle commandHandle, int enableFileCaching) +{ + struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle; + b3Assert(command->m_type == CMD_SEND_PHYSICS_SIMULATION_PARAMETERS); + + command->m_physSimParamArgs.m_enableFileCaching= enableFileCaching; + command->m_updateFlags |= SIM_PARAM_ENABLE_FILE_CACHING ; + return 0; + +} + int b3PhysicsParamSetNumSolverIterations(b3SharedMemoryCommandHandle commandHandle, int numSolverIterations) { struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle; @@ -1785,7 +1796,10 @@ void b3RequestCameraImageSelectRenderer(b3SharedMemoryCommandHandle commandHandl b3Assert(command); b3Assert(command->m_type == CMD_REQUEST_CAMERA_IMAGE_DATA); b3Assert(renderer>(1<<15)); - command->m_updateFlags |= renderer; + if (renderer>(1<<15)) + { + command->m_updateFlags |= renderer; + } } void b3RequestCameraImageSetCameraMatrices(b3SharedMemoryCommandHandle commandHandle, float viewMatrix[16], float projectionMatrix[16]) @@ -2712,6 +2726,8 @@ int b3SetVRCameraRootOrientation(b3SharedMemoryCommandHandle commandHandle, doub command->m_vrCameraStateArguments.m_rootOrientation[0] = rootOrn[0]; command->m_vrCameraStateArguments.m_rootOrientation[1] = rootOrn[1]; command->m_vrCameraStateArguments.m_rootOrientation[2] = rootOrn[2]; + command->m_vrCameraStateArguments.m_rootOrientation[3] = rootOrn[3]; + return 0; } @@ -2725,6 +2741,15 @@ int b3SetVRCameraTrackingObject(b3SharedMemoryCommandHandle commandHandle, int o return 0; } +int b3SetVRCameraTrackingObjectFlag(b3SharedMemoryCommandHandle commandHandle, int flag) +{ + struct SharedMemoryCommand* command = (struct SharedMemoryCommand*) commandHandle; + b3Assert(command); + b3Assert(command->m_type == CMD_SET_VR_CAMERA_STATE); + command->m_updateFlags |= VR_CAMERA_FLAG; + command->m_vrCameraStateArguments.m_trackingObjectFlag = flag; + return 0; +} b3SharedMemoryCommandHandle b3RequestKeyboardEventsCommandInit(b3PhysicsClientHandle physClient) diff --git a/examples/SharedMemory/PhysicsClientC_API.h b/examples/SharedMemory/PhysicsClientC_API.h index b9802de36..cee3a9b41 100644 --- a/examples/SharedMemory/PhysicsClientC_API.h +++ b/examples/SharedMemory/PhysicsClientC_API.h @@ -215,6 +215,7 @@ int b3PhysicsParamSetUseSplitImpulse(b3SharedMemoryCommandHandle commandHandle, int b3PhysicsParamSetSplitImpulsePenetrationThreshold(b3SharedMemoryCommandHandle commandHandle, double splitImpulsePenetrationThreshold); int b3PhysicsParamSetContactBreakingThreshold(b3SharedMemoryCommandHandle commandHandle, double contactBreakingThreshold); int b3PhysicsParamSetMaxNumCommandsPer1ms(b3SharedMemoryCommandHandle commandHandle, int maxNumCmdPer1ms); +int b3PhysicsParamSetEnableFileCaching(b3SharedMemoryCommandHandle commandHandle, int enableFileCaching); //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 @@ -376,6 +377,7 @@ b3SharedMemoryCommandHandle b3SetVRCameraStateCommandInit(b3PhysicsClientHandle int b3SetVRCameraRootPosition(b3SharedMemoryCommandHandle commandHandle, double rootPos[3]); int b3SetVRCameraRootOrientation(b3SharedMemoryCommandHandle commandHandle, double rootOrn[4]); int b3SetVRCameraTrackingObject(b3SharedMemoryCommandHandle commandHandle, int objectUniqueId); +int b3SetVRCameraTrackingObjectFlag(b3SharedMemoryCommandHandle commandHandle, int flag); b3SharedMemoryCommandHandle b3RequestKeyboardEventsCommandInit(b3PhysicsClientHandle physClient); void b3GetKeyboardEventsData(b3PhysicsClientHandle physClient, struct b3KeyboardEventsData* keyboardEventsData); diff --git a/examples/SharedMemory/PhysicsClientExample.cpp b/examples/SharedMemory/PhysicsClientExample.cpp index 7fe0109d8..0a3bc706c 100644 --- a/examples/SharedMemory/PhysicsClientExample.cpp +++ b/examples/SharedMemory/PhysicsClientExample.cpp @@ -122,7 +122,8 @@ protected: { if (m_options == eCLIENTEXAMPLE_SERVER) { - m_physicsServer.renderScene(); + int renderFlags = 0; + m_physicsServer.renderScene(renderFlags); } b3DebugLines debugLines; diff --git a/examples/SharedMemory/PhysicsClientTCP.cpp b/examples/SharedMemory/PhysicsClientTCP.cpp index 4215769e1..f959325c0 100644 --- a/examples/SharedMemory/PhysicsClientTCP.cpp +++ b/examples/SharedMemory/PhysicsClientTCP.cpp @@ -226,7 +226,7 @@ bool TcpNetworkedPhysicsProcessor::receiveStatus(struct SharedMemoryStatus& serv } -void TcpNetworkedPhysicsProcessor::renderScene() +void TcpNetworkedPhysicsProcessor::renderScene(int renderFlags) { } diff --git a/examples/SharedMemory/PhysicsClientTCP.h b/examples/SharedMemory/PhysicsClientTCP.h index 12644eb68..0304e0a65 100644 --- a/examples/SharedMemory/PhysicsClientTCP.h +++ b/examples/SharedMemory/PhysicsClientTCP.h @@ -24,7 +24,7 @@ public: virtual bool receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); - virtual void renderScene(); + virtual void renderScene(int renderFlags); virtual void physicsDebugDraw(int debugDrawFlags); diff --git a/examples/SharedMemory/PhysicsClientUDP.cpp b/examples/SharedMemory/PhysicsClientUDP.cpp index 7bc1a6286..f3b316723 100644 --- a/examples/SharedMemory/PhysicsClientUDP.cpp +++ b/examples/SharedMemory/PhysicsClientUDP.cpp @@ -540,7 +540,7 @@ bool UdpNetworkedPhysicsProcessor::receiveStatus(struct SharedMemoryStatus& serv } -void UdpNetworkedPhysicsProcessor::renderScene() +void UdpNetworkedPhysicsProcessor::renderScene(int renderFlags) { } diff --git a/examples/SharedMemory/PhysicsClientUDP.h b/examples/SharedMemory/PhysicsClientUDP.h index bcb4e3268..8d8d08fd1 100644 --- a/examples/SharedMemory/PhysicsClientUDP.h +++ b/examples/SharedMemory/PhysicsClientUDP.h @@ -24,7 +24,7 @@ public: virtual bool receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); - virtual void renderScene(); + virtual void renderScene(int renderFlags); virtual void physicsDebugDraw(int debugDrawFlags); diff --git a/examples/SharedMemory/PhysicsCommandProcessorInterface.h b/examples/SharedMemory/PhysicsCommandProcessorInterface.h index e883b86f4..70ed2d044 100644 --- a/examples/SharedMemory/PhysicsCommandProcessorInterface.h +++ b/examples/SharedMemory/PhysicsCommandProcessorInterface.h @@ -1,6 +1,11 @@ #ifndef PHYSICS_COMMAND_PROCESSOR_INTERFACE_H #define PHYSICS_COMMAND_PROCESSOR_INTERFACE_H +enum PhysicsCOmmandRenderFlags +{ + COV_DISABLE_SYNC_RENDERING=1 +}; + class PhysicsCommandProcessorInterface { @@ -17,7 +22,7 @@ public: virtual bool receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes) = 0; - virtual void renderScene() = 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; diff --git a/examples/SharedMemory/PhysicsDirect.cpp b/examples/SharedMemory/PhysicsDirect.cpp index 8a5ec6c8d..e03e2d7f0 100644 --- a/examples/SharedMemory/PhysicsDirect.cpp +++ b/examples/SharedMemory/PhysicsDirect.cpp @@ -171,7 +171,8 @@ bool PhysicsDirect::connect(struct GUIHelperInterface* guiHelper) void PhysicsDirect::renderScene() { - m_data->m_commandProcessor->renderScene(); + int renderFlags = 0; + m_data->m_commandProcessor->renderScene(renderFlags); } void PhysicsDirect::debugDraw(int debugDrawMode) diff --git a/examples/SharedMemory/PhysicsServer.h b/examples/SharedMemory/PhysicsServer.h index e80af8193..7b75a36cf 100644 --- a/examples/SharedMemory/PhysicsServer.h +++ b/examples/SharedMemory/PhysicsServer.h @@ -33,7 +33,7 @@ public: //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)=0; - virtual void renderScene()=0; + virtual void renderScene(int renderFlags)=0; virtual void enableCommandLogging(bool enable, const char* fileName)=0; virtual void replayFromLogFile(const char* fileName)=0; diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp index 9b3c724c2..ea720de67 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp @@ -22,6 +22,7 @@ #include "../Utils/RobotLoggingUtil.h" #include "LinearMath/btTransform.h" #include "../Importers/ImportMJCFDemo/BulletMJCFImporter.h" +#include "../Importers/ImportObjDemo/LoadMeshFromObj.h" #include "../Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h" #include "BulletDynamics/Featherstone/btMultiBodyJointMotor.h" #include "LinearMath/btSerializer.h" @@ -54,6 +55,8 @@ bool gCreateDefaultRobotAssets = false; int gInternalSimFlags = 0; bool gResetSimulation = 0; int gVRTrackingObjectUniqueId = -1; +int gVRTrackingObjectFlag = VR_CAMERA_TRACK_OBJECT_ORIENTATION; + btTransform gVRTrackingObjectTr = btTransform::getIdentity(); int gMaxNumCmdPer1ms = -1;//experiment: add some delay to avoid threads starving other threads @@ -2181,7 +2184,7 @@ int PhysicsServerCommandProcessor::createBodyInfoStream(int bodyUniqueId, char* //serialize the btMultiBody and send the data to the client. This is one way to get the link/joint names across the (shared memory) wire InternalBodyHandle* bodyHandle = m_data->m_bodyHandles.getHandle(bodyUniqueId); - btMultiBody* mb = bodyHandle->m_multiBody; + btMultiBody* mb = bodyHandle? bodyHandle->m_multiBody:0; if (mb) { UrdfLinkNameMapUtil* util = new UrdfLinkNameMapUtil; @@ -2440,6 +2443,7 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm { if (clientCmd.m_stateLoggingArguments.m_loggingUniqueId == m_data->m_profileTimingLoggingUid) { + serverStatusOut.m_type = CMD_STATE_LOGGING_COMPLETED; b3ChromeUtilsStopTimingsAndWriteJsonFile(m_data->m_profileTimingFileName.c_str()); m_data->m_profileTimingLoggingUid = -1; } @@ -2482,6 +2486,11 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm gVRTrackingObjectUniqueId = clientCmd.m_vrCameraStateArguments.m_trackingObjectUniqueId; } + if (clientCmd.m_updateFlags & VR_CAMERA_FLAG) + { + gVRTrackingObjectFlag = clientCmd.m_vrCameraStateArguments.m_trackingObjectFlag; + } + serverStatusOut.m_type = CMD_CLIENT_COMMAND_COMPLETED; hasStatus = true; break; @@ -2837,10 +2846,11 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm int actualNumBodies = 0; for (int i=0;im_bodyHandles.getHandle(usedHandles[i]); + int usedHandle = usedHandles[i]; + InteralBodyData* body = m_data->m_bodyHandles.getHandle(usedHandle); if (body && (body->m_multiBody || body->m_rigidBody)) { - serverStatusOut.m_sdfLoadedArgs.m_bodyUniqueIds[actualNumBodies++] = i; + serverStatusOut.m_sdfLoadedArgs.m_bodyUniqueIds[actualNumBodies++] = usedHandle; } } serverStatusOut.m_sdfLoadedArgs.m_numBodies = actualNumBodies; @@ -4058,6 +4068,12 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm m_data->m_dynamicsWorld->getSolverInfo().m_erp2 = clientCmd.m_physSimParamArgs.m_defaultContactERP; } + if (clientCmd.m_updateFlags&SIM_PARAM_ENABLE_FILE_CACHING) + { + b3EnableFileCaching(clientCmd.m_physSimParamArgs.m_enableFileCaching); + } + + SharedMemoryStatus& serverCmd =serverStatusOut; serverCmd.m_type = CMD_CLIENT_COMMAND_COMPLETED; hasStatus = true; @@ -4216,10 +4232,12 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm case CMD_RESET_SIMULATION: { + BT_PROFILE("CMD_RESET_SIMULATION"); - + m_data->m_guiHelper->setVisualizerFlag(COV_ENABLE_SYNC_RENDERING_INTERNAL,0); resetSimulation(); - + m_data->m_guiHelper->setVisualizerFlag(COV_ENABLE_SYNC_RENDERING_INTERNAL,1); + SharedMemoryStatus& serverCmd =serverStatusOut; serverCmd.m_type = CMD_RESET_SIMULATION_COMPLETED; hasStatus = true; @@ -5062,6 +5080,8 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm serverCmd.m_removeObjectArgs.m_numBodies = 0; serverCmd.m_removeObjectArgs.m_numUserConstraints = 0; + m_data->m_guiHelper->setVisualizerFlag(COV_ENABLE_SYNC_RENDERING_INTERNAL,0); + for (int i=0;im_bodyHandles.freeHandle(bodyUniqueId); } - + m_data->m_guiHelper->setVisualizerFlag(COV_ENABLE_SYNC_RENDERING_INTERNAL,1); + hasStatus = true; break; @@ -5929,11 +5950,14 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm //static int skip=1; -void PhysicsServerCommandProcessor::renderScene() +void PhysicsServerCommandProcessor::renderScene(int renderFlags) { if (m_data->m_guiHelper) { - m_data->m_guiHelper->syncPhysicsToGraphics(m_data->m_dynamicsWorld); + if (0==(renderFlags&COV_DISABLE_SYNC_RENDERING)) + { + m_data->m_guiHelper->syncPhysicsToGraphics(m_data->m_dynamicsWorld); + } m_data->m_guiHelper->render(m_data->m_dynamicsWorld); } #ifdef USE_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD @@ -6180,6 +6204,24 @@ void PhysicsServerCommandProcessor::stepSimulationRealTime(double dtInSec, const gResetSimulation = false; } + if (gVRTrackingObjectUniqueId >= 0) + { + InternalBodyHandle* bodyHandle = m_data->m_bodyHandles.getHandle(gVRTrackingObjectUniqueId); + if (bodyHandle && bodyHandle->m_multiBody) + { +// gVRTrackingObjectTr = bodyHandle->m_multiBody->getBaseWorldTransform(); + + if (gVRTrackingObjectUniqueId>=0) + { + gVRTrackingObjectTr.setOrigin(bodyHandle->m_multiBody->getBaseWorldTransform().getOrigin()); + } + if (gVRTrackingObjectFlag&VR_CAMERA_TRACK_OBJECT_ORIENTATION) + { + gVRTrackingObjectTr.setBasis(bodyHandle->m_multiBody->getBaseWorldTransform().getBasis()); + } + } + } + if ((m_data->m_allowRealTimeSimulation) && m_data->m_guiHelper) { @@ -6199,14 +6241,7 @@ void PhysicsServerCommandProcessor::stepSimulationRealTime(double dtInSec, const gSubStep = m_data->m_physicsDeltaTime; } - if (gVRTrackingObjectUniqueId >= 0) - { - InternalBodyHandle* bodyHandle = m_data->m_bodyHandles.getHandle(gVRTrackingObjectUniqueId); - if (bodyHandle && bodyHandle->m_multiBody) - { - gVRTrackingObjectTr = bodyHandle->m_multiBody->getBaseWorldTransform(); - } - } + int numSteps = m_data->m_dynamicsWorld->stepSimulation(dtInSec*simTimeScalingFactor,maxSteps, gSubStep); diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.h b/examples/SharedMemory/PhysicsServerCommandProcessor.h index 5dc0d0e64..f30d35f2c 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.h +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.h @@ -78,7 +78,7 @@ public: return false; }; - virtual void renderScene(); + virtual void renderScene(int renderFlags); virtual void physicsDebugDraw(int debugDrawFlags); virtual void setGuiHelper(struct GUIHelperInterface* guiHelper); diff --git a/examples/SharedMemory/PhysicsServerExample.cpp b/examples/SharedMemory/PhysicsServerExample.cpp index 7ffa48b21..cf5f0c275 100644 --- a/examples/SharedMemory/PhysicsServerExample.cpp +++ b/examples/SharedMemory/PhysicsServerExample.cpp @@ -25,6 +25,11 @@ //@todo(erwincoumans) those globals are hacks for a VR demo, move this to Python/pybullet! extern btVector3 gLastPickPos; +bool gEnablePicking=true; +bool gEnableTeleporting=true; +bool gEnableRendering= true; +bool gEnableSyncPhysicsRendering= true; +bool gEnableUpdateDebugDrawLines = true; btVector3 gVRTeleportPosLocal(0,0,0); btQuaternion gVRTeleportOrnLocal(0,0,0,1); @@ -181,6 +186,7 @@ enum MultiThreadedGUIHelperCommunicationEnums eGUIDumpFramesToVideo, eGUIHelperRemoveGraphicsInstance, eGUIHelperChangeGraphicsInstanceRGBAColor, + eGUIHelperSetVisualizerFlag, }; @@ -232,7 +238,9 @@ struct MyMouseCommand struct MotionArgs { MotionArgs() - :m_physicsServerPtr(0) + : + m_debugDrawFlags(0), + m_physicsServerPtr(0) { for (int i=0;i m_mouseCommands; @@ -452,6 +461,15 @@ void MotionThreadFunc(void* userPtr,void* lsMemory) { args->m_physicsServerPtr->stepSimulationRealTime(deltaTimeInSeconds, args->m_sendVrControllerEvents,numSendVrControllers, keyEvents, args->m_sendKeyEvents.size()); } + { + if (gEnableUpdateDebugDrawLines) + { + args->m_csGUI->lock(); + args->m_physicsServerPtr->physicsDebugDraw(args->m_debugDrawFlags); + gEnableUpdateDebugDrawLines=false; + args->m_csGUI->unlock(); + } + } deltaTimeInSeconds = 0; } @@ -546,6 +564,138 @@ struct UserDebugText }; + struct LineSegment +{ + btVector3 m_from; + btVector3 m_to; +}; + +struct ColorWidth +{ + btVector3FloatData m_color; + int width; + int getHash() const + { + unsigned char r = (unsigned char) m_color.m_floats[0]*255; + unsigned char g = (unsigned char) m_color.m_floats[1]*255; + unsigned char b = (unsigned char) m_color.m_floats[2]*255; + unsigned char w = width; + return r+(256*g)+(256*256*b)+(256*256*256*w); + } + bool equals(const ColorWidth& other) const + { + bool same = ((width == other.width) && (m_color.m_floats[0] == other.m_color.m_floats[0]) && + (m_color.m_floats[1] == other.m_color.m_floats[1]) && + (m_color.m_floats[2] == other.m_color.m_floats[2])); + return same; + } +}; + + + +ATTRIBUTE_ALIGNED16( class )MultithreadedDebugDrawer : public btIDebugDraw +{ + class GUIHelperInterface* m_guiHelper; + int m_debugMode; + + btAlignedObjectArray< btAlignedObjectArray > m_sortedIndices; + btAlignedObjectArray< btAlignedObjectArray > m_sortedLines; + btHashMap m_hashedLines; + + + public: + void drawDebugDrawerLines() + { + if (m_hashedLines.size()) + { + for (int i=0;igetRenderInterface()->drawLines(positions,cw.m_color.m_floats,numPoints, stride, indices,numIndices,cw.width); + } + } + } + MultithreadedDebugDrawer(GUIHelperInterface* guiHelper) + :m_guiHelper(guiHelper), + m_debugMode(0) + { + } + virtual ~MultithreadedDebugDrawer() + { + } + virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color) + { + { + ColorWidth cw; + color.serializeFloat(cw.m_color); + cw.width = 1; + int index = -1; + + int* indexPtr = m_hashedLines.find(cw); + if (indexPtr) + { + index = *indexPtr; + } else + { + index = m_sortedLines.size(); + m_sortedLines.expand(); + m_sortedIndices.expand(); + m_hashedLines.insert(cw,index); + } + btAssert(index>=0); + if (index>=0) + { + btVector3FloatData from1,toX1; + m_sortedIndices[index].push_back(m_sortedLines[index].size()); + from.serializeFloat(from1); + m_sortedLines[index].push_back(from1); + m_sortedIndices[index].push_back(m_sortedLines[index].size()); + to.serializeFloat(toX1); + m_sortedLines[index].push_back(toX1); + } + } + } + + virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color) + { + drawLine(PointOnB,PointOnB+normalOnB*distance,color); + btVector3 ncolor(0, 0, 0); + drawLine(PointOnB, PointOnB + normalOnB*0.01, ncolor); + } + + virtual void reportErrorWarning(const char* warningString) + { + } + virtual void draw3dText(const btVector3& location,const char* textString) + { + } + virtual void setDebugMode(int debugMode) + { + m_debugMode = debugMode; + } + + virtual int getDebugMode() const + { + return m_debugMode; + } + + virtual void clearLines() + { + m_hashedLines.clear(); + m_sortedIndices.clear(); + m_sortedLines.clear(); + } + virtual void flushLines() + { + + } +}; class MultiThreadedOpenGLGuiHelper : public GUIHelperInterface { @@ -555,17 +705,19 @@ class MultiThreadedOpenGLGuiHelper : public GUIHelperInterface b3CriticalSection* m_cs2; b3CriticalSection* m_cs3; b3CriticalSection* m_csGUI; - + public: - void setVisualizerFlag(int flag, int enable) - { - m_childGuiHelper->setVisualizerFlag(flag,enable); - } - - + MultithreadedDebugDrawer* m_debugDraw; + void drawDebugDrawerLines() + { + if (m_debugDraw) + { + m_debugDraw->drawDebugDrawerLines(); + } + } GUIHelperInterface* m_childGuiHelper; int m_uidGenerator; @@ -626,6 +778,7 @@ public: m_cs2(0), m_cs3(0), m_csGUI(0), + m_debugDraw(0), m_uidGenerator(0), m_texels(0), m_textureId(-1) @@ -727,7 +880,18 @@ public: virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld) { - m_childGuiHelper->createPhysicsDebugDrawer(rbWorld); + btAssert(rbWorld); + if (m_debugDraw) + { + delete m_debugDraw; + m_debugDraw = 0; + } + + m_debugDraw = new MultithreadedDebugDrawer(this); + + rbWorld->setDebugDrawer(m_debugDraw ); + + //m_childGuiHelper->createPhysicsDebugDrawer(rbWorld); } virtual int registerTexture(const unsigned char* texels, int width, int height) @@ -759,6 +923,25 @@ public: return m_shapeIndex; } + + int m_visualizerFlag; + int m_visualizerEnable; + void setVisualizerFlag(int flag, int enable) + { + m_visualizerFlag = flag; + m_visualizerEnable = enable; + + m_cs->lock(); + m_cs->setSharedParam(1,eGUIHelperSetVisualizerFlag); + workerThreadWait(); + } + + void setVisualizerFlagCallback(VisualizerFlagCallback callback) + { + m_childGuiHelper->setVisualizerFlagCallback(callback); + } + + virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) { m_shapeIndex = shapeIndex; @@ -998,6 +1181,10 @@ public: } + + + + const char* m_mp4FileName; virtual void dumpFramesToVideo(const char* mp4FileName) { @@ -1558,6 +1745,38 @@ void PhysicsServerExample::updateGraphics() m_multiThreadedHelper->mainThreadRelease(); break; } + + case eGUIHelperSetVisualizerFlag: + { + int flag = m_multiThreadedHelper->m_visualizerFlag; + int enable = m_multiThreadedHelper->m_visualizerEnable; + + if (flag==COV_ENABLE_VR_TELEPORTING) + { + gEnableTeleporting = enable; + } + + if (flag == COV_ENABLE_VR_PICKING) + { + gEnablePicking = enable; + } + + if (flag ==COV_ENABLE_SYNC_RENDERING_INTERNAL) + { + gEnableSyncPhysicsRendering = enable; + } + + if (flag == COV_ENABLE_RENDERING) + { + gEnableRendering = enable; + } + + m_multiThreadedHelper->m_childGuiHelper->setVisualizerFlag(m_multiThreadedHelper->m_visualizerFlag,m_multiThreadedHelper->m_visualizerEnable); + m_multiThreadedHelper->mainThreadRelease(); + break; + } + + case eGUIHelperRegisterGraphicsInstance: { m_multiThreadedHelper->m_instanceId = m_multiThreadedHelper->m_childGuiHelper->registerGraphicsInstance( @@ -1761,32 +1980,6 @@ extern double gSubStep; extern int gVRTrackingObjectUniqueId; extern btTransform gVRTrackingObjectTr; - struct LineSegment - { - btVector3 m_from; - btVector3 m_to; - }; - - struct ColorWidth - { - btVector3FloatData m_color; - int width; - int getHash() const - { - unsigned char r = (unsigned char) m_color.m_floats[0]*255; - unsigned char g = (unsigned char) m_color.m_floats[1]*255; - unsigned char b = (unsigned char) m_color.m_floats[2]*255; - unsigned char w = width; - return r+(256*g)+(256*256*b)+(256*256*256*w); - } - bool equals(const ColorWidth& other) const - { - bool same = ((width == other.width) && (m_color.m_floats[0] == other.m_color.m_floats[0]) && - (m_color.m_floats[1] == other.m_color.m_floats[1]) && - (m_color.m_floats[2] == other.m_color.m_floats[2])); - return same; - } - }; void PhysicsServerExample::drawUserDebugLines() { @@ -2013,30 +2206,41 @@ void PhysicsServerExample::renderScene() m_multiThreadedHelper->m_childGuiHelper->getRenderInterface()-> getActiveCamera()->setVRCameraOffsetTransform(vrOffset); } - m_physicsServer.renderScene(); - - for (int i=0;igetAppInterface()->m_renderer->drawLine(from,toX,color,width); - color=btVector4(0,1,0,1); - m_guiHelper->getAppInterface()->m_renderer->drawLine(from,toY,color,width); - color=btVector4(0,0,1,1); - m_guiHelper->getAppInterface()->m_renderer->drawLine(from,toZ,color,width); + btVector4 color; + color=btVector4(1,0,0,1); + m_guiHelper->getAppInterface()->m_renderer->drawLine(from,toX,color,width); + color=btVector4(0,1,0,1); + m_guiHelper->getAppInterface()->m_renderer->drawLine(from,toY,color,width); + color=btVector4(0,0,1,1); + m_guiHelper->getAppInterface()->m_renderer->drawLine(from,toZ,color,width); + } } } @@ -2058,9 +2262,18 @@ void PhysicsServerExample::physicsDebugDraw(int debugDrawFlags) { drawUserDebugLines(); - ///debug rendering - m_physicsServer.physicsDebugDraw(debugDrawFlags); + if (gEnableRendering) + { + ///debug rendering + //m_physicsServer.physicsDebugDraw(debugDrawFlags); + m_args[0].m_csGUI->lock(); + //draw stuff and flush? + this->m_multiThreadedHelper->m_debugDraw->drawDebugDrawerLines(); + m_args[0].m_debugDrawFlags = debugDrawFlags; + gEnableUpdateDebugDrawLines = true; + m_args[0].m_csGUI->unlock(); + } } @@ -2132,10 +2345,12 @@ btVector3 PhysicsServerExample::getRayTo(int x,int y) extern int gSharedMemoryKey; + class CommonExampleInterface* PhysicsServerCreateFunc(struct CommonExampleOptions& options) { MultiThreadedOpenGLGuiHelper* guiHelperWrapper = new MultiThreadedOpenGLGuiHelper(options.m_guiHelper->getAppInterface(),options.m_guiHelper); + PhysicsServerExample* example = new PhysicsServerExample(guiHelperWrapper, options.m_sharedMem, @@ -2250,7 +2465,7 @@ void PhysicsServerExample::vrControllerButtonCallback(int controllerId, int butt } - if (button==1) + if (button==1 && gEnableTeleporting) { m_args[0].m_isVrControllerTeleporting[controllerId] = true; } @@ -2262,7 +2477,7 @@ void PhysicsServerExample::vrControllerButtonCallback(int controllerId, int butt else { - if (button == 33) + if (button == 33 && gEnablePicking) { m_args[0].m_isVrControllerPicking[controllerId] = (state != 0); m_args[0].m_isVrControllerReleasing[controllerId] = (state == 0); diff --git a/examples/SharedMemory/PhysicsServerSharedMemory.cpp b/examples/SharedMemory/PhysicsServerSharedMemory.cpp index 0a9c75f3c..b145db6c6 100644 --- a/examples/SharedMemory/PhysicsServerSharedMemory.cpp +++ b/examples/SharedMemory/PhysicsServerSharedMemory.cpp @@ -274,9 +274,9 @@ void PhysicsServerSharedMemory::processClientCommands() } } -void PhysicsServerSharedMemory::renderScene() +void PhysicsServerSharedMemory::renderScene(int renderFlags) { - m_data->m_commandProcessor->renderScene(); + m_data->m_commandProcessor->renderScene(renderFlags); diff --git a/examples/SharedMemory/PhysicsServerSharedMemory.h b/examples/SharedMemory/PhysicsServerSharedMemory.h index c85daabe7..3e1270c51 100644 --- a/examples/SharedMemory/PhysicsServerSharedMemory.h +++ b/examples/SharedMemory/PhysicsServerSharedMemory.h @@ -42,7 +42,7 @@ public: //and for physics visualization. The idea is that physicsDebugDraw can also send wireframe //to a physics client, over shared memory void physicsDebugDraw(int debugDrawFlags); - void renderScene(); + void renderScene(int renderFlags); void enableCommandLogging(bool enable, const char* fileName); void replayFromLogFile(const char* fileName); diff --git a/examples/SharedMemory/SharedMemoryCommandProcessor.cpp b/examples/SharedMemory/SharedMemoryCommandProcessor.cpp index 90980794e..abd4879a2 100644 --- a/examples/SharedMemory/SharedMemoryCommandProcessor.cpp +++ b/examples/SharedMemory/SharedMemoryCommandProcessor.cpp @@ -183,7 +183,7 @@ bool SharedMemoryCommandProcessor::receiveStatus(struct SharedMemoryStatus& serv return false; } -void SharedMemoryCommandProcessor::renderScene() +void SharedMemoryCommandProcessor::renderScene(int renderFlags) { } diff --git a/examples/SharedMemory/SharedMemoryCommandProcessor.h b/examples/SharedMemory/SharedMemoryCommandProcessor.h index b552b7ad3..6d75b87d9 100644 --- a/examples/SharedMemory/SharedMemoryCommandProcessor.h +++ b/examples/SharedMemory/SharedMemoryCommandProcessor.h @@ -23,7 +23,7 @@ public: virtual bool receiveStatus(struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); - virtual void renderScene(); + virtual void renderScene(int renderFlags); virtual void physicsDebugDraw(int debugDrawFlags); virtual void setGuiHelper(struct GUIHelperInterface* guiHelper); diff --git a/examples/SharedMemory/SharedMemoryCommands.h b/examples/SharedMemory/SharedMemoryCommands.h index 8b1feed62..c9f1099a5 100644 --- a/examples/SharedMemory/SharedMemoryCommands.h +++ b/examples/SharedMemory/SharedMemoryCommands.h @@ -353,6 +353,8 @@ enum EnumSimParamUpdateFlags SIM_PARAM_UPDATE_COLLISION_FILTER_MODE=512, SIM_PARAM_UPDATE_CONTACT_BREAKING_THRESHOLD = 1024, SIM_PARAM_MAX_CMD_PER_1MS = 2048, + SIM_PARAM_ENABLE_FILE_CACHING = 4096, + }; enum EnumLoadBunnyUpdateFlags @@ -384,6 +386,7 @@ struct SendPhysicsSimulationParameters int m_internalSimFlags; double m_defaultContactERP; int m_collisionFilterMode; + int m_enableFileCaching; }; struct LoadBunnyArgs @@ -675,7 +678,8 @@ enum eVRCameraEnums { VR_CAMERA_ROOT_POSITION=1, VR_CAMERA_ROOT_ORIENTATION=2, - VR_CAMERA_ROOT_TRACKING_OBJECT=4 + VR_CAMERA_ROOT_TRACKING_OBJECT=4, + VR_CAMERA_FLAG = 8, }; enum eStateLoggingEnums @@ -696,6 +700,7 @@ struct VRCameraState double m_rootPosition[3]; double m_rootOrientation[4]; int m_trackingObjectUniqueId; + int m_trackingObjectFlag; }; diff --git a/examples/SharedMemory/SharedMemoryPublic.h b/examples/SharedMemory/SharedMemoryPublic.h index f451e7a79..0f4bb31cd 100644 --- a/examples/SharedMemory/SharedMemoryPublic.h +++ b/examples/SharedMemory/SharedMemoryPublic.h @@ -320,6 +320,11 @@ enum eVRDeviceTypeEnums VR_DEVICE_GENERIC_TRACKER=4, }; +enum EVRCameraFlags +{ + VR_CAMERA_TRACK_OBJECT_ORIENTATION=1, +}; + struct b3VRControllerEvent { int m_controllerId;//valid for VR_CONTROLLER_MOVE_EVENT and VR_CONTROLLER_BUTTON_EVENT @@ -495,6 +500,11 @@ enum b3ConfigureDebugVisualizerEnum COV_ENABLE_GUI=1, COV_ENABLE_SHADOWS, COV_ENABLE_WIREFRAME, + COV_ENABLE_VR_TELEPORTING, + COV_ENABLE_VR_PICKING, + COV_ENABLE_VR_RENDER_CONTROLLERS, + COV_ENABLE_RENDERING, + COV_ENABLE_SYNC_RENDERING_INTERNAL, }; enum eCONNECT_METHOD { diff --git a/examples/SharedMemory/TinyRendererVisualShapeConverter.cpp b/examples/SharedMemory/TinyRendererVisualShapeConverter.cpp index c8d4b92e7..8c03556cf 100644 --- a/examples/SharedMemory/TinyRendererVisualShapeConverter.cpp +++ b/examples/SharedMemory/TinyRendererVisualShapeConverter.cpp @@ -516,7 +516,6 @@ void TinyRendererVisualShapeConverter::convertVisualShapes( btAssert(linkPtr); // TODO: remove if (not doing it now, because diff will be 50+ lines) if (linkPtr) { - const btArray* shapeArray; bool useVisual; int cnt = 0; if (linkPtr->m_visualArray.size() > 0) diff --git a/examples/StandaloneMain/hellovr_opengl_main.cpp b/examples/StandaloneMain/hellovr_opengl_main.cpp index 518fc98e8..a430ea615 100644 --- a/examples/StandaloneMain/hellovr_opengl_main.cpp +++ b/examples/StandaloneMain/hellovr_opengl_main.cpp @@ -367,6 +367,49 @@ void MyKeyboardCallback(int key, int state) prevKeyboardCallback(key,state); } + + + + +#include "../SharedMemory/SharedMemoryPublic.h" +extern bool useShadowMap; +bool gEnableVRRenderControllers=true; + + + +void VRPhysicsServerVisualizerFlagCallback(int flag, bool enable) +{ + if (flag == COV_ENABLE_SHADOWS) + { + useShadowMap = enable; + } + if (flag == COV_ENABLE_GUI) + { + //there is no regular GUI here, but disable the + } + if (flag == COV_ENABLE_VR_RENDER_CONTROLLERS) + { + gEnableVRRenderControllers = enable; + } + + + + if (flag == COV_ENABLE_WIREFRAME) + { + if (enable) + { + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + //gDebugDrawFlags |= btIDebugDraw::DBG_DrawWireframe; + } else + { + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL); + //gDebugDrawFlags &= ~btIDebugDraw::DBG_DrawWireframe; + } + } + + +} + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -418,6 +461,7 @@ bool CMainApplication::BInit() sGuiPtr = new OpenGLGuiHelper(m_app,false); + sGuiPtr->setVisualizerFlagCallback(VRPhysicsServerVisualizerFlagCallback); sGuiPtr->setVRMode(true); //sGuiPtr = new DummyGUIHelper; @@ -773,6 +817,7 @@ bool CMainApplication::HandleInput() if (button==2) { //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + ///todo(erwincoumans) can't use reguar debug drawer, because physics/graphics are not in sync ///so it can (and likely will) cause crashes ///add a special debug drawer that deals with this @@ -810,7 +855,6 @@ bool CMainApplication::HandleInput() if (button==2) { gDebugDrawFlags = 0; - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL); } sExample->vrControllerButtonCallback(unDevice, button, 0, pos, orn); @@ -1379,6 +1423,8 @@ extern int gGraspingController; void CMainApplication::DrawControllers() { + + // don't draw controllers if somebody else has input focus if( m_pHMD->IsInputFocusCapturedByAnotherProcess() ) return; @@ -1866,39 +1912,42 @@ void CMainApplication::RenderScene( vr::Hmd_Eye nEye ) bool bIsInputCapturedByAnotherProcess = m_pHMD->IsInputFocusCapturedByAnotherProcess(); - if( !bIsInputCapturedByAnotherProcess ) + if (gEnableVRRenderControllers) { - // draw the controller axis lines - glUseProgram( m_unControllerTransformProgramID ); - glUniformMatrix4fv( m_nControllerMatrixLocation, 1, GL_FALSE, GetCurrentViewProjectionMatrix( nEye ).get() ); - glBindVertexArray( m_unControllerVAO ); - glDrawArrays( GL_LINES, 0, m_uiControllerVertcount ); - glBindVertexArray( 0 ); + if( !bIsInputCapturedByAnotherProcess ) + { + // draw the controller axis lines + glUseProgram( m_unControllerTransformProgramID ); + glUniformMatrix4fv( m_nControllerMatrixLocation, 1, GL_FALSE, GetCurrentViewProjectionMatrix( nEye ).get() ); + glBindVertexArray( m_unControllerVAO ); + glDrawArrays( GL_LINES, 0, m_uiControllerVertcount ); + glBindVertexArray( 0 ); + } + + // ----- Render Model rendering ----- + glUseProgram( m_unRenderModelProgramID ); + + for( uint32_t unTrackedDevice = 0; unTrackedDevice < vr::k_unMaxTrackedDeviceCount; unTrackedDevice++ ) + { + if( !m_rTrackedDeviceToRenderModel[ unTrackedDevice ] || !m_rbShowTrackedDevice[ unTrackedDevice ] ) + continue; + + const vr::TrackedDevicePose_t & pose = m_rTrackedDevicePose[ unTrackedDevice ]; + if( !pose.bPoseIsValid ) + continue; + + if( bIsInputCapturedByAnotherProcess && m_pHMD->GetTrackedDeviceClass( unTrackedDevice ) == vr::TrackedDeviceClass_Controller ) + continue; + + const Matrix4 & matDeviceToTracking = m_rmat4DevicePose[ unTrackedDevice ]; + Matrix4 matMVP = GetCurrentViewProjectionMatrix( nEye ) * matDeviceToTracking; + glUniformMatrix4fv( m_nRenderModelMatrixLocation, 1, GL_FALSE, matMVP.get() ); + + m_rTrackedDeviceToRenderModel[ unTrackedDevice ]->Draw(); + } } - - // ----- Render Model rendering ----- - glUseProgram( m_unRenderModelProgramID ); - - for( uint32_t unTrackedDevice = 0; unTrackedDevice < vr::k_unMaxTrackedDeviceCount; unTrackedDevice++ ) - { - if( !m_rTrackedDeviceToRenderModel[ unTrackedDevice ] || !m_rbShowTrackedDevice[ unTrackedDevice ] ) - continue; - - const vr::TrackedDevicePose_t & pose = m_rTrackedDevicePose[ unTrackedDevice ]; - if( !pose.bPoseIsValid ) - continue; - - if( bIsInputCapturedByAnotherProcess && m_pHMD->GetTrackedDeviceClass( unTrackedDevice ) == vr::TrackedDeviceClass_Controller ) - continue; - - const Matrix4 & matDeviceToTracking = m_rmat4DevicePose[ unTrackedDevice ]; - Matrix4 matMVP = GetCurrentViewProjectionMatrix( nEye ) * matDeviceToTracking; - glUniformMatrix4fv( m_nRenderModelMatrixLocation, 1, GL_FALSE, matMVP.get() ); - - m_rTrackedDeviceToRenderModel[ unTrackedDevice ]->Draw(); - } - - glUseProgram( 0 ); + glUseProgram( 0 ); + } diff --git a/examples/ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp b/examples/ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp index f56de333a..d8e3102a8 100644 --- a/examples/ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp +++ b/examples/ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp @@ -560,9 +560,12 @@ LoadObj( int maxchars = 8192; // Alloc enough size. std::vector buf(maxchars); // Alloc enough size. + std::string linebuf; + linebuf.reserve(maxchars); + while (ifs.peek() != -1) { - std::string linebuf; + linebuf.resize(0); safeGetline(ifs,linebuf); // Trim newline '\r\n' or '\r' diff --git a/examples/pybullet/pybullet.c b/examples/pybullet/pybullet.c index 51e40307f..16d4ca70a 100644 --- a/examples/pybullet/pybullet.c +++ b/examples/pybullet/pybullet.c @@ -95,6 +95,9 @@ static int pybullet_internalSetMatrix(PyObject* objMat, float matrix[16]) int i, len; PyObject* seq; + if (objMat==NULL) + return 0; + seq = PySequence_Fast(objMat, "expected a sequence"); if (seq) { @@ -123,6 +126,7 @@ static int pybullet_internalSetVector(PyObject* objVec, float vector[3]) { int i, len; PyObject* seq = 0; + if (objVec == NULL) return 0; @@ -720,13 +724,15 @@ static PyObject* pybullet_setPhysicsEngineParameter(PyObject* self, PyObject* ar int collisionFilterMode = -1; double contactBreakingThreshold = -1; int maxNumCmdPer1ms = -2; + int enableFileCaching = -1; + b3PhysicsClientHandle sm = 0; int physicsClientId = 0; - static char* kwlist[] = {"fixedTimeStep", "numSolverIterations", "useSplitImpulse", "splitImpulsePenetrationThreshold", "numSubSteps", "collisionFilterMode", "contactBreakingThreshold", "maxNumCmdPer1ms", "physicsClientId", NULL}; + static char* kwlist[] = {"fixedTimeStep", "numSolverIterations", "useSplitImpulse", "splitImpulsePenetrationThreshold", "numSubSteps", "collisionFilterMode", "contactBreakingThreshold", "maxNumCmdPer1ms", "enableFileCaching","physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "|diidiidii", kwlist, &fixedTimeStep, &numSolverIterations, &useSplitImpulse, &splitImpulsePenetrationThreshold, &numSubSteps, - &collisionFilterMode, &contactBreakingThreshold, &maxNumCmdPer1ms, &physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "|diidiidiii", kwlist, &fixedTimeStep, &numSolverIterations, &useSplitImpulse, &splitImpulsePenetrationThreshold, &numSubSteps, + &collisionFilterMode, &contactBreakingThreshold, &maxNumCmdPer1ms, &enableFileCaching, &physicsClientId)) { return NULL; } @@ -777,6 +783,11 @@ static PyObject* pybullet_setPhysicsEngineParameter(PyObject* self, PyObject* ar b3PhysicsParamSetMaxNumCommandsPer1ms(command, maxNumCmdPer1ms); } + if (enableFileCaching>=0) + { + b3PhysicsParamSetEnableFileCaching(command, enableFileCaching); + } + //ret = b3PhysicsParamSetRealTimeSimulation(command, enableRealTimeSimulation); statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); @@ -3699,11 +3710,12 @@ static PyObject* pybullet_setVRCameraState(PyObject* self, PyObject* args, PyObj PyObject* rootPosObj = 0; PyObject* rootOrnObj = 0; int trackObjectUid = -2; + int trackObjectFlag = -1; double rootPos[3]; double rootOrn[4]; - static char* kwlist[] = {"rootPosition", "rootOrientation", "trackObject", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "|OOii", kwlist, &rootPosObj, &rootOrnObj, &trackObjectUid, &physicsClientId)) + static char* kwlist[] = {"rootPosition", "rootOrientation", "trackObject", "trackObjectFlag","physicsClientId", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, keywds, "|OOiii", kwlist, &rootPosObj, &rootOrnObj, &trackObjectUid,&trackObjectFlag, &physicsClientId)) { return NULL; } @@ -3730,6 +3742,11 @@ static PyObject* pybullet_setVRCameraState(PyObject* self, PyObject* args, PyObj b3SetVRCameraTrackingObject(commandHandle, trackObjectUid); } + if (trackObjectFlag>=-1) + { + b3SetVRCameraTrackingObjectFlag(commandHandle, trackObjectFlag); + } + statusHandle = b3SubmitClientCommandAndWaitStatus(sm, commandHandle); statusType = b3GetStatusType(statusHandle); @@ -4543,7 +4560,7 @@ static PyObject* pybullet_enableJointForceTorqueSensor(PyObject* self, PyObject* b3PhysicsClientHandle sm = 0; int numJoints = -1; - static char* kwlist[] = {"bodyUniqueId", "jointIndex", "enableSensor", "physicsClientId"}; + static char* kwlist[] = {"bodyUniqueId", "jointIndex", "enableSensor", "physicsClientId",NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "ii|ii", kwlist, &bodyUniqueId, &jointIndex, &enableSensor, &physicsClientId)) { @@ -4755,12 +4772,13 @@ static PyObject* pybullet_getCameraImage(PyObject* self, PyObject* args, PyObjec float projectionMatrix[16]; float lightDir[3]; float lightColor[3]; - float lightDist = 10.0; - int hasShadow = 0; - float lightAmbientCoeff = 0.6; - float lightDiffuseCoeff = 0.35; - float lightSpecularCoeff = 0.05; - int renderer = 0; + float lightDist = -1; + int hasShadow = -1; + float lightAmbientCoeff = -1; + float lightDiffuseCoeff = -1; + float lightSpecularCoeff = -1; + + int renderer = -1; // inialize cmd b3SharedMemoryCommandHandle command; int physicsClientId = 0; @@ -4783,12 +4801,12 @@ static PyObject* pybullet_getCameraImage(PyObject* self, PyObject* args, PyObjec b3RequestCameraImageSetPixelResolution(command, width, height); // set camera matrices only if set matrix function succeeds - if (pybullet_internalSetMatrix(objViewMat, viewMatrix) && (pybullet_internalSetMatrix(objProjMat, projectionMatrix))) + if (objViewMat && objProjMat && pybullet_internalSetMatrix(objViewMat, viewMatrix) && (pybullet_internalSetMatrix(objProjMat, projectionMatrix))) { b3RequestCameraImageSetCameraMatrices(command, viewMatrix, projectionMatrix); } //set light direction only if function succeeds - if (pybullet_internalSetVector(lightDirObj, lightDir)) + if (lightDirObj && pybullet_internalSetVector(lightDirObj, lightDir)) { b3RequestCameraImageSetLightDirection(command, lightDir); } @@ -4797,16 +4815,34 @@ static PyObject* pybullet_getCameraImage(PyObject* self, PyObject* args, PyObjec { b3RequestCameraImageSetLightColor(command, lightColor); } + if (lightDist>=0) + { + b3RequestCameraImageSetLightDistance(command, lightDist); + } - b3RequestCameraImageSetLightDistance(command, lightDist); + if (hasShadow>=0) + { + b3RequestCameraImageSetShadow(command, hasShadow); + } + if (lightAmbientCoeff>=0) + { + b3RequestCameraImageSetLightAmbientCoeff(command, lightAmbientCoeff); + } + if (lightDiffuseCoeff>=0) + { + b3RequestCameraImageSetLightDiffuseCoeff(command, lightDiffuseCoeff); + } - b3RequestCameraImageSetShadow(command, hasShadow); + if (lightSpecularCoeff>=0) + { + b3RequestCameraImageSetLightSpecularCoeff(command, lightSpecularCoeff); + } - b3RequestCameraImageSetLightAmbientCoeff(command, lightAmbientCoeff); - b3RequestCameraImageSetLightDiffuseCoeff(command, lightDiffuseCoeff); - b3RequestCameraImageSetLightSpecularCoeff(command, lightSpecularCoeff); - - b3RequestCameraImageSelectRenderer(command, renderer);//renderer could be ER_BULLET_HARDWARE_OPENGL + if (renderer>=0) + { + b3RequestCameraImageSelectRenderer(command, renderer);//renderer could be ER_BULLET_HARDWARE_OPENGL + } + //PyErr_Clear(); if (b3CanSubmitCommand(sm)) { @@ -6332,6 +6368,8 @@ initpybullet(void) PyModule_AddIntConstant(m, "VR_DEVICE_HMD", VR_DEVICE_HMD); PyModule_AddIntConstant(m, "VR_DEVICE_GENERIC_TRACKER", VR_DEVICE_GENERIC_TRACKER); + PyModule_AddIntConstant(m, "VR_CAMERA_TRACK_OBJECT_ORIENTATION", VR_CAMERA_TRACK_OBJECT_ORIENTATION); + PyModule_AddIntConstant(m, "KEY_IS_DOWN", eButtonIsDown); PyModule_AddIntConstant(m, "KEY_WAS_TRIGGERED", eButtonTriggered); PyModule_AddIntConstant(m, "KEY_WAS_RELEASED", eButtonReleased); @@ -6346,6 +6384,11 @@ initpybullet(void) PyModule_AddIntConstant(m, "COV_ENABLE_GUI", COV_ENABLE_GUI); PyModule_AddIntConstant(m, "COV_ENABLE_SHADOWS", COV_ENABLE_SHADOWS); PyModule_AddIntConstant(m, "COV_ENABLE_WIREFRAME", COV_ENABLE_WIREFRAME); + PyModule_AddIntConstant(m, "COV_ENABLE_VR_PICKING", COV_ENABLE_VR_PICKING); + PyModule_AddIntConstant(m, "COV_ENABLE_VR_TELEPORTING", COV_ENABLE_VR_TELEPORTING); + PyModule_AddIntConstant(m, "COV_ENABLE_RENDERING", COV_ENABLE_RENDERING); + PyModule_AddIntConstant(m, "COV_ENABLE_VR_RENDER_CONTROLLERS", COV_ENABLE_VR_RENDER_CONTROLLERS); + PyModule_AddIntConstant(m, "ER_TINY_RENDERER", ER_TINY_RENDERER); PyModule_AddIntConstant(m, "ER_BULLET_HARDWARE_OPENGL", ER_BULLET_HARDWARE_OPENGL); diff --git a/setup.py b/setup.py index 23041e881..0365485f3 100644 --- a/setup.py +++ b/setup.py @@ -417,7 +417,7 @@ else: setup( name = 'pybullet', - version='1.0.4', + version='1.0.6', description='Official Python Interface for the Bullet Physics SDK Robotics Simulator', long_description='pybullet is an easy to use Python module for physics simulation, robotics and machine learning based on the Bullet Physics SDK. With pybullet you can load articulated bodies from URDF, SDF and other file formats. pybullet provides forward dynamics simulation, inverse dynamics computation, forward and inverse kinematics and collision detection and ray intersection queries. Aside from physics simulation, pybullet supports to rendering, with a CPU renderer and OpenGL visualization and support for virtual reality headsets.', url='https://github.com/bulletphysics/bullet3', diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp index 4c5a67689..2940f7550 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp @@ -1514,6 +1514,8 @@ void btCollisionWorld::debugDrawWorld() { if (getDebugDrawer()) { + getDebugDrawer()->clearLines(); + btIDebugDraw::DefaultColors defaultColors = getDebugDrawer()->getDefaultColors(); if ( getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints) diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp index 2bed4a3a7..9eacc2264 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp @@ -798,6 +798,8 @@ void btMultiBodyDynamicsWorld::debugDrawWorld() { BT_PROFILE("btMultiBodyDynamicsWorld debugDrawWorld"); + btDiscreteDynamicsWorld::debugDrawWorld(); + bool drawConstraints = false; if (getDebugDrawer()) { @@ -867,7 +869,7 @@ void btMultiBodyDynamicsWorld::debugDrawWorld() } } - btDiscreteDynamicsWorld::debugDrawWorld(); + } diff --git a/src/LinearMath/btIDebugDraw.h b/src/LinearMath/btIDebugDraw.h index a020c3f4e..936aaa896 100644 --- a/src/LinearMath/btIDebugDraw.h +++ b/src/LinearMath/btIDebugDraw.h @@ -469,6 +469,10 @@ class btIDebugDraw drawLine(transform*pt2,transform*pt3,color); } + virtual void clearLines() + { + } + virtual void flushLines() { }