2015-05-28 23:05:24 +00:00
# include "PhysicsServer.h"
# include "PosixSharedMemory.h"
2015-06-04 22:37:18 +00:00
# include "Win32SharedMemory.h"
2015-07-04 01:17:14 +00:00
# include "../Importers/ImportURDFDemo/BulletUrdfImporter.h"
2015-05-29 00:49:55 +00:00
# include "../Importers/ImportURDFDemo/MyMultiBodyCreator.h"
# include "../Importers/ImportURDFDemo/URDF2Bullet.h"
2015-07-14 22:30:17 +00:00
# include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h"
# include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
# include "BulletDynamics/Featherstone/btMultiBodyPoint2Point.h"
# include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
2015-08-02 21:00:43 +00:00
# include "BulletDynamics/Featherstone/btMultiBodyJointFeedback.h"
2015-08-07 07:13:26 +00:00
# include "../CommonInterfaces/CommonRenderInterface.h"
2015-07-14 22:30:17 +00:00
# include "btBulletDynamicsCommon.h"
2015-09-03 21:18:22 +00:00
# include "LinearMath/btTransform.h"
2015-08-07 07:13:26 +00:00
2015-07-09 21:04:58 +00:00
# include "../Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h"
2015-07-14 15:34:02 +00:00
# include "BulletDynamics/Featherstone/btMultiBodyJointMotor.h"
2015-07-14 22:30:17 +00:00
# include "LinearMath/btSerializer.h"
# include "Bullet3Common/b3Logging.h"
# include "../CommonInterfaces/CommonGUIHelperInterface.h"
2015-07-23 18:51:25 +00:00
# include "SharedMemoryBlock.h"
2015-05-29 00:49:55 +00:00
2015-07-11 05:20:06 +00:00
struct UrdfLinkNameMapUtil
{
btMultiBody * m_mb ;
btDefaultSerializer * m_memSerializer ;
2015-05-28 23:05:24 +00:00
2015-07-11 05:20:06 +00:00
UrdfLinkNameMapUtil ( ) : m_mb ( 0 ) , m_memSerializer ( 0 )
{
}
} ;
2015-05-28 23:05:24 +00:00
2015-08-20 05:51:16 +00:00
struct SharedMemoryDebugDrawer : public btIDebugDraw
{
int m_debugMode ;
2015-09-03 21:18:22 +00:00
btAlignedObjectArray < SharedMemLines > m_lines2 ;
2015-08-20 05:51:16 +00:00
SharedMemoryDebugDrawer ( )
: m_debugMode ( 0 )
{
}
virtual void drawContactPoint ( const btVector3 & PointOnB , const btVector3 & normalOnB , btScalar distance , int lifeTime , const btVector3 & color )
{
}
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 drawLine ( const btVector3 & from , const btVector3 & to , const btVector3 & color )
{
SharedMemLines line ;
line . m_from = from ;
line . m_to = to ;
line . m_color = color ;
2015-09-03 21:18:22 +00:00
m_lines2 . push_back ( line ) ;
2015-08-20 05:51:16 +00:00
}
} ;
2015-10-13 18:32:25 +00:00
struct InteralBodyData
{
btMultiBody * m_multiBody ;
int m_testData ;
btTransform m_rootLocalInertialFrame ;
InteralBodyData ( )
: m_multiBody ( 0 ) ,
m_testData ( 0 )
{
m_rootLocalInertialFrame . setIdentity ( ) ;
}
} ;
///todo: templatize this
struct InternalBodyHandle : public InteralBodyData
{
BT_DECLARE_ALIGNED_ALLOCATOR ( ) ;
int m_nextFreeHandle ;
void SetNextFree ( int next )
{
m_nextFreeHandle = next ;
}
int GetNextFree ( ) const
{
return m_nextFreeHandle ;
}
} ;
2015-07-14 22:30:17 +00:00
struct PhysicsServerInternalData
2015-05-28 23:05:24 +00:00
{
2015-10-13 18:32:25 +00:00
///handle management
btAlignedObjectArray < InternalBodyHandle > m_bodyHandles ;
int m_numUsedHandles ; // number of active handles
int m_firstFreeHandle ; // free handles list
InternalBodyHandle * getHandle ( int handle )
{
btAssert ( handle > = 0 ) ;
btAssert ( handle < m_bodyHandles . size ( ) ) ;
if ( ( handle < 0 ) | | ( handle > = m_bodyHandles . size ( ) ) )
{
return 0 ;
}
return & m_bodyHandles [ handle ] ;
}
const InternalBodyHandle * getHandle ( int handle ) const
{
return & m_bodyHandles [ handle ] ;
}
void increaseHandleCapacity ( int extraCapacity )
{
int curCapacity = m_bodyHandles . size ( ) ;
btAssert ( curCapacity = = m_numUsedHandles ) ;
int newCapacity = curCapacity + extraCapacity ;
m_bodyHandles . resize ( newCapacity ) ;
{
for ( int i = curCapacity ; i < newCapacity ; i + + )
m_bodyHandles [ i ] . SetNextFree ( i + 1 ) ;
m_bodyHandles [ newCapacity - 1 ] . SetNextFree ( - 1 ) ;
}
m_firstFreeHandle = curCapacity ;
}
void initHandles ( )
{
m_numUsedHandles = 0 ;
m_firstFreeHandle = - 1 ;
increaseHandleCapacity ( 1 ) ;
}
void exitHandles ( )
{
m_bodyHandles . resize ( 0 ) ;
m_firstFreeHandle = - 1 ;
m_numUsedHandles = 0 ;
}
int allocHandle ( )
{
btAssert ( m_firstFreeHandle > = 0 ) ;
int handle = m_firstFreeHandle ;
m_firstFreeHandle = getHandle ( handle ) - > GetNextFree ( ) ;
m_numUsedHandles + + ;
if ( m_firstFreeHandle < 0 )
{
int curCapacity = m_bodyHandles . size ( ) ;
int additionalCapacity = m_bodyHandles . size ( ) ;
increaseHandleCapacity ( additionalCapacity ) ;
getHandle ( handle ) - > SetNextFree ( m_firstFreeHandle ) ;
}
return handle ;
}
void freeHandle ( int handle )
{
btAssert ( handle > = 0 ) ;
getHandle ( handle ) - > SetNextFree ( m_firstFreeHandle ) ;
m_firstFreeHandle = handle ;
m_numUsedHandles - - ;
}
///end handle management
2015-05-28 23:05:24 +00:00
SharedMemoryInterface * m_sharedMemory ;
2015-07-23 18:51:25 +00:00
SharedMemoryBlock * m_testBlock1 ;
2015-07-14 22:30:17 +00:00
bool m_isConnected ;
2015-07-21 06:35:29 +00:00
btScalar m_physicsDeltaTime ;
2015-08-02 21:00:43 +00:00
btAlignedObjectArray < btMultiBodyJointFeedback * > m_multiBodyJointFeedbacks ;
2015-06-10 01:13:05 +00:00
2015-10-13 18:32:25 +00:00
2015-07-09 21:04:58 +00:00
btAlignedObjectArray < btBulletWorldImporter * > m_worldImporters ;
2015-07-11 05:20:06 +00:00
btAlignedObjectArray < UrdfLinkNameMapUtil * > m_urdfLinkNameMapper ;
2015-07-14 15:34:02 +00:00
btHashMap < btHashInt , btMultiBodyJointMotor * > m_multiBodyJointMotorMap ;
2015-07-11 05:20:06 +00:00
btAlignedObjectArray < std : : string * > m_strings ;
2015-05-29 22:04:05 +00:00
2015-08-07 07:13:26 +00:00
btAlignedObjectArray < btCollisionShape * > m_collisionShapes ;
btBroadphaseInterface * m_broadphase ;
btCollisionDispatcher * m_dispatcher ;
btMultiBodyConstraintSolver * m_solver ;
btDefaultCollisionConfiguration * m_collisionConfiguration ;
2015-07-14 22:30:17 +00:00
btMultiBodyDynamicsWorld * m_dynamicsWorld ;
2015-08-20 05:51:16 +00:00
SharedMemoryDebugDrawer * m_debugDrawer ;
2015-10-13 18:32:25 +00:00
2015-09-03 21:18:22 +00:00
2015-07-14 22:30:17 +00:00
struct GUIHelperInterface * m_guiHelper ;
2015-08-07 07:13:26 +00:00
int m_sharedMemoryKey ;
2015-07-14 22:30:17 +00:00
2015-08-20 05:51:16 +00:00
bool m_verboseOutput ;
2015-08-07 07:13:26 +00:00
2015-09-04 18:28:08 +00:00
//data for picking objects
class btRigidBody * m_pickedBody ;
class btTypedConstraint * m_pickedConstraint ;
class btMultiBodyPoint2Point * m_pickingMultiBodyPoint2Point ;
btVector3 m_oldPickingPos ;
btVector3 m_hitPos ;
btScalar m_oldPickingDist ;
bool m_prevCanSleep ;
2015-07-14 22:30:17 +00:00
PhysicsServerInternalData ( )
: m_sharedMemory ( 0 ) ,
m_testBlock1 ( 0 ) ,
m_isConnected ( false ) ,
2015-08-20 21:57:14 +00:00
m_physicsDeltaTime ( 1. / 240. ) ,
2015-07-14 22:30:17 +00:00
m_dynamicsWorld ( 0 ) ,
2015-08-20 05:51:16 +00:00
m_debugDrawer ( 0 ) ,
2015-08-07 07:13:26 +00:00
m_guiHelper ( 0 ) ,
2015-08-20 05:51:16 +00:00
m_sharedMemoryKey ( SHARED_MEMORY_KEY ) ,
2015-09-04 18:28:08 +00:00
m_verboseOutput ( false ) ,
m_pickedBody ( 0 ) ,
m_pickedConstraint ( 0 ) ,
m_pickingMultiBodyPoint2Point ( 0 )
2015-05-28 23:05:24 +00:00
{
2015-10-13 18:32:25 +00:00
initHandles ( ) ;
#if 0
btAlignedObjectArray < int > bla ;
for ( int i = 0 ; i < 1024 ; i + + )
{
int handle = allocHandle ( ) ;
bla . push_back ( handle ) ;
InternalBodyHandle * body = getHandle ( handle ) ;
InteralBodyData * body2 = body ;
}
for ( int i = 0 ; i < bla . size ( ) ; i + + )
{
freeHandle ( bla [ i ] ) ;
}
bla . resize ( 0 ) ;
for ( int i = 0 ; i < 1024 ; i + + )
{
int handle = allocHandle ( ) ;
bla . push_back ( handle ) ;
InternalBodyHandle * body = getHandle ( handle ) ;
InteralBodyData * body2 = body ;
}
for ( int i = 0 ; i < bla . size ( ) ; i + + )
{
freeHandle ( bla [ i ] ) ;
}
bla . resize ( 0 ) ;
for ( int i = 0 ; i < 1024 ; i + + )
{
int handle = allocHandle ( ) ;
bla . push_back ( handle ) ;
InternalBodyHandle * body = getHandle ( handle ) ;
InteralBodyData * body2 = body ;
}
for ( int i = 0 ; i < bla . size ( ) ; i + + )
{
freeHandle ( bla [ i ] ) ;
}
# endif
2015-05-28 23:05:24 +00:00
}
2015-07-31 06:22:44 +00:00
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 + + ;
}
2015-05-28 23:05:24 +00:00
} ;
2015-07-14 22:30:17 +00:00
PhysicsServerSharedMemory : : PhysicsServerSharedMemory ( )
2015-05-28 23:05:24 +00:00
{
2015-07-14 22:30:17 +00:00
m_data = new PhysicsServerInternalData ( ) ;
# ifdef _WIN32
m_data - > m_sharedMemory = new Win32SharedMemoryServer ( ) ;
# else
m_data - > m_sharedMemory = new PosixSharedMemory ( ) ;
# endif
2015-08-07 07:13:26 +00:00
createEmptyDynamicsWorld ( ) ;
2015-07-14 22:30:17 +00:00
2015-05-29 22:04:05 +00:00
}
2015-07-14 22:30:17 +00:00
PhysicsServerSharedMemory : : ~ PhysicsServerSharedMemory ( )
2015-05-29 22:04:05 +00:00
{
2015-08-07 07:13:26 +00:00
deleteDynamicsWorld ( ) ;
2015-07-14 22:30:17 +00:00
delete m_data ;
2015-05-28 23:05:24 +00:00
}
2015-08-07 07:13:26 +00:00
void PhysicsServerSharedMemory : : setSharedMemoryKey ( int key )
{
m_data - > m_sharedMemoryKey = key ;
}
2015-07-14 22:30:17 +00:00
2015-08-07 07:13:26 +00:00
void PhysicsServerSharedMemory : : createEmptyDynamicsWorld ( )
{
///collision configuration contains default setup for memory, collision setup
m_data - > m_collisionConfiguration = new btDefaultCollisionConfiguration ( ) ;
//m_collisionConfiguration->setConvexConvexMultipointIterations();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_data - > m_dispatcher = new btCollisionDispatcher ( m_data - > m_collisionConfiguration ) ;
m_data - > m_broadphase = new btDbvtBroadphase ( ) ;
m_data - > m_solver = new btMultiBodyConstraintSolver ;
m_data - > m_dynamicsWorld = new btMultiBodyDynamicsWorld ( m_data - > m_dispatcher , m_data - > m_broadphase , m_data - > m_solver , m_data - > m_collisionConfiguration ) ;
2015-08-20 05:51:16 +00:00
m_data - > m_debugDrawer = new SharedMemoryDebugDrawer ( ) ;
m_data - > m_dynamicsWorld - > setDebugDrawer ( m_data - > m_debugDrawer ) ;
2015-08-07 07:13:26 +00:00
2015-08-07 20:17:33 +00:00
m_data - > m_dynamicsWorld - > setGravity ( btVector3 ( 0 , 0 , 0 ) ) ;
2015-08-07 07:13:26 +00:00
}
void PhysicsServerSharedMemory : : deleteDynamicsWorld ( )
{
for ( int i = 0 ; i < m_data - > m_multiBodyJointFeedbacks . size ( ) ; i + + )
{
delete m_data - > m_multiBodyJointFeedbacks [ i ] ;
}
m_data - > m_multiBodyJointFeedbacks . clear ( ) ;
for ( int i = 0 ; i < m_data - > m_worldImporters . size ( ) ; i + + )
{
delete m_data - > m_worldImporters [ i ] ;
}
m_data - > m_worldImporters . clear ( ) ;
for ( int i = 0 ; i < m_data - > m_urdfLinkNameMapper . size ( ) ; i + + )
{
delete m_data - > m_urdfLinkNameMapper [ i ] ;
}
m_data - > m_urdfLinkNameMapper . clear ( ) ;
m_data - > m_multiBodyJointMotorMap . clear ( ) ;
for ( int i = 0 ; i < m_data - > m_strings . size ( ) ; i + + )
{
delete m_data - > m_strings [ i ] ;
}
m_data - > m_strings . clear ( ) ;
if ( m_data - > m_dynamicsWorld )
{
int i ;
for ( i = m_data - > m_dynamicsWorld - > getNumConstraints ( ) - 1 ; i > = 0 ; i - - )
{
m_data - > m_dynamicsWorld - > removeConstraint ( m_data - > m_dynamicsWorld - > getConstraint ( i ) ) ;
}
for ( i = m_data - > m_dynamicsWorld - > getNumCollisionObjects ( ) - 1 ; i > = 0 ; i - - )
{
btCollisionObject * obj = m_data - > m_dynamicsWorld - > getCollisionObjectArray ( ) [ i ] ;
btRigidBody * body = btRigidBody : : upcast ( obj ) ;
if ( body & & body - > getMotionState ( ) )
{
delete body - > getMotionState ( ) ;
}
m_data - > m_dynamicsWorld - > removeCollisionObject ( obj ) ;
delete obj ;
}
}
//delete collision shapes
for ( int j = 0 ; j < m_data - > m_collisionShapes . size ( ) ; j + + )
{
btCollisionShape * shape = m_data - > m_collisionShapes [ j ] ;
delete shape ;
}
m_data - > m_collisionShapes . clear ( ) ;
delete m_data - > m_dynamicsWorld ;
2015-08-07 20:17:33 +00:00
m_data - > m_dynamicsWorld = 0 ;
2015-08-07 07:13:26 +00:00
2015-08-20 05:51:16 +00:00
delete m_data - > m_debugDrawer ;
m_data - > m_debugDrawer = 0 ;
2015-08-07 07:13:26 +00:00
delete m_data - > m_solver ;
2015-08-07 20:17:33 +00:00
m_data - > m_solver = 0 ;
2015-08-07 07:13:26 +00:00
delete m_data - > m_broadphase ;
2015-08-07 20:17:33 +00:00
m_data - > m_broadphase = 0 ;
2015-08-07 07:13:26 +00:00
delete m_data - > m_dispatcher ;
2015-08-07 20:17:33 +00:00
m_data - > m_dispatcher = 0 ;
2015-08-07 07:13:26 +00:00
delete m_data - > m_collisionConfiguration ;
2015-08-07 20:17:33 +00:00
m_data - > m_collisionConfiguration = 0 ;
2015-08-07 07:13:26 +00:00
}
bool PhysicsServerSharedMemory : : connectSharedMemory ( struct GUIHelperInterface * guiHelper )
2015-05-28 23:05:24 +00:00
{
2015-07-14 22:30:17 +00:00
m_data - > m_guiHelper = guiHelper ;
bool allowCreation = true ;
2015-08-02 21:00:43 +00:00
bool allowConnectToExistingSharedMemory = false ;
2015-07-14 22:30:17 +00:00
2015-08-06 18:59:31 +00:00
if ( m_data - > m_isConnected )
{
b3Warning ( " connectSharedMemory, while already connected " ) ;
return m_data - > m_isConnected ;
}
2015-08-07 07:13:26 +00:00
m_data - > m_testBlock1 = ( SharedMemoryBlock * ) m_data - > m_sharedMemory - > allocateSharedMemory ( m_data - > m_sharedMemoryKey , SHARED_MEMORY_SIZE , allowCreation ) ;
2015-07-14 22:30:17 +00:00
if ( m_data - > m_testBlock1 )
2015-05-28 23:05:24 +00:00
{
2015-08-06 18:59:31 +00:00
int magicId = m_data - > m_testBlock1 - > m_magicId ;
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " magicId = %d \n " , magicId ) ;
}
2015-08-06 18:59:31 +00:00
if ( m_data - > m_testBlock1 - > m_magicId ! = SHARED_MEMORY_MAGIC_NUMBER )
2015-05-28 23:05:24 +00:00
{
2015-08-06 18:59:31 +00:00
InitSharedMemoryBlock ( m_data - > m_testBlock1 ) ;
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " Created and initialized shared memory block \n " ) ;
}
2015-08-06 18:59:31 +00:00
m_data - > m_isConnected = true ;
2015-07-14 22:30:17 +00:00
} else
{
2015-08-06 18:59:31 +00:00
b3Error ( " Server cannot connect to existing shared memory, disconnecting shared memory. \n " ) ;
2015-08-07 07:13:26 +00:00
m_data - > m_sharedMemory - > releaseSharedMemory ( m_data - > m_sharedMemoryKey , SHARED_MEMORY_SIZE ) ;
2015-08-06 18:59:31 +00:00
m_data - > m_testBlock1 = 0 ;
m_data - > m_isConnected = false ;
2015-07-14 22:30:17 +00:00
}
2015-05-28 23:05:24 +00:00
} else
2015-07-14 22:30:17 +00:00
{
b3Error ( " Cannot connect to shared memory " ) ;
2015-08-06 18:59:31 +00:00
m_data - > m_isConnected = false ;
2015-07-14 22:30:17 +00:00
}
2015-08-06 18:59:31 +00:00
return m_data - > m_isConnected ;
2015-05-28 23:05:24 +00:00
}
2015-05-29 22:04:05 +00:00
2015-07-14 22:30:17 +00:00
void PhysicsServerSharedMemory : : disconnectSharedMemory ( bool deInitializeSharedMemory )
2015-05-29 22:04:05 +00:00
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " releaseSharedMemory1 \n " ) ;
}
2015-07-14 22:30:17 +00:00
if ( m_data - > m_testBlock1 )
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " m_testBlock1 \n " ) ;
}
2015-07-14 22:30:17 +00:00
if ( deInitializeSharedMemory )
{
m_data - > m_testBlock1 - > m_magicId = 0 ;
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " De-initialized shared memory, magic id = %d \n " , m_data - > m_testBlock1 - > m_magicId ) ;
}
2015-07-14 22:30:17 +00:00
}
btAssert ( m_data - > m_sharedMemory ) ;
2015-08-07 07:13:26 +00:00
m_data - > m_sharedMemory - > releaseSharedMemory ( m_data - > m_sharedMemoryKey , SHARED_MEMORY_SIZE ) ;
2015-07-14 22:30:17 +00:00
}
if ( m_data - > m_sharedMemory )
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " m_sharedMemory \n " ) ;
}
2015-07-14 22:30:17 +00:00
delete m_data - > m_sharedMemory ;
m_data - > m_sharedMemory = 0 ;
m_data - > m_testBlock1 = 0 ;
}
}
void PhysicsServerSharedMemory : : releaseSharedMemory ( )
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " releaseSharedMemory1 \n " ) ;
}
2015-07-14 22:30:17 +00:00
if ( m_data - > m_testBlock1 )
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " m_testBlock1 \n " ) ;
}
2015-07-14 22:30:17 +00:00
m_data - > m_testBlock1 - > m_magicId = 0 ;
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " magic id = %d \n " , m_data - > m_testBlock1 - > m_magicId ) ;
}
2015-07-14 22:30:17 +00:00
btAssert ( m_data - > m_sharedMemory ) ;
2015-08-07 07:13:26 +00:00
m_data - > m_sharedMemory - > releaseSharedMemory ( m_data - > m_sharedMemoryKey
, SHARED_MEMORY_SIZE ) ;
2015-07-14 22:30:17 +00:00
}
if ( m_data - > m_sharedMemory )
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " m_sharedMemory \n " ) ;
}
2015-07-14 22:30:17 +00:00
delete m_data - > m_sharedMemory ;
m_data - > m_sharedMemory = 0 ;
m_data - > m_testBlock1 = 0 ;
}
2015-05-29 22:04:05 +00:00
}
2015-07-14 15:34:02 +00:00
2015-07-14 22:30:17 +00:00
bool PhysicsServerSharedMemory : : supportsJointMotor ( btMultiBody * mb , int mbLinkIndex )
2015-07-14 15:34:02 +00:00
{
bool canHaveMotor = ( mb - > getLink ( mbLinkIndex ) . m_jointType = = btMultibodyLink : : eRevolute
| | mb - > getLink ( mbLinkIndex ) . m_jointType = = btMultibodyLink : : ePrismatic ) ;
return canHaveMotor ;
}
//for testing, create joint motors for revolute and prismatic joints
2015-07-14 22:30:17 +00:00
void PhysicsServerSharedMemory : : createJointMotors ( btMultiBody * mb )
2015-07-14 15:34:02 +00:00
{
int numLinks = mb - > getNumLinks ( ) ;
for ( int i = 0 ; i < numLinks ; i + + )
{
int mbLinkIndex = i ;
if ( supportsJointMotor ( mb , mbLinkIndex ) )
{
float maxMotorImpulse = 0.f ;
int dof = 0 ;
btScalar desiredVelocity = 0.f ;
btMultiBodyJointMotor * motor = new btMultiBodyJointMotor ( mb , mbLinkIndex , dof , desiredVelocity , maxMotorImpulse ) ;
//motor->setMaxAppliedImpulse(0);
2015-07-14 22:30:17 +00:00
m_data - > m_multiBodyJointMotorMap . insert ( mbLinkIndex , motor ) ;
m_data - > m_dynamicsWorld - > addMultiBodyConstraint ( motor ) ;
2015-07-14 15:34:02 +00:00
}
}
}
2015-07-14 22:30:17 +00:00
bool PhysicsServerSharedMemory : : loadUrdf ( const char * fileName , const btVector3 & pos , const btQuaternion & orn ,
2015-10-13 18:32:25 +00:00
bool useMultiBody , bool useFixedBase , int * bodyUniqueIdPtr )
2015-05-29 00:49:55 +00:00
{
2015-07-14 22:30:17 +00:00
btAssert ( m_data - > m_dynamicsWorld ) ;
if ( ! m_data - > m_dynamicsWorld )
{
b3Error ( " loadUrdf: No valid m_dynamicsWorld " ) ;
return false ;
}
BulletURDFImporter u2b ( m_data - > m_guiHelper ) ;
2015-09-03 21:18:22 +00:00
2015-07-14 23:23:01 +00:00
bool loadOk = u2b . loadURDF ( fileName , useFixedBase ) ;
2015-05-29 00:49:55 +00:00
if ( loadOk )
{
2015-10-13 18:32:25 +00:00
//get a body index
int bodyUniqueId = m_data - > allocHandle ( ) ;
if ( bodyUniqueIdPtr )
* bodyUniqueIdPtr = bodyUniqueId ;
InternalBodyHandle * bodyHandle = m_data - > getHandle ( bodyUniqueId ) ;
2015-09-03 21:18:22 +00:00
{
btScalar mass = 0 ;
2015-10-13 18:32:25 +00:00
bodyHandle - > m_rootLocalInertialFrame . setIdentity ( ) ;
2015-09-03 21:18:22 +00:00
btVector3 localInertiaDiagonal ( 0 , 0 , 0 ) ;
int urdfLinkIndex = u2b . getRootLinkIndex ( ) ;
2015-10-13 18:32:25 +00:00
u2b . getMassAndInertia ( urdfLinkIndex , mass , localInertiaDiagonal , bodyHandle - > m_rootLocalInertialFrame ) ;
2015-09-03 21:18:22 +00:00
}
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " loaded %s OK! " , fileName ) ;
}
2015-05-29 00:49:55 +00:00
btTransform tr ;
tr . setIdentity ( ) ;
tr . setOrigin ( pos ) ;
tr . setRotation ( orn ) ;
2015-07-23 18:51:25 +00:00
//int rootLinkIndex = u2b.getRootLinkIndex();
2015-05-29 00:49:55 +00:00
// printf("urdf root link index = %d\n",rootLinkIndex);
2015-07-14 22:30:17 +00:00
MyMultiBodyCreator creation ( m_data - > m_guiHelper ) ;
2015-05-29 22:04:05 +00:00
2015-07-14 22:30:17 +00:00
ConvertURDF2Bullet ( u2b , creation , tr , m_data - > m_dynamicsWorld , useMultiBody , u2b . getPathPrefix ( ) ) ;
2015-05-29 00:49:55 +00:00
btMultiBody * mb = creation . getBulletMultiBody ( ) ;
2015-06-10 01:13:05 +00:00
if ( useMultiBody )
{
if ( mb )
{
2015-10-13 18:32:25 +00:00
bodyHandle - > m_multiBody = mb ;
2015-07-14 15:34:02 +00:00
createJointMotors ( mb ) ;
//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
2015-07-11 05:20:06 +00:00
UrdfLinkNameMapUtil * util = new UrdfLinkNameMapUtil ;
2015-07-14 22:30:17 +00:00
m_data - > m_urdfLinkNameMapper . push_back ( util ) ;
2015-07-11 05:20:06 +00:00
util - > m_mb = mb ;
2015-07-14 22:30:17 +00:00
util - > m_memSerializer = new btDefaultSerializer ( SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE , ( unsigned char * ) m_data - > m_testBlock1 - > m_bulletStreamDataServerToClient ) ;
2015-07-11 05:20:06 +00:00
//disable serialization of the collision objects (they are too big, and the client likely doesn't need them);
util - > m_memSerializer - > m_skipPointers . insert ( mb - > getBaseCollider ( ) , 0 ) ;
for ( int i = 0 ; i < mb - > getNumLinks ( ) ; i + + )
{
//disable serialization of the collision objects
util - > m_memSerializer - > m_skipPointers . insert ( mb - > getLink ( i ) . m_collider , 0 ) ;
int urdfLinkIndex = creation . m_mb2urdfLink [ i ] ;
std : : string * linkName = new std : : string ( u2b . getLinkName ( urdfLinkIndex ) . c_str ( ) ) ;
2015-07-14 22:30:17 +00:00
m_data - > m_strings . push_back ( linkName ) ;
2015-07-11 05:20:06 +00:00
util - > m_memSerializer - > registerNameForPointer ( linkName - > c_str ( ) , linkName - > c_str ( ) ) ;
mb - > getLink ( i ) . m_linkName = linkName - > c_str ( ) ;
std : : string * jointName = new std : : string ( u2b . getJointName ( urdfLinkIndex ) . c_str ( ) ) ;
2015-07-14 22:30:17 +00:00
m_data - > m_strings . push_back ( jointName ) ;
2015-07-11 05:20:06 +00:00
util - > m_memSerializer - > registerNameForPointer ( jointName - > c_str ( ) , jointName - > c_str ( ) ) ;
mb - > getLink ( i ) . m_jointName = jointName - > c_str ( ) ;
}
std : : string * baseName = new std : : string ( u2b . getLinkName ( u2b . getRootLinkIndex ( ) ) ) ;
2015-07-14 22:30:17 +00:00
m_data - > m_strings . push_back ( baseName ) ;
2015-07-11 05:20:06 +00:00
util - > m_memSerializer - > registerNameForPointer ( baseName - > c_str ( ) , baseName - > c_str ( ) ) ;
mb - > setBaseName ( baseName - > c_str ( ) ) ;
util - > m_memSerializer - > insertHeader ( ) ;
int len = mb - > calculateSerializeBufferSize ( ) ;
btChunk * chunk = util - > m_memSerializer - > allocate ( len , 1 ) ;
const char * structType = mb - > serialize ( chunk - > m_oldPtr , util - > m_memSerializer ) ;
util - > m_memSerializer - > finalizeChunk ( chunk , structType , BT_MULTIBODY_CODE , mb ) ;
2015-06-10 01:13:05 +00:00
return true ;
} else
{
2015-07-14 15:34:02 +00:00
b3Warning ( " No multibody loaded from URDF. Could add btRigidBody+btTypedConstraint solution later. " ) ;
2015-06-10 01:13:05 +00:00
return false ;
}
} else
{
2015-07-14 22:30:17 +00:00
btAssert ( 0 ) ;
2015-08-02 21:00:43 +00:00
2015-06-10 01:13:05 +00:00
return true ;
}
2015-05-29 00:49:55 +00:00
}
2015-05-29 22:04:05 +00:00
return false ;
2015-05-29 00:49:55 +00:00
}
2015-07-31 06:22:44 +00:00
2015-07-14 22:30:17 +00:00
void PhysicsServerSharedMemory : : processClientCommands ( )
{
if ( m_data - > m_isConnected & & m_data - > m_testBlock1 )
2015-05-28 23:05:24 +00:00
{
///we ignore overflow of integer for now
2015-07-14 22:30:17 +00:00
if ( m_data - > m_testBlock1 - > m_numClientCommands > m_data - > m_testBlock1 - > m_numProcessedClientCommands )
2015-05-28 23:05:24 +00:00
{
//until we implement a proper ring buffer, we assume always maximum of 1 outstanding commands
2015-07-14 22:30:17 +00:00
btAssert ( m_data - > m_testBlock1 - > m_numClientCommands = = m_data - > m_testBlock1 - > m_numProcessedClientCommands + 1 ) ;
2015-05-28 23:05:24 +00:00
2015-07-14 22:30:17 +00:00
const SharedMemoryCommand & clientCmd = m_data - > m_testBlock1 - > m_clientCommands [ 0 ] ;
m_data - > m_testBlock1 - > m_numProcessedClientCommands + + ;
2015-07-31 06:22:44 +00:00
//no timestamp yet
int timeStamp = 0 ;
2015-05-28 23:05:24 +00:00
//consume the command
2015-07-14 22:30:17 +00:00
switch ( clientCmd . m_type )
2015-05-28 23:05:24 +00:00
{
2015-07-09 21:04:58 +00:00
case CMD_SEND_BULLET_DATA_STREAM :
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " Processed CMD_SEND_BULLET_DATA_STREAM length %d " , clientCmd . m_dataStreamArguments . m_streamChunkLength ) ;
}
2015-07-09 21:04:58 +00:00
2015-07-14 22:30:17 +00:00
btBulletWorldImporter * worldImporter = new btBulletWorldImporter ( m_data - > m_dynamicsWorld ) ;
m_data - > m_worldImporters . push_back ( worldImporter ) ;
bool completedOk = worldImporter - > loadFileFromMemory ( m_data - > m_testBlock1 - > m_bulletStreamDataClientToServer , clientCmd . m_dataStreamArguments . m_streamChunkLength ) ;
2015-07-09 21:04:58 +00:00
if ( completedOk )
{
2015-07-31 06:22:44 +00:00
SharedMemoryStatus & status = m_data - > createServerStatus ( CMD_BULLET_DATA_STREAM_RECEIVED_COMPLETED , clientCmd . m_sequenceNumber , timeStamp ) ;
2015-07-14 22:30:17 +00:00
m_data - > m_guiHelper - > autogenerateGraphicsObjects ( this - > m_data - > m_dynamicsWorld ) ;
2015-07-31 06:22:44 +00:00
m_data - > submitServerStatus ( status ) ;
2015-07-09 21:04:58 +00:00
} else
{
2015-07-31 06:22:44 +00:00
SharedMemoryStatus & status = m_data - > createServerStatus ( CMD_BULLET_DATA_STREAM_RECEIVED_FAILED , clientCmd . m_sequenceNumber , timeStamp ) ;
m_data - > submitServerStatus ( status ) ;
2015-07-09 21:04:58 +00:00
}
2015-07-31 06:22:44 +00:00
2015-07-09 21:04:58 +00:00
break ;
}
2015-08-20 05:51:16 +00:00
case CMD_REQUEST_DEBUG_LINES :
{
int curFlags = m_data - > m_debugDrawer - > getDebugMode ( ) ;
2015-09-03 21:18:22 +00:00
int debugMode = clientCmd . m_requestDebugLinesArguments . m_debugMode ; //clientCmd.btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb;
int startingLineIndex = clientCmd . m_requestDebugLinesArguments . m_startingLineIndex ;
if ( startingLineIndex < 0 )
{
b3Warning ( " startingLineIndex should be non-negative " ) ;
startingLineIndex = 0 ;
}
if ( clientCmd . m_requestDebugLinesArguments . m_startingLineIndex = = 0 )
{
m_data - > m_debugDrawer - > m_lines2 . resize ( 0 ) ;
//|btIDebugDraw::DBG_DrawAabb|
// btIDebugDraw::DBG_DrawConstraints |btIDebugDraw::DBG_DrawConstraintLimits ;
m_data - > m_debugDrawer - > setDebugMode ( debugMode ) ;
m_data - > m_dynamicsWorld - > debugDrawWorld ( ) ;
m_data - > m_debugDrawer - > setDebugMode ( curFlags ) ;
}
//9 floats per line: 3 floats for 'from', 3 floats for 'to' and 3 floats for 'color'
int maxNumLines = SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE / ( sizeof ( float ) * 9 ) - 1 ;
if ( startingLineIndex > m_data - > m_debugDrawer - > m_lines2 . size ( ) )
{
b3Warning ( " m_startingLineIndex exceeds total number of debug lines " ) ;
startingLineIndex = m_data - > m_debugDrawer - > m_lines2 . size ( ) ;
}
int numLines = btMin ( maxNumLines , m_data - > m_debugDrawer - > m_lines2 . size ( ) - startingLineIndex ) ;
if ( numLines )
{
2015-08-20 05:51:16 +00:00
2015-09-03 21:18:22 +00:00
float * linesFrom = ( float * ) & m_data - > m_testBlock1 - > m_bulletStreamDataServerToClient [ 0 ] ;
float * linesTo = ( float * ) ( & m_data - > m_testBlock1 - > m_bulletStreamDataServerToClient [ 0 ] + numLines * 3 * sizeof ( float ) ) ;
float * linesColor = ( float * ) ( & m_data - > m_testBlock1 - > m_bulletStreamDataServerToClient [ 0 ] + 2 * numLines * 3 * sizeof ( float ) ) ;
2015-08-20 05:51:16 +00:00
for ( int i = 0 ; i < numLines ; i + + )
{
2015-09-03 21:18:22 +00:00
linesFrom [ i * 3 ] = m_data - > m_debugDrawer - > m_lines2 [ i + startingLineIndex ] . m_from . x ( ) ;
linesTo [ i * 3 ] = m_data - > m_debugDrawer - > m_lines2 [ i + startingLineIndex ] . m_to . x ( ) ;
linesColor [ i * 3 ] = m_data - > m_debugDrawer - > m_lines2 [ i + startingLineIndex ] . m_color . x ( ) ;
2015-08-20 15:09:22 +00:00
2015-09-03 21:18:22 +00:00
linesFrom [ i * 3 + 1 ] = m_data - > m_debugDrawer - > m_lines2 [ i + startingLineIndex ] . m_from . y ( ) ;
linesTo [ i * 3 + 1 ] = m_data - > m_debugDrawer - > m_lines2 [ i + startingLineIndex ] . m_to . y ( ) ;
linesColor [ i * 3 + 1 ] = m_data - > m_debugDrawer - > m_lines2 [ i + startingLineIndex ] . m_color . y ( ) ;
2015-08-20 15:09:22 +00:00
2015-09-03 21:18:22 +00:00
linesFrom [ i * 3 + 2 ] = m_data - > m_debugDrawer - > m_lines2 [ i + startingLineIndex ] . m_from . z ( ) ;
linesTo [ i * 3 + 2 ] = m_data - > m_debugDrawer - > m_lines2 [ i + startingLineIndex ] . m_to . z ( ) ;
linesColor [ i * 3 + 2 ] = m_data - > m_debugDrawer - > m_lines2 [ i + startingLineIndex ] . m_color . z ( ) ;
}
2015-08-20 05:51:16 +00:00
}
2015-09-03 21:18:22 +00:00
SharedMemoryStatus & status = m_data - > createServerStatus ( CMD_DEBUG_LINES_COMPLETED , clientCmd . m_sequenceNumber , timeStamp ) ;
status . m_sendDebugLinesArgs . m_numDebugLines = numLines ;
status . m_sendDebugLinesArgs . m_startingLineIndex = startingLineIndex ;
status . m_sendDebugLinesArgs . m_numRemainingDebugLines = m_data - > m_debugDrawer - > m_lines2 . size ( ) - ( startingLineIndex + numLines ) ;
m_data - > submitServerStatus ( status ) ;
2015-08-20 05:51:16 +00:00
break ;
}
2015-05-28 23:05:24 +00:00
case CMD_LOAD_URDF :
{
2015-10-13 18:32:25 +00:00
2015-07-12 21:48:43 +00:00
const UrdfArgs & urdfArgs = clientCmd . m_urdfArguments ;
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " Processed CMD_LOAD_URDF:%s " , urdfArgs . m_urdfFileName ) ;
}
2015-07-31 06:22:44 +00:00
btAssert ( ( clientCmd . m_updateFlags & URDF_ARGS_FILE_NAME ) ! = 0 ) ;
btAssert ( urdfArgs . m_urdfFileName ) ;
btVector3 initialPos ( 0 , 0 , 0 ) ;
btQuaternion initialOrn ( 0 , 0 , 0 , 1 ) ;
if ( clientCmd . m_updateFlags & URDF_ARGS_INITIAL_POSITION )
{
initialPos [ 0 ] = urdfArgs . m_initialPosition [ 0 ] ;
initialPos [ 1 ] = urdfArgs . m_initialPosition [ 1 ] ;
initialPos [ 2 ] = urdfArgs . m_initialPosition [ 2 ] ;
}
if ( clientCmd . m_updateFlags & URDF_ARGS_INITIAL_ORIENTATION )
{
initialOrn [ 0 ] = urdfArgs . m_initialOrientation [ 0 ] ;
initialOrn [ 1 ] = urdfArgs . m_initialOrientation [ 1 ] ;
initialOrn [ 2 ] = urdfArgs . m_initialOrientation [ 2 ] ;
initialOrn [ 3 ] = urdfArgs . m_initialOrientation [ 3 ] ;
}
bool useMultiBody = ( clientCmd . m_updateFlags & URDF_ARGS_USE_MULTIBODY ) ? urdfArgs . m_useMultiBody : true ;
bool useFixedBase = ( clientCmd . m_updateFlags & URDF_ARGS_USE_FIXED_BASE ) ? urdfArgs . m_useFixedBase : false ;
2015-10-13 18:32:25 +00:00
int bodyUniqueId ;
2015-07-12 21:48:43 +00:00
//load the actual URDF and send a report: completed or failed
bool completedOk = loadUrdf ( urdfArgs . m_urdfFileName ,
2015-07-31 06:22:44 +00:00
initialPos , initialOrn ,
2015-10-13 18:32:25 +00:00
useMultiBody , useFixedBase , & bodyUniqueId ) ;
2015-05-29 00:49:55 +00:00
if ( completedOk )
{
2015-10-13 18:32:25 +00:00
m_data - > m_guiHelper - > autogenerateGraphicsObjects ( this - > m_data - > m_dynamicsWorld ) ;
SharedMemoryStatus & status = m_data - > createServerStatus ( CMD_URDF_LOADING_COMPLETED , clientCmd . m_sequenceNumber , timeStamp ) ;
2015-07-14 22:30:17 +00:00
if ( m_data - > m_urdfLinkNameMapper . size ( ) )
2015-07-11 05:20:06 +00:00
{
2015-10-13 18:32:25 +00:00
status . m_dataStreamArguments . m_streamChunkLength = m_data - > m_urdfLinkNameMapper . at ( m_data - > m_urdfLinkNameMapper . size ( ) - 1 ) - > m_memSerializer - > getCurrentBufferSize ( ) ;
status . m_dataStreamArguments . m_bodyUniqueId = bodyUniqueId ;
2015-07-11 05:20:06 +00:00
}
2015-07-31 06:22:44 +00:00
m_data - > submitServerStatus ( status ) ;
2015-05-29 00:49:55 +00:00
} else
{
2015-07-31 06:22:44 +00:00
SharedMemoryStatus & status = m_data - > createServerStatus ( CMD_URDF_LOADING_FAILED , clientCmd . m_sequenceNumber , timeStamp ) ;
m_data - > submitServerStatus ( status ) ;
2015-05-29 00:49:55 +00:00
}
2015-07-31 06:22:44 +00:00
2015-07-11 05:20:06 +00:00
2015-08-02 21:00:43 +00:00
break ;
}
case CMD_CREATE_SENSOR :
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " Processed CMD_CREATE_SENSOR " ) ;
}
2015-10-13 18:32:25 +00:00
int bodyUniqueId = clientCmd . m_createSensorArguments . m_bodyUniqueId ;
InteralBodyData * body = m_data - > getHandle ( bodyUniqueId ) ;
if ( body & & body - > m_multiBody )
2015-08-02 21:00:43 +00:00
{
2015-10-13 18:32:25 +00:00
btMultiBody * mb = body - > m_multiBody ;
2015-08-02 21:00:43 +00:00
btAssert ( mb ) ;
for ( int i = 0 ; i < clientCmd . m_createSensorArguments . m_numJointSensorChanges ; i + + )
{
int jointIndex = clientCmd . m_createSensorArguments . m_jointIndex [ i ] ;
if ( clientCmd . m_createSensorArguments . m_enableJointForceSensor [ i ] )
{
if ( mb - > getLink ( jointIndex ) . m_jointFeedback )
{
b3Warning ( " CMD_CREATE_SENSOR: sensor for joint [%d] already enabled " , jointIndex ) ;
} else
{
btMultiBodyJointFeedback * fb = new btMultiBodyJointFeedback ( ) ;
fb - > m_reactionForces . setZero ( ) ;
mb - > getLink ( jointIndex ) . m_jointFeedback = fb ;
m_data - > m_multiBodyJointFeedbacks . push_back ( fb ) ;
} ;
} else
{
if ( mb - > getLink ( jointIndex ) . m_jointFeedback )
{
m_data - > m_multiBodyJointFeedbacks . remove ( mb - > getLink ( jointIndex ) . m_jointFeedback ) ;
delete mb - > getLink ( jointIndex ) . m_jointFeedback ;
mb - > getLink ( jointIndex ) . m_jointFeedback = 0 ;
} else
{
b3Warning ( " CMD_CREATE_SENSOR: cannot perform sensor removal request, no sensor on joint [%d] " , jointIndex ) ;
} ;
}
}
} else
{
b3Warning ( " No btMultiBody in the world. btRigidBody/btTypedConstraint sensor not hooked up yet " ) ;
}
#if 0
//todo(erwincoumans) here is some sample code to hook up a force/torque sensor for btTypedConstraint/btRigidBody
/*
for ( int i = 0 ; i < m_data - > m_dynamicsWorld - > getNumConstraints ( ) ; i + + )
{
btTypedConstraint * c = m_data - > m_dynamicsWorld - > getConstraint ( i ) ;
btJointFeedback * fb = new btJointFeedback ( ) ;
m_data - > m_jointFeedbacks . push_back ( fb ) ;
c - > setJointFeedback ( fb ) ;
}
*/
# endif
SharedMemoryStatus & serverCmd = m_data - > createServerStatus ( CMD_CLIENT_COMMAND_COMPLETED , clientCmd . m_sequenceNumber , timeStamp ) ;
m_data - > submitServerStatus ( serverCmd ) ;
2015-05-29 22:04:05 +00:00
break ;
}
2015-07-14 15:34:02 +00:00
case CMD_SEND_DESIRED_STATE :
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
2015-07-14 15:34:02 +00:00
b3Printf ( " Processed CMD_SEND_DESIRED_STATE " ) ;
2015-08-20 05:51:16 +00:00
}
2015-10-13 18:32:25 +00:00
int bodyUniqueId = clientCmd . m_sendDesiredStateCommandArgument . m_bodyUniqueId ;
InteralBodyData * body = m_data - > getHandle ( bodyUniqueId ) ;
if ( body & & body - > m_multiBody )
2015-07-14 15:34:02 +00:00
{
2015-10-13 18:32:25 +00:00
btMultiBody * mb = body - > m_multiBody ;
2015-07-14 15:34:02 +00:00
btAssert ( mb ) ;
switch ( clientCmd . m_sendDesiredStateCommandArgument . m_controlMode )
{
case CONTROL_MODE_TORQUE :
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " Using CONTROL_MODE_TORQUE " ) ;
}
2015-07-14 15:34:02 +00:00
mb - > clearForcesAndTorques ( ) ;
int torqueIndex = 0 ;
2015-07-15 22:23:40 +00:00
btVector3 f ( clientCmd . m_sendDesiredStateCommandArgument . m_desiredStateForceTorque [ 0 ] ,
clientCmd . m_sendDesiredStateCommandArgument . m_desiredStateForceTorque [ 1 ] ,
clientCmd . m_sendDesiredStateCommandArgument . m_desiredStateForceTorque [ 2 ] ) ;
btVector3 t ( clientCmd . m_sendDesiredStateCommandArgument . m_desiredStateForceTorque [ 3 ] ,
clientCmd . m_sendDesiredStateCommandArgument . m_desiredStateForceTorque [ 4 ] ,
clientCmd . m_sendDesiredStateCommandArgument . m_desiredStateForceTorque [ 5 ] ) ;
2015-07-14 15:34:02 +00:00
torqueIndex + = 6 ;
mb - > addBaseForce ( f ) ;
mb - > addBaseTorque ( t ) ;
for ( int link = 0 ; link < mb - > getNumLinks ( ) ; link + + )
{
for ( int dof = 0 ; dof < mb - > getLink ( link ) . m_dofCount ; dof + + )
{
2015-07-15 22:23:40 +00:00
double torque = clientCmd . m_sendDesiredStateCommandArgument . m_desiredStateForceTorque [ torqueIndex ] ;
2015-07-14 15:34:02 +00:00
mb - > addJointTorqueMultiDof ( link , dof , torque ) ;
torqueIndex + + ;
}
}
break ;
}
case CONTROL_MODE_VELOCITY :
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " Using CONTROL_MODE_VELOCITY " ) ;
}
2015-08-02 21:00:43 +00:00
2015-07-14 15:34:02 +00:00
int numMotors = 0 ;
//find the joint motors and apply the desired velocity and maximum force/torque
{
int dofIndex = 6 ; //skip the 3 linear + 3 angular degree of freedom entries of the base
for ( int link = 0 ; link < mb - > getNumLinks ( ) ; link + + )
{
if ( supportsJointMotor ( mb , link ) )
{
2015-07-14 22:30:17 +00:00
btMultiBodyJointMotor * * motorPtr = m_data - > m_multiBodyJointMotorMap [ link ] ;
2015-07-14 15:34:02 +00:00
if ( motorPtr )
{
btMultiBodyJointMotor * motor = * motorPtr ;
2015-07-15 22:23:40 +00:00
btScalar desiredVelocity = clientCmd . m_sendDesiredStateCommandArgument . m_desiredStateQdot [ dofIndex ] ;
2015-07-14 15:34:02 +00:00
motor - > setVelocityTarget ( desiredVelocity ) ;
2015-07-21 06:35:29 +00:00
btScalar maxImp = clientCmd . m_sendDesiredStateCommandArgument . m_desiredStateForceTorque [ dofIndex ] * m_data - > m_physicsDeltaTime ;
2015-07-14 15:34:02 +00:00
motor - > setMaxAppliedImpulse ( maxImp ) ;
numMotors + + ;
}
}
dofIndex + = mb - > getLink ( link ) . m_dofCount ;
}
}
2015-08-20 05:51:16 +00:00
break ;
}
case CONTROL_MODE_POSITION_VELOCITY_PD :
{
if ( m_data - > m_verboseOutput )
{
b3Printf ( " Using CONTROL_MODE_POSITION_VELOCITY_PD " ) ;
}
//compute the force base on PD control
mb - > clearForcesAndTorques ( ) ;
int numMotors = 0 ;
//find the joint motors and apply the desired velocity and maximum force/torque
{
int velIndex = 6 ; //skip the 3 linear + 3 angular degree of freedom velocity entries of the base
int posIndex = 7 ; //skip 3 positional and 4 orientation (quaternion) positional degrees of freedom of the base
for ( int link = 0 ; link < mb - > getNumLinks ( ) ; link + + )
{
if ( supportsJointMotor ( mb , link ) )
{
btMultiBodyJointMotor * * motorPtr = m_data - > m_multiBodyJointMotorMap [ link ] ;
if ( motorPtr )
{
btMultiBodyJointMotor * motor = * motorPtr ;
2015-08-20 21:57:14 +00:00
btScalar desiredVelocity = clientCmd . m_sendDesiredStateCommandArgument . m_desiredStateQdot [ velIndex ] ;
btScalar desiredPosition = clientCmd . m_sendDesiredStateCommandArgument . m_desiredStateQ [ posIndex ] ;
btScalar kp = clientCmd . m_sendDesiredStateCommandArgument . m_Kp [ velIndex ] ;
btScalar kd = clientCmd . m_sendDesiredStateCommandArgument . m_Kd [ velIndex ] ;
int dof1 = 0 ;
btScalar currentPosition = mb - > getJointPosMultiDof ( link ) [ dof1 ] ;
btScalar currentVelocity = mb - > getJointVelMultiDof ( link ) [ dof1 ] ;
btScalar positionStabiliationTerm = ( desiredPosition - currentPosition ) / m_data - > m_physicsDeltaTime ;
btScalar velocityError = ( desiredVelocity - currentVelocity ) ;
desiredVelocity = kp * positionStabiliationTerm +
kd * velocityError ;
motor - > setVelocityTarget ( desiredVelocity ) ;
btScalar maxImp = clientCmd . m_sendDesiredStateCommandArgument . m_desiredStateForceTorque [ velIndex ] * m_data - > m_physicsDeltaTime ;
motor - > setMaxAppliedImpulse ( 1000 ) ; //maxImp);
numMotors + + ;
}
2015-08-20 05:51:16 +00:00
}
velIndex + = mb - > getLink ( link ) . m_dofCount ;
posIndex + = mb - > getLink ( link ) . m_posVarCount ;
}
}
2015-07-14 15:34:02 +00:00
break ;
}
default :
{
2015-08-20 05:51:16 +00:00
b3Warning ( " m_controlMode not implemented yet " ) ;
2015-07-14 15:34:02 +00:00
break ;
}
}
}
2015-07-31 06:22:44 +00:00
SharedMemoryStatus & status = m_data - > createServerStatus ( CMD_DESIRED_STATE_RECEIVED_COMPLETED , clientCmd . m_sequenceNumber , timeStamp ) ;
m_data - > submitServerStatus ( status ) ;
2015-07-14 15:34:02 +00:00
break ;
}
2015-06-21 20:24:36 +00:00
case CMD_REQUEST_ACTUAL_STATE :
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " Sending the actual state (Q,U) " ) ;
}
2015-10-13 18:32:25 +00:00
int bodyUniqueId = clientCmd . m_requestActualStateInformationCommandArgument . m_bodyUniqueId ;
InteralBodyData * body = m_data - > getHandle ( bodyUniqueId ) ;
btMultiBody * mb = 0 ;
if ( body )
{
mb = body - > m_multiBody ;
}
if ( mb )
2015-06-21 20:24:36 +00:00
{
2015-10-13 18:32:25 +00:00
2015-07-31 06:22:44 +00:00
SharedMemoryStatus & serverCmd = m_data - > createServerStatus ( CMD_ACTUAL_STATE_UPDATE_COMPLETED , clientCmd . m_sequenceNumber , timeStamp ) ;
2015-06-21 20:24:36 +00:00
2015-10-16 15:18:26 +00:00
serverCmd . m_sendActualStateArgs . m_bodyUniqueId = bodyUniqueId ;
2015-06-21 20:24:36 +00:00
int totalDegreeOfFreedomQ = 0 ;
int totalDegreeOfFreedomU = 0 ;
2015-10-13 18:32:25 +00:00
2015-06-21 20:24:36 +00:00
//always add the base, even for static (non-moving objects)
//so that we can easily move the 'fixed' base when needed
//do we don't use this conditional "if (!mb->hasFixedBase())"
{
btTransform tr ;
tr . setOrigin ( mb - > getBasePos ( ) ) ;
tr . setRotation ( mb - > getWorldToBaseRot ( ) . inverse ( ) ) ;
2015-09-03 21:18:22 +00:00
serverCmd . m_sendActualStateArgs . m_rootLocalInertialFrame [ 0 ] =
2015-10-13 18:32:25 +00:00
body - > m_rootLocalInertialFrame . getOrigin ( ) [ 0 ] ;
2015-09-03 21:18:22 +00:00
serverCmd . m_sendActualStateArgs . m_rootLocalInertialFrame [ 1 ] =
2015-10-13 18:32:25 +00:00
body - > m_rootLocalInertialFrame . getOrigin ( ) [ 1 ] ;
2015-09-03 21:18:22 +00:00
serverCmd . m_sendActualStateArgs . m_rootLocalInertialFrame [ 2 ] =
2015-10-13 18:32:25 +00:00
body - > m_rootLocalInertialFrame . getOrigin ( ) [ 2 ] ;
2015-09-03 21:18:22 +00:00
serverCmd . m_sendActualStateArgs . m_rootLocalInertialFrame [ 3 ] =
2015-10-13 18:32:25 +00:00
body - > m_rootLocalInertialFrame . getRotation ( ) [ 0 ] ;
2015-09-03 21:18:22 +00:00
serverCmd . m_sendActualStateArgs . m_rootLocalInertialFrame [ 4 ] =
2015-10-13 18:32:25 +00:00
body - > m_rootLocalInertialFrame . getRotation ( ) [ 1 ] ;
2015-09-03 21:18:22 +00:00
serverCmd . m_sendActualStateArgs . m_rootLocalInertialFrame [ 5 ] =
2015-10-13 18:32:25 +00:00
body - > m_rootLocalInertialFrame . getRotation ( ) [ 2 ] ;
2015-09-03 21:18:22 +00:00
serverCmd . m_sendActualStateArgs . m_rootLocalInertialFrame [ 6 ] =
2015-10-13 18:32:25 +00:00
body - > m_rootLocalInertialFrame . getRotation ( ) [ 3 ] ;
2015-09-03 21:18:22 +00:00
2015-06-21 20:24:36 +00:00
//base position in world space, carthesian
2015-07-15 22:23:40 +00:00
serverCmd . m_sendActualStateArgs . m_actualStateQ [ 0 ] = tr . getOrigin ( ) [ 0 ] ;
serverCmd . m_sendActualStateArgs . m_actualStateQ [ 1 ] = tr . getOrigin ( ) [ 1 ] ;
serverCmd . m_sendActualStateArgs . m_actualStateQ [ 2 ] = tr . getOrigin ( ) [ 2 ] ;
2015-06-21 20:24:36 +00:00
//base orientation, quaternion x,y,z,w, in world space, carthesian
2015-07-15 22:23:40 +00:00
serverCmd . m_sendActualStateArgs . m_actualStateQ [ 3 ] = tr . getRotation ( ) [ 0 ] ;
serverCmd . m_sendActualStateArgs . m_actualStateQ [ 4 ] = tr . getRotation ( ) [ 1 ] ;
serverCmd . m_sendActualStateArgs . m_actualStateQ [ 5 ] = tr . getRotation ( ) [ 2 ] ;
serverCmd . m_sendActualStateArgs . m_actualStateQ [ 6 ] = tr . getRotation ( ) [ 3 ] ;
2015-06-21 20:24:36 +00:00
totalDegreeOfFreedomQ + = 7 ; //pos + quaternion
//base linear velocity (in world space, carthesian)
2015-07-15 22:23:40 +00:00
serverCmd . m_sendActualStateArgs . m_actualStateQdot [ 0 ] = mb - > getBaseVel ( ) [ 0 ] ;
serverCmd . m_sendActualStateArgs . m_actualStateQdot [ 1 ] = mb - > getBaseVel ( ) [ 1 ] ;
serverCmd . m_sendActualStateArgs . m_actualStateQdot [ 2 ] = mb - > getBaseVel ( ) [ 2 ] ;
2015-06-21 20:24:36 +00:00
//base angular velocity (in world space, carthesian)
2015-07-15 22:23:40 +00:00
serverCmd . m_sendActualStateArgs . m_actualStateQdot [ 3 ] = mb - > getBaseOmega ( ) [ 0 ] ;
serverCmd . m_sendActualStateArgs . m_actualStateQdot [ 4 ] = mb - > getBaseOmega ( ) [ 1 ] ;
serverCmd . m_sendActualStateArgs . m_actualStateQdot [ 5 ] = mb - > getBaseOmega ( ) [ 2 ] ;
2015-06-21 20:24:36 +00:00
totalDegreeOfFreedomU + = 6 ; //3 linear and 3 angular DOF
}
for ( int l = 0 ; l < mb - > getNumLinks ( ) ; l + + )
{
for ( int d = 0 ; d < mb - > getLink ( l ) . m_posVarCount ; d + + )
{
2015-07-15 22:23:40 +00:00
serverCmd . m_sendActualStateArgs . m_actualStateQ [ totalDegreeOfFreedomQ + + ] = mb - > getJointPosMultiDof ( l ) [ d ] ;
2015-06-21 20:24:36 +00:00
}
for ( int d = 0 ; d < mb - > getLink ( l ) . m_dofCount ; d + + )
{
2015-07-15 22:23:40 +00:00
serverCmd . m_sendActualStateArgs . m_actualStateQdot [ totalDegreeOfFreedomU + + ] = mb - > getJointVelMultiDof ( l ) [ d ] ;
2015-06-21 20:24:36 +00:00
}
2015-08-02 21:00:43 +00:00
if ( 0 = = mb - > getLink ( l ) . m_jointFeedback )
{
for ( int d = 0 ; d < 6 ; d + + )
{
serverCmd . m_sendActualStateArgs . m_jointReactionForces [ l * 6 + d ] = 0 ;
}
} else
{
btVector3 sensedForce = mb - > getLink ( l ) . m_jointFeedback - > m_reactionForces . getLinear ( ) ;
2015-08-22 01:18:12 +00:00
btVector3 sensedTorque = mb - > getLink ( l ) . m_jointFeedback - > m_reactionForces . getAngular ( ) ;
2015-08-02 21:00:43 +00:00
serverCmd . m_sendActualStateArgs . m_jointReactionForces [ l * 6 + 0 ] = sensedForce [ 0 ] ;
serverCmd . m_sendActualStateArgs . m_jointReactionForces [ l * 6 + 1 ] = sensedForce [ 1 ] ;
serverCmd . m_sendActualStateArgs . m_jointReactionForces [ l * 6 + 2 ] = sensedForce [ 2 ] ;
serverCmd . m_sendActualStateArgs . m_jointReactionForces [ l * 6 + 3 ] = sensedTorque [ 0 ] ;
serverCmd . m_sendActualStateArgs . m_jointReactionForces [ l * 6 + 4 ] = sensedTorque [ 1 ] ;
serverCmd . m_sendActualStateArgs . m_jointReactionForces [ l * 6 + 5 ] = sensedTorque [ 2 ] ;
}
2015-06-21 20:24:36 +00:00
}
2015-06-10 01:13:05 +00:00
2015-06-21 20:24:36 +00:00
serverCmd . m_sendActualStateArgs . m_numDegreeOfFreedomQ = totalDegreeOfFreedomQ ;
serverCmd . m_sendActualStateArgs . m_numDegreeOfFreedomU = totalDegreeOfFreedomU ;
2015-07-31 06:22:44 +00:00
m_data - > submitServerStatus ( serverCmd ) ;
2015-06-21 20:24:36 +00:00
} else
{
2015-07-31 06:22:44 +00:00
2015-06-21 20:24:36 +00:00
b3Warning ( " Request state but no multibody available " ) ;
2015-07-31 06:22:44 +00:00
SharedMemoryStatus & serverCmd = m_data - > createServerStatus ( CMD_ACTUAL_STATE_UPDATE_FAILED , clientCmd . m_sequenceNumber , timeStamp ) ;
m_data - > submitServerStatus ( serverCmd ) ;
2015-06-21 20:24:36 +00:00
}
break ;
}
case CMD_STEP_FORWARD_SIMULATION :
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " Step simulation request " ) ;
}
m_data - > m_dynamicsWorld - > stepSimulation ( m_data - > m_physicsDeltaTime , 0 ) ;
2015-06-21 20:24:36 +00:00
2015-07-31 06:22:44 +00:00
SharedMemoryStatus & serverCmd = m_data - > createServerStatus ( CMD_STEP_FORWARD_SIMULATION_COMPLETED , clientCmd . m_sequenceNumber , timeStamp ) ;
m_data - > submitServerStatus ( serverCmd ) ;
2015-06-21 20:24:36 +00:00
2015-05-29 22:04:05 +00:00
break ;
}
2015-07-22 04:46:28 +00:00
case CMD_SEND_PHYSICS_SIMULATION_PARAMETERS :
{
2015-08-26 22:26:53 +00:00
if ( clientCmd . m_updateFlags & SIM_PARAM_UPDATE_DELTA_TIME )
{
m_data - > m_physicsDeltaTime = clientCmd . m_physSimParamArgs . m_deltaTime ;
}
2015-07-23 17:51:09 +00:00
if ( clientCmd . m_updateFlags & SIM_PARAM_UPDATE_GRAVITY )
2015-07-22 04:46:28 +00:00
{
btVector3 grav ( clientCmd . m_physSimParamArgs . m_gravityAcceleration [ 0 ] ,
clientCmd . m_physSimParamArgs . m_gravityAcceleration [ 1 ] ,
clientCmd . m_physSimParamArgs . m_gravityAcceleration [ 2 ] ) ;
this - > m_data - > m_dynamicsWorld - > setGravity ( grav ) ;
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " Updated Gravity: %f,%f,%f " , grav [ 0 ] , grav [ 1 ] , grav [ 2 ] ) ;
}
2015-07-22 04:46:28 +00:00
}
2015-07-31 06:22:44 +00:00
SharedMemoryStatus & serverCmd = m_data - > createServerStatus ( CMD_CLIENT_COMMAND_COMPLETED , clientCmd . m_sequenceNumber , timeStamp ) ;
m_data - > submitServerStatus ( serverCmd ) ;
2015-07-22 04:46:28 +00:00
break ;
} ;
case CMD_INIT_POSE :
{
2015-08-20 05:51:16 +00:00
if ( m_data - > m_verboseOutput )
{
b3Printf ( " Server Init Pose not implemented yet " ) ;
}
2015-10-24 20:48:53 +00:00
int bodyUniqueId = clientCmd . m_initPoseArgs . m_bodyUniqueId ;
2015-10-13 18:32:25 +00:00
InteralBodyData * body = m_data - > getHandle ( bodyUniqueId ) ;
if ( body & & body - > m_multiBody )
2015-09-25 05:42:22 +00:00
{
2015-10-13 18:32:25 +00:00
btMultiBody * mb = body - > m_multiBody ;
2015-10-14 05:23:28 +00:00
if ( clientCmd . m_updateFlags & INIT_POSE_HAS_INITIAL_POSITION )
{
btVector3 zero ( 0 , 0 , 0 ) ;
mb - > setBaseVel ( zero ) ;
mb - > setBasePos ( btVector3 (
clientCmd . m_initPoseArgs . m_initialStateQ [ 0 ] ,
clientCmd . m_initPoseArgs . m_initialStateQ [ 1 ] ,
clientCmd . m_initPoseArgs . m_initialStateQ [ 2 ] ) ) ;
}
if ( clientCmd . m_updateFlags & INIT_POSE_HAS_INITIAL_ORIENTATION )
{
mb - > setBaseOmega ( btVector3 ( 0 , 0 , 0 ) ) ;
mb - > setWorldToBaseRot ( btQuaternion (
clientCmd . m_initPoseArgs . m_initialStateQ [ 3 ] ,
clientCmd . m_initPoseArgs . m_initialStateQ [ 4 ] ,
clientCmd . m_initPoseArgs . m_initialStateQ [ 5 ] ,
clientCmd . m_initPoseArgs . m_initialStateQ [ 6 ] ) ) ;
}
if ( clientCmd . m_updateFlags & INIT_POSE_HAS_JOINT_STATE )
{
int dofIndex = 7 ;
for ( int i = 0 ; i < mb - > getNumLinks ( ) ; i + + )
{
if ( mb - > getLink ( i ) . m_dofCount = = 1 )
{
mb - > setJointPos ( i , clientCmd . m_initPoseArgs . m_initialStateQ [ dofIndex ] ) ;
mb - > setJointVel ( i , 0 ) ;
}
dofIndex + = mb - > getLink ( i ) . m_dofCount ;
}
}
2015-09-25 05:42:22 +00:00
}
2015-07-22 04:46:28 +00:00
2015-07-31 06:22:44 +00:00
SharedMemoryStatus & serverCmd = m_data - > createServerStatus ( CMD_CLIENT_COMMAND_COMPLETED , clientCmd . m_sequenceNumber , timeStamp ) ;
m_data - > submitServerStatus ( serverCmd ) ;
2015-07-22 04:46:28 +00:00
break ;
}
2015-08-07 07:13:26 +00:00
case CMD_RESET_SIMULATION :
2015-05-29 22:04:05 +00:00
{
2015-08-07 07:13:26 +00:00
//clean up all data
2015-09-09 22:14:47 +00:00
if ( m_data & & m_data - > m_guiHelper & & m_data - > m_guiHelper - > getRenderInterface ( ) )
{
m_data - > m_guiHelper - > getRenderInterface ( ) - > removeAllInstances ( ) ;
}
deleteDynamicsWorld ( ) ;
2015-10-24 20:49:25 +00:00
createEmptyDynamicsWorld ( ) ;
m_data - > exitHandles ( ) ;
m_data - > initHandles ( ) ;
2015-09-17 06:09:10 +00:00
SharedMemoryStatus & serverCmd = m_data - > createServerStatus ( CMD_RESET_SIMULATION_COMPLETED , clientCmd . m_sequenceNumber , timeStamp ) ;
2015-07-31 06:22:44 +00:00
m_data - > submitServerStatus ( serverCmd ) ;
2015-05-29 22:04:05 +00:00
break ;
2015-05-28 23:05:24 +00:00
}
2015-10-27 21:55:46 +00:00
case CMD_CREATE_RIGID_BODY :
2015-07-09 21:04:58 +00:00
case CMD_CREATE_BOX_COLLISION_SHAPE :
{
2015-08-02 21:00:43 +00:00
btVector3 halfExtents ( 1 , 1 , 1 ) ;
2015-08-06 18:59:31 +00:00
if ( clientCmd . m_updateFlags & BOX_SHAPE_HAS_HALF_EXTENTS )
2015-08-02 21:00:43 +00:00
{
halfExtents = btVector3 (
clientCmd . m_createBoxShapeArguments . m_halfExtentsX ,
clientCmd . m_createBoxShapeArguments . m_halfExtentsY ,
clientCmd . m_createBoxShapeArguments . m_halfExtentsZ ) ;
}
2015-07-09 21:04:58 +00:00
btTransform startTrans ;
startTrans . setIdentity ( ) ;
2015-08-06 18:59:31 +00:00
if ( clientCmd . m_updateFlags & BOX_SHAPE_HAS_INITIAL_POSITION )
2015-08-02 21:00:43 +00:00
{
startTrans . setOrigin ( btVector3 (
clientCmd . m_createBoxShapeArguments . m_initialPosition [ 0 ] ,
clientCmd . m_createBoxShapeArguments . m_initialPosition [ 1 ] ,
clientCmd . m_createBoxShapeArguments . m_initialPosition [ 2 ] ) ) ;
}
2015-08-06 18:59:31 +00:00
if ( clientCmd . m_updateFlags & BOX_SHAPE_HAS_INITIAL_ORIENTATION )
2015-08-02 21:00:43 +00:00
{
2015-08-06 18:59:31 +00:00
2015-08-02 21:00:43 +00:00
startTrans . setRotation ( btQuaternion (
clientCmd . m_createBoxShapeArguments . m_initialOrientation [ 0 ] ,
clientCmd . m_createBoxShapeArguments . m_initialOrientation [ 1 ] ,
clientCmd . m_createBoxShapeArguments . m_initialOrientation [ 2 ] ,
clientCmd . m_createBoxShapeArguments . m_initialOrientation [ 3 ] ) ) ;
}
2015-10-27 21:55:46 +00:00
btScalar mass = 0.f ;
if ( clientCmd . m_updateFlags & BOX_SHAPE_HAS_MASS )
{
mass = clientCmd . m_createBoxShapeArguments . m_mass ;
}
int shapeType = COLLISION_SHAPE_TYPE_BOX ;
if ( clientCmd . m_updateFlags & BOX_SHAPE_HAS_COLLISION_SHAPE_TYPE )
{
shapeType = clientCmd . m_createBoxShapeArguments . m_collisionShapeType ;
}
2015-07-14 22:30:17 +00:00
btBulletWorldImporter * worldImporter = new btBulletWorldImporter ( m_data - > m_dynamicsWorld ) ;
m_data - > m_worldImporters . push_back ( worldImporter ) ;
2015-10-27 21:55:46 +00:00
btCollisionShape * shape = 0 ;
switch ( shapeType )
{
case COLLISION_SHAPE_TYPE_CYLINDER_X :
{
btScalar radius = halfExtents [ 1 ] ;
btScalar height = halfExtents [ 0 ] ;
shape = worldImporter - > createCylinderShapeX ( radius , height ) ;
break ;
}
case COLLISION_SHAPE_TYPE_CYLINDER_Y :
{
btScalar radius = halfExtents [ 0 ] ;
btScalar height = halfExtents [ 1 ] ;
shape = worldImporter - > createCylinderShapeY ( radius , height ) ;
break ;
}
case COLLISION_SHAPE_TYPE_CYLINDER_Z :
{
btScalar radius = halfExtents [ 1 ] ;
btScalar height = halfExtents [ 2 ] ;
shape = worldImporter - > createCylinderShapeZ ( radius , height ) ;
break ;
}
case COLLISION_SHAPE_TYPE_CAPSULE_X :
{
btScalar radius = halfExtents [ 1 ] ;
btScalar height = halfExtents [ 0 ] ;
shape = worldImporter - > createCapsuleShapeX ( radius , height ) ;
break ;
}
case COLLISION_SHAPE_TYPE_CAPSULE_Y :
{
btScalar radius = halfExtents [ 0 ] ;
btScalar height = halfExtents [ 1 ] ;
shape = worldImporter - > createCapsuleShapeY ( radius , height ) ;
break ;
}
case COLLISION_SHAPE_TYPE_CAPSULE_Z :
{
btScalar radius = halfExtents [ 1 ] ;
btScalar height = halfExtents [ 2 ] ;
shape = worldImporter - > createCapsuleShapeZ ( radius , height ) ;
break ;
}
case COLLISION_SHAPE_TYPE_SPHERE :
{
btScalar radius = halfExtents [ 0 ] ;
shape = worldImporter - > createSphereShape ( radius ) ;
break ;
}
case COLLISION_SHAPE_TYPE_BOX :
default :
{
shape = worldImporter - > createBoxShape ( halfExtents ) ;
}
}
2015-07-14 22:30:17 +00:00
bool isDynamic = ( mass > 0 ) ;
worldImporter - > createRigidBody ( isDynamic , mass , startTrans , shape , 0 ) ;
m_data - > m_guiHelper - > autogenerateGraphicsObjects ( this - > m_data - > m_dynamicsWorld ) ;
2015-07-31 06:22:44 +00:00
SharedMemoryStatus & serverCmd = m_data - > createServerStatus ( CMD_CLIENT_COMMAND_COMPLETED , clientCmd . m_sequenceNumber , timeStamp ) ;
m_data - > submitServerStatus ( serverCmd ) ;
2015-07-09 21:04:58 +00:00
break ;
}
2015-09-25 05:42:22 +00:00
case CMD_PICK_BODY :
{
pickBody ( btVector3 ( clientCmd . m_pickBodyArguments . m_rayFromWorld [ 0 ] ,
clientCmd . m_pickBodyArguments . m_rayFromWorld [ 1 ] ,
clientCmd . m_pickBodyArguments . m_rayFromWorld [ 2 ] ) ,
btVector3 ( clientCmd . m_pickBodyArguments . m_rayToWorld [ 0 ] ,
clientCmd . m_pickBodyArguments . m_rayToWorld [ 1 ] ,
clientCmd . m_pickBodyArguments . m_rayToWorld [ 2 ] ) ) ;
SharedMemoryStatus & serverCmd =
m_data - > createServerStatus ( CMD_CLIENT_COMMAND_COMPLETED ,
clientCmd . m_sequenceNumber , timeStamp ) ;
m_data - > submitServerStatus ( serverCmd ) ;
break ;
}
case CMD_MOVE_PICKED_BODY :
{
movePickedBody ( btVector3 ( clientCmd . m_pickBodyArguments . m_rayFromWorld [ 0 ] ,
clientCmd . m_pickBodyArguments . m_rayFromWorld [ 1 ] ,
clientCmd . m_pickBodyArguments . m_rayFromWorld [ 2 ] ) ,
btVector3 ( clientCmd . m_pickBodyArguments . m_rayToWorld [ 0 ] ,
clientCmd . m_pickBodyArguments . m_rayToWorld [ 1 ] ,
clientCmd . m_pickBodyArguments . m_rayToWorld [ 2 ] ) ) ;
SharedMemoryStatus & serverCmd =
m_data - > createServerStatus ( CMD_CLIENT_COMMAND_COMPLETED ,
clientCmd . m_sequenceNumber , timeStamp ) ;
m_data - > submitServerStatus ( serverCmd ) ;
break ;
}
case CMD_REMOVE_PICKING_CONSTRAINT_BODY :
{
removePickingConstraint ( ) ;
SharedMemoryStatus & serverCmd =
m_data - > createServerStatus ( CMD_CLIENT_COMMAND_COMPLETED ,
clientCmd . m_sequenceNumber , timeStamp ) ;
m_data - > submitServerStatus ( serverCmd ) ;
break ;
}
2015-05-28 23:05:24 +00:00
default :
{
2015-07-31 06:22:44 +00:00
b3Error ( " Unknown command encountered " ) ;
SharedMemoryStatus & serverCmd = m_data - > createServerStatus ( CMD_UNKNOWN_COMMAND_FLUSHED , clientCmd . m_sequenceNumber , timeStamp ) ;
m_data - > submitServerStatus ( serverCmd ) ;
2015-05-28 23:05:24 +00:00
}
} ;
}
}
}
2015-08-07 07:13:26 +00:00
void PhysicsServerSharedMemory : : renderScene ( )
{
if ( m_data - > m_guiHelper )
{
m_data - > m_guiHelper - > syncPhysicsToGraphics ( m_data - > m_dynamicsWorld ) ;
m_data - > m_guiHelper - > render ( m_data - > m_dynamicsWorld ) ;
}
}
void PhysicsServerSharedMemory : : physicsDebugDraw ( int debugDrawFlags )
{
2015-09-03 21:18:22 +00:00
#if 0
2015-08-07 07:13:26 +00:00
if ( m_data - > m_dynamicsWorld )
{
if ( m_data - > m_dynamicsWorld - > getDebugDrawer ( ) )
{
2015-09-03 21:18:22 +00:00
//m_data->m_debugDrawer->m_lines.clear();
//m_data->m_dynamicsWorld->getDebugDrawer()->setDebugMode(debugDrawFlags);
2015-08-07 07:13:26 +00:00
}
m_data - > m_dynamicsWorld - > debugDrawWorld ( ) ;
}
2015-09-03 21:18:22 +00:00
# endif
2015-08-07 07:13:26 +00:00
}
2015-09-04 18:28:08 +00:00
bool PhysicsServerSharedMemory : : pickBody ( const btVector3 & rayFromWorld , const btVector3 & rayToWorld )
{
if ( m_data - > m_dynamicsWorld = = 0 )
return false ;
btCollisionWorld : : ClosestRayResultCallback rayCallback ( rayFromWorld , rayToWorld ) ;
m_data - > m_dynamicsWorld - > rayTest ( rayFromWorld , rayToWorld , rayCallback ) ;
if ( rayCallback . hasHit ( ) )
{
btVector3 pickPos = rayCallback . m_hitPointWorld ;
btRigidBody * body = ( btRigidBody * ) btRigidBody : : upcast ( rayCallback . m_collisionObject ) ;
if ( body )
{
//other exclusions?
if ( ! ( body - > isStaticObject ( ) | | body - > isKinematicObject ( ) ) )
{
m_data - > m_pickedBody = body ;
m_data - > m_pickedBody - > setActivationState ( DISABLE_DEACTIVATION ) ;
//printf("pickPos=%f,%f,%f\n",pickPos.getX(),pickPos.getY(),pickPos.getZ());
btVector3 localPivot = body - > getCenterOfMassTransform ( ) . inverse ( ) * pickPos ;
btPoint2PointConstraint * p2p = new btPoint2PointConstraint ( * body , localPivot ) ;
m_data - > m_dynamicsWorld - > addConstraint ( p2p , true ) ;
m_data - > m_pickedConstraint = p2p ;
btScalar mousePickClamping = 30.f ;
p2p - > m_setting . m_impulseClamp = mousePickClamping ;
//very weak constraint for picking
p2p - > m_setting . m_tau = 0.001f ;
}
} else
{
btMultiBodyLinkCollider * multiCol = ( btMultiBodyLinkCollider * ) btMultiBodyLinkCollider : : upcast ( rayCallback . m_collisionObject ) ;
if ( multiCol & & multiCol - > m_multiBody )
{
m_data - > m_prevCanSleep = multiCol - > m_multiBody - > getCanSleep ( ) ;
multiCol - > m_multiBody - > setCanSleep ( false ) ;
btVector3 pivotInA = multiCol - > m_multiBody - > worldPosToLocal ( multiCol - > m_link , pickPos ) ;
btMultiBodyPoint2Point * p2p = new btMultiBodyPoint2Point ( multiCol - > m_multiBody , multiCol - > m_link , 0 , pivotInA , pickPos ) ;
//if you add too much energy to the system, causing high angular velocities, simulation 'explodes'
//see also http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=949
//so we try to avoid it by clamping the maximum impulse (force) that the mouse pick can apply
//it is not satisfying, hopefully we find a better solution (higher order integrator, using joint friction using a zero-velocity target motor with limited force etc?)
btScalar scaling = 1 ;
p2p - > setMaxAppliedImpulse ( 2 * scaling ) ;
btMultiBodyDynamicsWorld * world = ( btMultiBodyDynamicsWorld * ) m_data - > m_dynamicsWorld ;
world - > addMultiBodyConstraint ( p2p ) ;
m_data - > m_pickingMultiBodyPoint2Point = p2p ;
}
}
// pickObject(pickPos, rayCallback.m_collisionObject);
m_data - > m_oldPickingPos = rayToWorld ;
m_data - > m_hitPos = pickPos ;
m_data - > m_oldPickingDist = ( pickPos - rayFromWorld ) . length ( ) ;
// printf("hit !\n");
//add p2p
}
return false ;
}
bool PhysicsServerSharedMemory : : movePickedBody ( const btVector3 & rayFromWorld , const btVector3 & rayToWorld )
{
if ( m_data - > m_pickedBody & & m_data - > m_pickedConstraint )
{
btPoint2PointConstraint * pickCon = static_cast < btPoint2PointConstraint * > ( m_data - > m_pickedConstraint ) ;
if ( pickCon )
{
//keep it at the same picking distance
btVector3 dir = rayToWorld - rayFromWorld ;
dir . normalize ( ) ;
dir * = m_data - > m_oldPickingDist ;
btVector3 newPivotB = rayFromWorld + dir ;
pickCon - > setPivotB ( newPivotB ) ;
}
}
if ( m_data - > m_pickingMultiBodyPoint2Point )
{
//keep it at the same picking distance
btVector3 dir = rayToWorld - rayFromWorld ;
dir . normalize ( ) ;
dir * = m_data - > m_oldPickingDist ;
btVector3 newPivotB = rayFromWorld + dir ;
m_data - > m_pickingMultiBodyPoint2Point - > setPivotInB ( newPivotB ) ;
}
return false ;
}
void PhysicsServerSharedMemory : : removePickingConstraint ( )
{
if ( m_data - > m_pickedConstraint )
{
m_data - > m_dynamicsWorld - > removeConstraint ( m_data - > m_pickedConstraint ) ;
delete m_data - > m_pickedConstraint ;
m_data - > m_pickedConstraint = 0 ;
m_data - > m_pickedBody = 0 ;
}
if ( m_data - > m_pickingMultiBodyPoint2Point )
{
m_data - > m_pickingMultiBodyPoint2Point - > getMultiBodyA ( ) - > setCanSleep ( m_data - > m_prevCanSleep ) ;
btMultiBodyDynamicsWorld * world = ( btMultiBodyDynamicsWorld * ) m_data - > m_dynamicsWorld ;
world - > removeMultiBodyConstraint ( m_data - > m_pickingMultiBodyPoint2Point ) ;
delete m_data - > m_pickingMultiBodyPoint2Point ;
m_data - > m_pickingMultiBodyPoint2Point = 0 ;
}
}