mirror of
https://github.com/bulletphysics/bullet3
synced 2024-12-14 13:50:04 +00:00
c28cd03fbd
Compile using premake+visual studio, and compile App_SharedMemoryPhysics_VR Compile pybullet using cmake using cmake -DBUILD_PYBULLET=OFF -DCMAKE_BUILD_TYPE=Release .. Create a symbolic link from c:\python\dlls\pybullet.pyd to C:\develop\bullet3\cmp\lib\Release\pybullet.dll App_SharedMemoryPhysics_VR Run Python. Here are some Python lines to get going: import pybullet as p p.connect(p.SHARED_MEMORY) p.loadURDF("cube.urdf") p.setGravity(0,0,-10) p.setRealTimeSimulation(1) Allow real-time simulation in physics server, add pybullet command setRealTimeSimulation to control it Mesh decimation (reduce number of triangles/vertices) using a Blender modifier for Kuka IIWA and Husky Disabled the 'glFlush' commands in GLInstancingRenderer. Add VR controller methods to examples\CommonInterfaces\CommonExampleInterface.h Use the ANSI version in Windows file/string operations instead of unicode, hope this doesn't break builds.
312 lines
7.7 KiB
C++
312 lines
7.7 KiB
C++
#include "PhysicsServerSharedMemory.h"
|
|
#include "PosixSharedMemory.h"
|
|
#include "Win32SharedMemory.h"
|
|
|
|
#include "../CommonInterfaces/CommonRenderInterface.h"
|
|
|
|
#include "btBulletDynamicsCommon.h"
|
|
|
|
#include "LinearMath/btTransform.h"
|
|
|
|
#include "Bullet3Common/b3Logging.h"
|
|
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
|
#include "SharedMemoryBlock.h"
|
|
|
|
#include "PhysicsServerCommandProcessor.h"
|
|
|
|
|
|
|
|
struct PhysicsServerSharedMemoryInternalData
|
|
{
|
|
|
|
///end handle management
|
|
|
|
|
|
SharedMemoryInterface* m_sharedMemory;
|
|
bool m_ownsSharedMemory;
|
|
|
|
SharedMemoryBlock* m_testBlock1;
|
|
int m_sharedMemoryKey;
|
|
bool m_isConnected;
|
|
bool m_verboseOutput;
|
|
PhysicsServerCommandProcessor* m_commandProcessor;
|
|
|
|
PhysicsServerSharedMemoryInternalData()
|
|
:m_sharedMemory(0),
|
|
m_ownsSharedMemory(false),
|
|
m_testBlock1(0),
|
|
m_sharedMemoryKey(SHARED_MEMORY_KEY),
|
|
m_isConnected(false),
|
|
m_verboseOutput(false),
|
|
m_commandProcessor(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
SharedMemoryStatus& createServerStatus(int statusType, int sequenceNumber, int timeStamp)
|
|
{
|
|
SharedMemoryStatus& serverCmd =m_testBlock1->m_serverCommands[0];
|
|
serverCmd .m_type = statusType;
|
|
serverCmd.m_sequenceNumber = sequenceNumber;
|
|
serverCmd.m_timeStamp = timeStamp;
|
|
return serverCmd;
|
|
}
|
|
void submitServerStatus(SharedMemoryStatus& status)
|
|
{
|
|
m_testBlock1->m_numServerCommands++;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
PhysicsServerSharedMemory::PhysicsServerSharedMemory(SharedMemoryInterface* sharedMem)
|
|
{
|
|
m_data = new PhysicsServerSharedMemoryInternalData();
|
|
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 = new PhysicsServerCommandProcessor;
|
|
|
|
|
|
}
|
|
|
|
PhysicsServerSharedMemory::~PhysicsServerSharedMemory()
|
|
{
|
|
m_data->m_commandProcessor->deleteDynamicsWorld();
|
|
delete 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;
|
|
|
|
|
|
if (m_data->m_isConnected)
|
|
{
|
|
b3Warning("connectSharedMemory, while already connected");
|
|
return m_data->m_isConnected;
|
|
}
|
|
|
|
|
|
int counter = 0;
|
|
do
|
|
{
|
|
|
|
m_data->m_testBlock1 = (SharedMemoryBlock*)m_data->m_sharedMemory->allocateSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE,allowCreation);
|
|
if (m_data->m_testBlock1)
|
|
{
|
|
int magicId =m_data->m_testBlock1->m_magicId;
|
|
if (m_data->m_verboseOutput)
|
|
{
|
|
b3Printf("magicId = %d\n", magicId);
|
|
}
|
|
|
|
if (m_data->m_testBlock1->m_magicId !=SHARED_MEMORY_MAGIC_NUMBER)
|
|
{
|
|
InitSharedMemoryBlock(m_data->m_testBlock1);
|
|
if (m_data->m_verboseOutput)
|
|
{
|
|
b3Printf("Created and initialized shared memory block\n");
|
|
}
|
|
m_data->m_isConnected = true;
|
|
} else
|
|
{
|
|
m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE);
|
|
m_data->m_testBlock1 = 0;
|
|
m_data->m_isConnected = false;
|
|
}
|
|
} else
|
|
{
|
|
b3Error("Cannot connect to shared memory");
|
|
m_data->m_isConnected = false;
|
|
}
|
|
} while (counter++ < 10 && !m_data->m_isConnected);
|
|
|
|
if (!m_data->m_isConnected)
|
|
{
|
|
b3Error("Server cannot connect to shared memory.\n");
|
|
}
|
|
|
|
return m_data->m_isConnected;
|
|
}
|
|
|
|
|
|
void PhysicsServerSharedMemory::disconnectSharedMemory(bool deInitializeSharedMemory)
|
|
{
|
|
m_data->m_commandProcessor->setGuiHelper(0);
|
|
|
|
if (m_data->m_verboseOutput)
|
|
{
|
|
b3Printf("releaseSharedMemory1\n");
|
|
}
|
|
if (m_data->m_testBlock1)
|
|
{
|
|
if (m_data->m_verboseOutput)
|
|
{
|
|
b3Printf("m_testBlock1\n");
|
|
}
|
|
if (deInitializeSharedMemory)
|
|
{
|
|
m_data->m_testBlock1->m_magicId = 0;
|
|
if (m_data->m_verboseOutput)
|
|
{
|
|
b3Printf("De-initialized shared memory, magic id = %d\n",m_data->m_testBlock1->m_magicId);
|
|
}
|
|
}
|
|
btAssert(m_data->m_sharedMemory);
|
|
m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE);
|
|
}
|
|
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_testBlock1 = 0;
|
|
}
|
|
}
|
|
|
|
void PhysicsServerSharedMemory::releaseSharedMemory()
|
|
{
|
|
if (m_data->m_verboseOutput)
|
|
{
|
|
b3Printf("releaseSharedMemory1\n");
|
|
}
|
|
if (m_data->m_testBlock1)
|
|
{
|
|
if (m_data->m_verboseOutput)
|
|
{
|
|
b3Printf("m_testBlock1\n");
|
|
}
|
|
m_data->m_testBlock1->m_magicId = 0;
|
|
if (m_data->m_verboseOutput)
|
|
{
|
|
b3Printf("magic id = %d\n",m_data->m_testBlock1->m_magicId);
|
|
}
|
|
btAssert(m_data->m_sharedMemory);
|
|
m_data->m_sharedMemory->releaseSharedMemory( m_data->m_sharedMemoryKey
|
|
, SHARED_MEMORY_SIZE);
|
|
}
|
|
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_testBlock1 = 0;
|
|
}
|
|
}
|
|
|
|
|
|
void PhysicsServerSharedMemory::stepSimulationRealTime(double dtInSec)
|
|
{
|
|
m_data->m_commandProcessor->stepSimulationRealTime(dtInSec);
|
|
}
|
|
|
|
|
|
void PhysicsServerSharedMemory::processClientCommands()
|
|
{
|
|
if (m_data->m_isConnected && m_data->m_testBlock1)
|
|
{
|
|
m_data->m_commandProcessor->replayLogCommand(&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
|
|
|
|
///we ignore overflow of integer for now
|
|
if (m_data->m_testBlock1->m_numClientCommands> m_data->m_testBlock1->m_numProcessedClientCommands)
|
|
{
|
|
|
|
|
|
//until we implement a proper ring buffer, we assume always maximum of 1 outstanding commands
|
|
btAssert(m_data->m_testBlock1->m_numClientCommands==m_data->m_testBlock1->m_numProcessedClientCommands+1);
|
|
|
|
const SharedMemoryCommand& clientCmd =m_data->m_testBlock1->m_clientCommands[0];
|
|
|
|
m_data->m_testBlock1->m_numProcessedClientCommands++;
|
|
//todo, timeStamp
|
|
int timeStamp = 0;
|
|
SharedMemoryStatus& serverStatusOut = m_data->createServerStatus(CMD_BULLET_DATA_STREAM_RECEIVED_COMPLETED,clientCmd.m_sequenceNumber,timeStamp);
|
|
bool hasStatus = m_data->m_commandProcessor->processCommand(clientCmd, serverStatusOut,&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
|
|
if (hasStatus)
|
|
{
|
|
m_data->submitServerStatus(serverStatusOut);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
void PhysicsServerSharedMemory::renderScene()
|
|
{
|
|
m_data->m_commandProcessor->renderScene();
|
|
|
|
|
|
|
|
}
|
|
|
|
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);
|
|
}
|