2015-04-16 16:55:32 +00:00
# ifndef COMMON_MULTI_BODY_SETUP_H
# define COMMON_MULTI_BODY_SETUP_H
# include "btBulletDynamicsCommon.h"
# include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h"
# include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
# include "BulletDynamics/Featherstone/btMultiBodyPoint2Point.h"
# include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
# include "btBulletDynamicsCommon.h"
2015-04-29 20:33:26 +00:00
# include "CommonExampleInterface.h"
2015-04-16 16:55:32 +00:00
# include "CommonGUIHelperInterface.h"
# include "CommonRenderInterface.h"
# include "CommonGraphicsAppInterface.h"
# include "CommonWindowInterface.h"
2015-04-16 22:16:13 +00:00
# include "CommonCameraInterface.h"
2015-04-16 16:55:32 +00:00
2017-01-16 16:23:49 +00:00
enum MyFilterModes
{
2018-09-23 21:17:31 +00:00
FILTER_GROUPAMASKB_AND_GROUPBMASKA2 = 0 ,
2017-01-16 16:23:49 +00:00
FILTER_GROUPAMASKB_OR_GROUPBMASKA2
} ;
struct MyOverlapFilterCallback2 : public btOverlapFilterCallback
{
int m_filterMode ;
2018-09-23 21:17:31 +00:00
2017-01-16 16:23:49 +00:00
MyOverlapFilterCallback2 ( )
2018-09-23 21:17:31 +00:00
: m_filterMode ( FILTER_GROUPAMASKB_AND_GROUPBMASKA2 )
2017-01-16 16:23:49 +00:00
{
}
2018-09-23 21:17:31 +00:00
2017-01-16 16:23:49 +00:00
virtual ~ MyOverlapFilterCallback2 ( )
2018-09-23 21:17:31 +00:00
{
}
2017-01-16 16:23:49 +00:00
// return true when pairs need collision
2018-09-23 21:17:31 +00:00
virtual bool needBroadphaseCollision ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 ) const
2017-01-16 16:23:49 +00:00
{
2018-09-23 21:17:31 +00:00
if ( m_filterMode = = FILTER_GROUPAMASKB_AND_GROUPBMASKA2 )
2017-01-16 16:23:49 +00:00
{
bool collides = ( proxy0 - > m_collisionFilterGroup & proxy1 - > m_collisionFilterMask ) ! = 0 ;
collides = collides & & ( proxy1 - > m_collisionFilterGroup & proxy0 - > m_collisionFilterMask ) ;
return collides ;
}
2018-09-23 21:17:31 +00:00
if ( m_filterMode = = FILTER_GROUPAMASKB_OR_GROUPBMASKA2 )
2017-01-16 16:23:49 +00:00
{
bool collides = ( proxy0 - > m_collisionFilterGroup & proxy1 - > m_collisionFilterMask ) ! = 0 ;
collides = collides | | ( proxy1 - > m_collisionFilterGroup & proxy0 - > m_collisionFilterMask ) ;
return collides ;
}
return false ;
}
} ;
2015-04-29 20:33:26 +00:00
struct CommonMultiBodyBase : public CommonExampleInterface
2015-04-16 16:55:32 +00:00
{
2018-09-23 21:17:31 +00:00
//keep the collision shapes, for deletion/cleanup
btAlignedObjectArray < btCollisionShape * > m_collisionShapes ;
2017-01-16 16:23:49 +00:00
MyOverlapFilterCallback2 * m_filterCallback ;
btOverlappingPairCache * m_pairCache ;
2018-09-23 21:17:31 +00:00
btBroadphaseInterface * m_broadphase ;
btCollisionDispatcher * m_dispatcher ;
btMultiBodyConstraintSolver * m_solver ;
2015-04-16 16:55:32 +00:00
btDefaultCollisionConfiguration * m_collisionConfiguration ;
btMultiBodyDynamicsWorld * m_dynamicsWorld ;
//data for picking objects
2018-09-23 21:17:31 +00:00
class btRigidBody * m_pickedBody ;
2015-04-16 16:55:32 +00:00
class btTypedConstraint * m_pickedConstraint ;
2018-09-23 21:17:31 +00:00
class btMultiBodyPoint2Point * m_pickingMultiBodyPoint2Point ;
2015-04-16 16:55:32 +00:00
btVector3 m_oldPickingPos ;
btVector3 m_hitPos ;
btScalar m_oldPickingDist ;
bool m_prevCanSleep ;
struct GUIHelperInterface * m_guiHelper ;
CommonMultiBodyBase ( GUIHelperInterface * helper )
2018-09-23 21:17:31 +00:00
: m_filterCallback ( 0 ) ,
m_pairCache ( 0 ) ,
m_broadphase ( 0 ) ,
m_dispatcher ( 0 ) ,
m_solver ( 0 ) ,
m_collisionConfiguration ( 0 ) ,
m_dynamicsWorld ( 0 ) ,
m_pickedBody ( 0 ) ,
m_pickedConstraint ( 0 ) ,
m_pickingMultiBodyPoint2Point ( 0 ) ,
m_prevCanSleep ( false ) ,
m_guiHelper ( helper )
2015-04-16 16:55:32 +00:00
{
}
virtual void createEmptyDynamicsWorld ( )
{
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btDefaultCollisionConfiguration ( ) ;
//m_collisionConfiguration->setConvexConvexMultipointIterations();
2017-01-16 16:23:49 +00:00
m_filterCallback = new MyOverlapFilterCallback2 ( ) ;
2018-09-23 21:17:31 +00:00
2015-04-16 16:55:32 +00:00
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
2018-09-23 21:17:31 +00:00
m_dispatcher = new btCollisionDispatcher ( m_collisionConfiguration ) ;
2015-04-16 16:55:32 +00:00
2017-01-16 16:23:49 +00:00
m_pairCache = new btHashedOverlappingPairCache ( ) ;
m_pairCache - > setOverlapFilterCallback ( m_filterCallback ) ;
2018-09-23 21:17:31 +00:00
m_broadphase = new btDbvtBroadphase ( m_pairCache ) ; //btSimpleBroadphase();
2015-04-16 16:55:32 +00:00
m_solver = new btMultiBodyConstraintSolver ;
m_dynamicsWorld = new btMultiBodyDynamicsWorld ( m_dispatcher , m_broadphase , m_solver , m_collisionConfiguration ) ;
m_dynamicsWorld - > setGravity ( btVector3 ( 0 , - 10 , 0 ) ) ;
}
virtual void stepSimulation ( float deltaTime )
{
if ( m_dynamicsWorld )
{
m_dynamicsWorld - > stepSimulation ( deltaTime ) ;
}
}
virtual void exitPhysics ( )
{
removePickingConstraint ( ) ;
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
if ( m_dynamicsWorld )
{
2018-09-23 21:17:31 +00:00
int i ;
for ( i = m_dynamicsWorld - > getNumConstraints ( ) - 1 ; i > = 0 ; i - - )
{
m_dynamicsWorld - > removeConstraint ( m_dynamicsWorld - > getConstraint ( i ) ) ;
}
2015-04-16 16:55:32 +00:00
2016-07-17 00:40:44 +00:00
for ( i = m_dynamicsWorld - > getNumMultiBodyConstraints ( ) - 1 ; i > = 0 ; i - - )
{
btMultiBodyConstraint * mbc = m_dynamicsWorld - > getMultiBodyConstraint ( i ) ;
m_dynamicsWorld - > removeMultiBodyConstraint ( mbc ) ;
delete mbc ;
}
for ( i = m_dynamicsWorld - > getNumMultibodies ( ) - 1 ; i > = 0 ; i - - )
{
btMultiBody * mb = m_dynamicsWorld - > getMultiBody ( i ) ;
m_dynamicsWorld - > removeMultiBody ( mb ) ;
delete mb ;
}
2015-04-16 16:55:32 +00:00
for ( i = m_dynamicsWorld - > getNumCollisionObjects ( ) - 1 ; i > = 0 ; i - - )
{
btCollisionObject * obj = m_dynamicsWorld - > getCollisionObjectArray ( ) [ i ] ;
btRigidBody * body = btRigidBody : : upcast ( obj ) ;
if ( body & & body - > getMotionState ( ) )
{
delete body - > getMotionState ( ) ;
}
m_dynamicsWorld - > removeCollisionObject ( obj ) ;
delete obj ;
}
}
//delete collision shapes
2018-09-23 21:17:31 +00:00
for ( int j = 0 ; j < m_collisionShapes . size ( ) ; j + + )
2015-04-16 16:55:32 +00:00
{
btCollisionShape * shape = m_collisionShapes [ j ] ;
delete shape ;
}
m_collisionShapes . clear ( ) ;
delete m_dynamicsWorld ;
2015-11-13 18:37:43 +00:00
m_dynamicsWorld = 0 ;
2015-04-16 16:55:32 +00:00
delete m_solver ;
2018-09-23 21:17:31 +00:00
m_solver = 0 ;
2015-04-16 16:55:32 +00:00
delete m_broadphase ;
2018-09-23 21:17:31 +00:00
m_broadphase = 0 ;
2015-04-16 16:55:32 +00:00
delete m_dispatcher ;
2018-09-23 21:17:31 +00:00
m_dispatcher = 0 ;
2017-01-16 16:23:49 +00:00
delete m_pairCache ;
m_pairCache = 0 ;
2015-04-16 16:55:32 +00:00
2017-01-16 16:23:49 +00:00
delete m_filterCallback ;
m_filterCallback = 0 ;
2018-09-23 21:17:31 +00:00
2015-04-16 16:55:32 +00:00
delete m_collisionConfiguration ;
2018-09-23 21:17:31 +00:00
m_collisionConfiguration = 0 ;
2015-04-16 16:55:32 +00:00
}
virtual void syncPhysicsToGraphics ( )
{
if ( m_dynamicsWorld )
{
m_guiHelper - > syncPhysicsToGraphics ( m_dynamicsWorld ) ;
}
}
virtual void renderScene ( )
{
2018-09-23 21:17:31 +00:00
if ( m_dynamicsWorld )
{
m_guiHelper - > syncPhysicsToGraphics ( m_dynamicsWorld ) ;
2015-04-16 16:55:32 +00:00
2018-09-23 21:17:31 +00:00
m_guiHelper - > render ( m_dynamicsWorld ) ;
}
2015-04-16 16:55:32 +00:00
}
2018-09-23 21:17:31 +00:00
virtual void physicsDebugDraw ( int debugDrawFlags )
{
if ( m_dynamicsWorld )
{
2015-04-16 16:55:32 +00:00
if ( m_dynamicsWorld - > getDebugDrawer ( ) )
{
m_dynamicsWorld - > getDebugDrawer ( ) - > setDebugMode ( debugDrawFlags ) ;
}
2018-09-23 21:17:31 +00:00
m_dynamicsWorld - > debugDrawWorld ( ) ;
}
}
2015-04-16 16:55:32 +00:00
2018-09-23 21:17:31 +00:00
virtual bool keyboardCallback ( int key , int state )
2015-04-16 16:55:32 +00:00
{
2018-09-23 21:17:31 +00:00
if ( ( key = = B3G_F3 ) & & state & & m_dynamicsWorld )
2017-11-23 02:12:02 +00:00
{
2018-09-23 21:17:31 +00:00
btDefaultSerializer * serializer = new btDefaultSerializer ( ) ;
2017-11-23 02:12:02 +00:00
m_dynamicsWorld - > serialize ( serializer ) ;
2018-09-23 21:17:31 +00:00
FILE * file = fopen ( " testFile.bullet " , " wb " ) ;
fwrite ( serializer - > getBufferPointer ( ) , serializer - > getCurrentBufferSize ( ) , 1 , file ) ;
2017-11-23 02:12:02 +00:00
fclose ( file ) ;
//b3Printf("btDefaultSerializer wrote testFile.bullet");
delete serializer ;
return true ;
}
2018-09-23 21:17:31 +00:00
return false ; //don't handle this key
2015-04-16 16:55:32 +00:00
}
2018-09-23 21:17:31 +00:00
btVector3 getRayTo ( int x , int y )
2015-04-16 16:55:32 +00:00
{
CommonRenderInterface * renderer = m_guiHelper - > getRenderInterface ( ) ;
2018-09-23 21:17:31 +00:00
2015-04-16 16:55:32 +00:00
if ( ! renderer )
{
btAssert ( 0 ) ;
2018-09-23 21:17:31 +00:00
return btVector3 ( 0 , 0 , 0 ) ;
2015-04-16 16:55:32 +00:00
}
float top = 1.f ;
float bottom = - 1.f ;
float nearPlane = 1.f ;
2018-09-23 21:17:31 +00:00
float tanFov = ( top - bottom ) * 0.5f / nearPlane ;
2015-04-16 16:55:32 +00:00
float fov = btScalar ( 2.0 ) * btAtan ( tanFov ) ;
2018-09-23 21:17:31 +00:00
btVector3 camPos , camTarget ;
2015-04-16 22:16:13 +00:00
renderer - > getActiveCamera ( ) - > getCameraPosition ( camPos ) ;
renderer - > getActiveCamera ( ) - > getCameraTargetPosition ( camTarget ) ;
2015-04-16 16:55:32 +00:00
2018-09-23 21:17:31 +00:00
btVector3 rayFrom = camPos ;
btVector3 rayForward = ( camTarget - camPos ) ;
2015-04-16 16:55:32 +00:00
rayForward . normalize ( ) ;
float farPlane = 10000.f ;
2018-09-23 21:17:31 +00:00
rayForward * = farPlane ;
2015-04-16 16:55:32 +00:00
btVector3 rightOffset ;
2018-09-23 21:17:31 +00:00
btVector3 cameraUp = btVector3 ( 0 , 0 , 0 ) ;
cameraUp [ m_guiHelper - > getAppInterface ( ) - > getUpAxis ( ) ] = 1 ;
2015-04-16 16:55:32 +00:00
btVector3 vertical = cameraUp ;
btVector3 hor ;
hor = rayForward . cross ( vertical ) ;
hor . normalize ( ) ;
vertical = hor . cross ( rayForward ) ;
vertical . normalize ( ) ;
2018-09-23 21:17:31 +00:00
float tanfov = tanf ( 0.5f * fov ) ;
2015-04-16 16:55:32 +00:00
hor * = 2.f * farPlane * tanfov ;
vertical * = 2.f * farPlane * tanfov ;
btScalar aspect ;
float width = float ( renderer - > getScreenWidth ( ) ) ;
2018-09-23 21:17:31 +00:00
float height = float ( renderer - > getScreenHeight ( ) ) ;
2015-04-16 16:55:32 +00:00
2018-09-23 21:17:31 +00:00
aspect = width / height ;
2015-04-16 16:55:32 +00:00
2018-09-23 21:17:31 +00:00
hor * = aspect ;
2015-04-16 16:55:32 +00:00
btVector3 rayToCenter = rayFrom + rayForward ;
2018-09-23 21:17:31 +00:00
btVector3 dHor = hor * 1.f / width ;
btVector3 dVert = vertical * 1.f / height ;
2015-04-16 16:55:32 +00:00
btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical ;
rayTo + = btScalar ( x ) * dHor ;
rayTo - = btScalar ( y ) * dVert ;
return rayTo ;
}
2018-09-23 21:17:31 +00:00
virtual bool mouseMoveCallback ( float x , float y )
2015-04-16 16:55:32 +00:00
{
CommonRenderInterface * renderer = m_guiHelper - > getRenderInterface ( ) ;
2018-09-23 21:17:31 +00:00
2015-04-16 16:55:32 +00:00
if ( ! renderer )
{
btAssert ( 0 ) ;
return false ;
}
btVector3 rayTo = getRayTo ( int ( x ) , int ( y ) ) ;
btVector3 rayFrom ;
2015-04-16 22:16:13 +00:00
renderer - > getActiveCamera ( ) - > getCameraPosition ( rayFrom ) ;
2018-09-23 21:17:31 +00:00
movePickedBody ( rayFrom , rayTo ) ;
2015-04-16 16:55:32 +00:00
return false ;
}
2018-09-23 21:17:31 +00:00
virtual bool mouseButtonCallback ( int button , int state , float x , float y )
2015-04-16 16:55:32 +00:00
{
CommonRenderInterface * renderer = m_guiHelper - > getRenderInterface ( ) ;
2018-09-23 21:17:31 +00:00
2015-04-16 16:55:32 +00:00
if ( ! renderer )
{
btAssert ( 0 ) ;
return false ;
}
2018-09-23 21:17:31 +00:00
2015-04-17 00:35:34 +00:00
CommonWindowInterface * window = m_guiHelper - > getAppInterface ( ) - > m_window ;
2015-04-16 16:55:32 +00:00
2018-09-23 21:17:31 +00:00
if ( state = = 1 )
2015-04-16 16:55:32 +00:00
{
2018-09-23 21:17:31 +00:00
if ( button = = 0 & & ( ! window - > isModifierKeyPressed ( B3G_ALT ) & & ! window - > isModifierKeyPressed ( B3G_CONTROL ) ) )
2015-04-16 16:55:32 +00:00
{
btVector3 camPos ;
2015-04-16 22:16:13 +00:00
renderer - > getActiveCamera ( ) - > getCameraPosition ( camPos ) ;
2015-04-16 16:55:32 +00:00
btVector3 rayFrom = camPos ;
2018-09-23 21:17:31 +00:00
btVector3 rayTo = getRayTo ( int ( x ) , int ( y ) ) ;
2015-04-16 16:55:32 +00:00
pickBody ( rayFrom , rayTo ) ;
}
2018-09-23 21:17:31 +00:00
}
else
2015-04-16 16:55:32 +00:00
{
2018-09-23 21:17:31 +00:00
if ( button = = 0 )
2015-04-16 16:55:32 +00:00
{
removePickingConstraint ( ) ;
//remove p2p
}
}
//printf("button=%d, state=%d\n",button,state);
return false ;
}
virtual bool pickBody ( const btVector3 & rayFromWorld , const btVector3 & rayToWorld )
{
2018-09-23 21:17:31 +00:00
if ( m_dynamicsWorld = = 0 )
2015-04-16 16:55:32 +00:00
return false ;
btCollisionWorld : : ClosestRayResultCallback rayCallback ( rayFromWorld , rayToWorld ) ;
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_pickedBody = body ;
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_dynamicsWorld - > addConstraint ( p2p , true ) ;
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 ;
}
2018-09-23 21:17:31 +00:00
}
else
2015-04-16 16:55:32 +00:00
{
btMultiBodyLinkCollider * multiCol = ( btMultiBodyLinkCollider * ) btMultiBodyLinkCollider : : upcast ( rayCallback . m_collisionObject ) ;
if ( multiCol & & multiCol - > m_multiBody )
{
m_prevCanSleep = multiCol - > m_multiBody - > getCanSleep ( ) ;
multiCol - > m_multiBody - > setCanSleep ( false ) ;
btVector3 pivotInA = multiCol - > m_multiBody - > worldPosToLocal ( multiCol - > m_link , pickPos ) ;
2018-09-23 21:17:31 +00:00
btMultiBodyPoint2Point * p2p = new btMultiBodyPoint2Point ( multiCol - > m_multiBody , multiCol - > m_link , 0 , pivotInA , pickPos ) ;
2015-04-16 16:55:32 +00:00
//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?)
2018-09-23 21:17:31 +00:00
btScalar scaling = 1 ;
p2p - > setMaxAppliedImpulse ( 2 * scaling ) ;
btMultiBodyDynamicsWorld * world = ( btMultiBodyDynamicsWorld * ) m_dynamicsWorld ;
2015-04-16 16:55:32 +00:00
world - > addMultiBodyConstraint ( p2p ) ;
2018-09-23 21:17:31 +00:00
m_pickingMultiBodyPoint2Point = p2p ;
2015-04-16 16:55:32 +00:00
}
}
// pickObject(pickPos, rayCallback.m_collisionObject);
m_oldPickingPos = rayToWorld ;
m_hitPos = pickPos ;
m_oldPickingDist = ( pickPos - rayFromWorld ) . length ( ) ;
// printf("hit !\n");
//add p2p
}
return false ;
}
virtual bool movePickedBody ( const btVector3 & rayFromWorld , const btVector3 & rayToWorld )
{
2018-09-23 21:17:31 +00:00
if ( m_pickedBody & & m_pickedConstraint )
2015-04-16 16:55:32 +00:00
{
btPoint2PointConstraint * pickCon = static_cast < btPoint2PointConstraint * > ( m_pickedConstraint ) ;
if ( pickCon )
{
//keep it at the same picking distance
2018-09-23 21:17:31 +00:00
btVector3 dir = rayToWorld - rayFromWorld ;
2015-04-16 16:55:32 +00:00
dir . normalize ( ) ;
dir * = m_oldPickingDist ;
btVector3 newPivotB = rayFromWorld + dir ;
pickCon - > setPivotB ( newPivotB ) ;
}
}
2018-09-23 21:17:31 +00:00
2015-04-16 16:55:32 +00:00
if ( m_pickingMultiBodyPoint2Point )
{
//keep it at the same picking distance
2018-09-23 21:17:31 +00:00
btVector3 dir = rayToWorld - rayFromWorld ;
2015-04-16 16:55:32 +00:00
dir . normalize ( ) ;
dir * = m_oldPickingDist ;
btVector3 newPivotB = rayFromWorld + dir ;
2018-09-23 21:17:31 +00:00
2015-04-16 16:55:32 +00:00
m_pickingMultiBodyPoint2Point - > setPivotInB ( newPivotB ) ;
}
2018-09-23 21:17:31 +00:00
2015-04-16 16:55:32 +00:00
return false ;
}
2020-03-09 18:19:08 +00:00
2015-04-16 16:55:32 +00:00
virtual void removePickingConstraint ( )
{
if ( m_pickedConstraint )
{
m_dynamicsWorld - > removeConstraint ( m_pickedConstraint ) ;
2018-08-27 01:07:28 +00:00
if ( m_pickedBody )
{
m_pickedBody - > forceActivationState ( ACTIVE_TAG ) ;
m_pickedBody - > activate ( true ) ;
}
2015-04-16 16:55:32 +00:00
delete m_pickedConstraint ;
m_pickedConstraint = 0 ;
m_pickedBody = 0 ;
}
if ( m_pickingMultiBodyPoint2Point )
{
m_pickingMultiBodyPoint2Point - > getMultiBodyA ( ) - > setCanSleep ( m_prevCanSleep ) ;
2018-09-23 21:17:31 +00:00
btMultiBodyDynamicsWorld * world = ( btMultiBodyDynamicsWorld * ) m_dynamicsWorld ;
2015-04-16 16:55:32 +00:00
world - > removeMultiBodyConstraint ( m_pickingMultiBodyPoint2Point ) ;
delete m_pickingMultiBodyPoint2Point ;
m_pickingMultiBodyPoint2Point = 0 ;
}
}
btBoxShape * createBoxShape ( const btVector3 & halfExtents )
{
btBoxShape * box = new btBoxShape ( halfExtents ) ;
return box ;
}
2018-09-23 21:17:31 +00:00
btRigidBody * createRigidBody ( float mass , const btTransform & startTransform , btCollisionShape * shape , const btVector4 & color = btVector4 ( 1 , 0 , 0 , 1 ) )
2015-04-16 16:55:32 +00:00
{
btAssert ( ( ! shape | | shape - > getShapeType ( ) ! = INVALID_SHAPE_PROXYTYPE ) ) ;
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = ( mass ! = 0.f ) ;
btVector3 localInertia ( 0 , 0 , 0 ) ;
if ( isDynamic )
shape - > calculateLocalInertia ( mass , localInertia ) ;
2018-09-23 21:17:31 +00:00
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
2015-04-16 16:55:32 +00:00
# define USE_MOTIONSTATE 1
# ifdef USE_MOTIONSTATE
btDefaultMotionState * myMotionState = new btDefaultMotionState ( startTransform ) ;
btRigidBody : : btRigidBodyConstructionInfo cInfo ( mass , myMotionState , shape , localInertia ) ;
btRigidBody * body = new btRigidBody ( cInfo ) ;
//body->setContactProcessingThreshold(m_defaultContactProcessingThreshold);
# else
btRigidBody * body = new btRigidBody ( mass , 0 , shape , localInertia ) ;
body - > setWorldTransform ( startTransform ) ;
2018-09-23 21:17:31 +00:00
# endif //
2015-04-16 16:55:32 +00:00
body - > setUserIndex ( - 1 ) ;
m_dynamicsWorld - > addRigidBody ( body ) ;
return body ;
}
} ;
2018-09-23 21:17:31 +00:00
# endif //COMMON_MULTI_BODY_SETUP_H