00001
00002 #include "PhysicsWorld.h"
00003
00004 namespace RenderTools {
00005
00006 PropertyContainerPtr PhysicsWorld::s_instance = PropertyContainerPtr();
00007 float PhysicsWorld::s_step = 0.01f;
00008 bool PhysicsWorld::s_initialized = false;
00009
00010 #ifdef RT_BULLET
00011 btDefaultCollisionConfiguration * PhysicsWorld::s_config = 0;
00012 btCollisionDispatcher * PhysicsWorld::s_dispatcher = 0;
00013 btSequentialImpulseConstraintSolver * PhysicsWorld::s_solver = 0;
00014 btDiscreteDynamicsWorld * PhysicsWorld::s_world = 0;
00015 btAlignedObjectArray<btRigidBody*> PhysicsWorld::s_bodies;
00016 btAxisSweep3 * PhysicsWorld::s_cache = 0;
00017 btClock PhysicsWorld::s_clock;
00018 #endif
00019
00020 PropertyPtr PhysicsWorld::create( const XMLNodePtr & xml ){
00021 if( ! s_instance ){
00022 s_instance = PropertyContainerPtr( new RelationalNode() );
00023 createProperty( s_instance.get(), "step", & s_step );
00024 s_instance->setProperties( xml, false );
00025 }
00026 else{
00027 Error::error( Error::REINITIALIZATION, __FILE__, __LINE__ );
00028 }
00029 return( s_instance );
00030 }
00031
00032 void PhysicsWorld::initialize(){
00033 if( s_initialized ){
00034 return;
00035 }
00036
00037 #ifdef RT_BULLET
00039 while( s_bodies.size() ){
00040 deleteRigidBody( s_bodies[ 0 ] );
00041 }
00042
00043 if( s_solver ){
00044
00045 delete s_solver;
00046 }
00047
00048 if( s_cache ){
00049
00050 delete s_cache;
00051 }
00052
00053 if( s_dispatcher ){
00054
00055 delete s_dispatcher;
00056 }
00057
00058 if( s_config ){
00059
00060 delete s_config;
00061 }
00062
00063
00064 s_config = new btDefaultCollisionConfiguration();
00065
00066
00067 s_dispatcher = new btCollisionDispatcher( s_config );
00068
00069
00070 s_solver = new btSequentialImpulseConstraintSolver();
00071
00073 Vec3 worldMin( - 2.0 * WARP_X, - 2.0 * WARP_Y, - 10.0 );
00074 Vec3 worldMax( + 2.0 * WARP_X, + 2.0 * WARP_Y, + 10000.0 );
00075 s_cache = new btAxisSweep3( toSim( worldMin ), toSim( worldMax ), MAX_OBJECTS );
00076
00077
00078 s_world = new btDiscreteDynamicsWorld( s_dispatcher, s_cache, s_solver, s_config );
00079
00080
00081 s_world->setGravity( btVector3( 0.0, 0.0, -100.0 ) );
00082
00083
00084 btCollisionShape * ground = new btBoxShape( btVector3( 3 * WARP_X, 3 * WARP_Y, 10 ) );
00085
00086
00087 btTransform groundTransform;
00088 groundTransform.setOrigin( btVector3( 0, 0, -10 ) );
00089 btDefaultMotionState * motionState = new btDefaultMotionState( groundTransform );
00090 btRigidBody::btRigidBodyConstructionInfo rbInfo( btScalar(0.0), motionState, ground, btVector3( 0.0, 0.0, 0.0 ) );
00091 btRigidBody * body = new btRigidBody( rbInfo );
00092 body->setFriction( 0.5 );
00093
00094
00095 addRigidBody( body );
00096 #endif
00097 }
00098
00099 #ifdef RT_BULLET
00100 void PhysicsWorld::addRigidBody( btRigidBody * const & body ){
00101 s_bodies.push_back( body );
00102 if( ! s_world ){
00103 Error::error( Error::NULL_POINTER, __FILE__, __LINE__ );
00104 }
00105 s_world->addRigidBody( body );
00106 }
00107
00108 void PhysicsWorld::deleteRigidBody( btRigidBody * const & body ){
00109 if( body ){
00110 s_bodies.remove( body );
00112 for( int i = 0; i < body->getNumConstraintRefs(); i++ ){
00113 s_world->removeConstraint( body->getConstraintRef( i ) );
00114 body->removeConstraintRef( body->getConstraintRef( i ) );
00115 }
00116 s_world->removeRigidBody( body );
00117 }
00118 }
00119
00120 void PhysicsWorld::deleteConstraint( btTypedConstraint * const & constraint ){
00121 if( constraint ){
00122 s_world->removeConstraint( constraint );
00123 delete constraint;
00124 }
00125 }
00126 #endif
00127
00128 void PhysicsWorld::update( void ){
00129 #ifdef RT_BULLET
00130 s_world->stepSimulation( s_step, 30, s_step );
00131 #endif
00132 }
00133
00134 float PhysicsWorld::toSim( float x ){
00135 return( x * 0.1 );
00136 }
00137
00138 float PhysicsWorld::fromSim( float x ){
00139 return( x * 10.0 );
00140 }
00141
00142 Vec3 PhysicsWorld::fromSim( const Vec3 & x ){
00143 Vec3 r;
00144 r[0] = fromSim( x[0] );
00145 r[1] = fromSim( x[1] );
00146 r[2] = fromSim( x[2] );
00147 return( r );
00148 }
00149
00150 Mat4 PhysicsWorld::fromSim( const Mat4 & x ){
00151 Mat4 m( x );
00152 m.setCol( 3, Vec4( fromSim( x.getCol(3).xyz() ), 1.0f ) );
00153 return( m );
00154 }
00155
00156 Vec3 PhysicsWorld::getWarpVector(){
00157 return( Vec3( WARP_X, WARP_Y, WARP_Z ) );
00158 }
00159
00160 void PhysicsWorld::setTimeStep( float step ){
00161 s_step = step;
00162 }
00163
00164 float PhysicsWorld::getTimeStep( void ){
00165 return( s_step );
00166 }
00167
00168 #ifdef RT_BULLET
00169 btVector3 PhysicsWorld::toSim( const Vec3 & v ){
00170 btVector3 r;
00171 r[0] = toSim( v[0] );
00172 r[1] = toSim( v[1] );
00173 r[2] = toSim( v[2] );
00174 return( r );
00175 }
00176
00177 btVector3 PhysicsWorld::toSim( const btVector3 & v ){
00178 btVector3 r;
00179 r[0] = toSim( v[0] );
00180 r[1] = toSim( v[1] );
00181 r[2] = toSim( v[2] );
00182 return( r );
00183 }
00184
00185 Vec3 PhysicsWorld::fromSim( const btVector3 & x ){
00186 Vec3 r;
00187 r[0] = fromSim( x[0] );
00188 r[1] = fromSim( x[1] );
00189 r[2] = fromSim( x[2] );
00190 return( r );
00191 }
00192
00193 btTransform PhysicsWorld::toSim( const Mat4 & x ){
00195 Mat4 xt = x;
00196 btTransform t;
00197 t.setFromOpenGLMatrix( x.getPointer() );
00198 t.setOrigin( toSim( t.getOrigin() ) );
00199 return( t );
00200 }
00201
00202 Mat4 PhysicsWorld::fromSim( const btTransform & x ){
00204 btScalar ogl[16];
00205 x.getOpenGLMatrix( ogl );
00206 Mat4 m( ogl );
00207 m.setCol( 3, Vec4( fromSim( m.getCol(3).xyz() ), 1.0f ) );
00208 return( m );
00209 }
00210
00211 static btDiscreteDynamicsWorld * PhysicsWorld::getWorld( void ){
00212 return( s_world );
00213 }
00214
00215 #endif
00216
00217 };