📄 oasisphysicssystem.cpp
字号:
const vector3 &physicsSystem::getGravity( void ) const {
return gravity;
}
void physicsSystem::setStepSize( const real newSize ) {
stepSize = newSize;
}
const real physicsSystem::getStepSize( void ) const {
return stepSize;
}
void physicsSystem::setERP( const real newERP ) {
odeWorld->setERP( newERP );
}
const real physicsSystem::getERP( void ) const {
return odeWorld->getERP( );
}
void physicsSystem::setCFM( const real newCFM ) {
odeWorld->setCFM( newCFM );
}
const real physicsSystem::getCFM( void ) const {
return odeWorld->getCFM( );
}
#if PHYSICS_SPACE_HASH == 1
void physicsSystem::setSpaceLimits( uint16 min, uint16 max ) {
if ( min > max ) {
oasisError( exception::ET_INTERNAL_ERROR,
"Minimum MUST be smaller or equal to maximum",
"physicsSystem::setSpaceLimits" );
}
static_cast< dHashSpace* >( odeSpace )->setLevels( min, max );
}
#endif
void physicsSystem::_parseFile( Ogre::DataChunk &chunk ) {
Ogre::String line;
physicsResource *file = NULL;
while( !chunk.isEOF( ) ) {
line = chunk.getLine( );
// Ignore blanks & comments
if( !line.length( ) || line.substr( 0, 2 ) == "//" ) {
continue;
} else {
if ( file == NULL ) {
// No current script
file = createPhysicsTemplate( line );
// Skip to and over next {
chunk.skipUpTo( "{" );
} else {
// Already in script
if ( line == "}" ) {
// Finished
file = NULL;
} else {
_parseAttribute( line, file );
}
}
}
}
}
void physicsSystem::_parseAttribute( const Ogre::String &line,
physicsResource *file ) {
Ogre::StringVector params = line.split( );
Ogre::String attrib = params[ 0 ].toLowerCase( );
if ( attrib == "gravity" ) {
if ( params.size( ) != 2 ) {
_logError( line, file );
return;
}
file->setGravity( Ogre::StringConverter::parseBool( params[ 1 ] ) );
} else if ( attrib == "softness" ) {
if ( params.size( ) != 2 ) {
_logError( line, file );
return;
}
file->setSoftness( Ogre::StringConverter::parseReal( params[ 1 ] ) );
} else if ( attrib == "friction" ) {
if ( params.size( ) != 2 ) {
_logError( line, file );
return;
}
if ( params[ 1 ] == "infinite" ) {
file->setFriction( physics::infiniteFriction );
} else {
file->setFriction( Ogre::StringConverter::parseReal( params[ 1 ] ) );
}
} else if ( attrib == "bounce" ) {
if ( params.size( ) != 3 ) {
_logError( line, file );
return;
}
file->setBounce( Ogre::StringConverter::parseReal( params[ 1 ] ),
Ogre::StringConverter::parseReal( params[ 2 ] ) );
} else if ( attrib == "mass" ) {
if ( params.size( ) < 3 ) {
_logError( line, file );
return;
}
if ( params[ 1 ] == "box" || params[ 1 ] == "BOX" ) {
if ( params.size( ) != 6 ) {
_logError( line, file );
return;
}
file->getMass( )->setBox( Ogre::StringConverter::parseReal( params[ 2 ] ),
Ogre::StringConverter::parseReal( params[ 3 ] ),
Ogre::StringConverter::parseReal( params[ 4 ] ),
Ogre::StringConverter::parseReal( params[ 5 ] ) );
}
if ( params[ 1 ] == "sphere" || params[ 1 ] == "SPHERE" ) {
if ( params.size( ) != 4 ) {
_logError( line, file );
return;
}
file->getMass( )->setSphere( Ogre::StringConverter::parseReal( params[ 2 ] ),
Ogre::StringConverter::parseReal( params[ 3 ] ) );
}
if ( params[ 1 ] == "ccylinder" || params[ 1 ] == "CCYLINDER" ) {
if ( params.size( ) != 5 ) {
_logError( line, file );
return;
}
file->getMass( )->setCCylinder( Ogre::StringConverter::parseReal( params[ 2 ] ),
Ogre::StringConverter::parseReal( params[ 3 ] ),
Ogre::StringConverter::parseReal( params[ 4 ] ) );
}
} else if ( attrib == "proxy" ) {
if ( params.size( ) < 2 ) {
_logError( line, file );
return;
}
if ( params[ 1 ] == "box" || params[ 1 ] == "BOX" ) {
if ( params.size( ) != 5 ) {
_logError( line, file );
return;
}
file->addBoxProxy( Ogre::StringConverter::parseReal( params[ 2 ] ),
Ogre::StringConverter::parseReal( params[ 3 ] ),
Ogre::StringConverter::parseReal( params[ 4 ] ) );
} else if ( params[ 1 ] == "sphere" || params[ 1 ] == "SPHERE" ) {
if ( params.size( ) != 3 ) {
_logError( line, file );
return;
}
file->addSphereProxy( Ogre::StringConverter::parseReal( params[ 2 ] ) );
} else if ( params[ 1 ] == "ccylinder" || params[ 1 ] == "CCYLINDER" ) {
if ( params.size( ) != 4 ) {
_logError( line, file );
return;
}
file->addCCylinderProxy( Ogre::StringConverter::parseReal( params[ 2 ] ),
Ogre::StringConverter::parseReal( params[ 3 ] ) );
} else {
_logError( line, file );
return;
}
}
}
poolable *physicsSystem::_createPoolable( void ) {
// Create a new object
physics *newPhysics = new physics( );
return newPhysics;
}
resource *physicsSystem::createResource( const string &name ) {
// First make sure this doesn't exist
if ( getByName( name ) != 0 ) {
oasisError( exception::ET_DUPLICATE_ITEM,
"Physics resource file " + name + " already exists.",
"physicsSystem::create" );
}
physicsResource *physicsFile = new physicsResource( name );
// Don't load now
resources[ name ] = physicsFile;
return physicsFile;
}
const dWorld *physicsSystem::getODEWorld( void ) const {
return odeWorld;
}
const dJointGroup *physicsSystem::getODEContactJointGroup( void ) const {
return odeContactGroup;
}
const dSpace *physicsSystem::getODESpace( void ) const {
return odeSpace;
}
bool physicsSystem::frameStarted( real time ) {
#if USE_PROFILER == 1
{
OgreProfile( "Oasis Physics System" );
#endif
real allTime = timeLeftOver + time;
uint16 steps = ( uint16 )( allTime / stepSize );
for ( uint16 step = 0; step < steps; step++ ) {
// Collision detection
odeSpace->collide( 0, &physicsSystem::_doCollision );
// The idea here is to use the stepfast most of the time, every so
// often putting in a real simulation
if ( stepfastSwitch++ < PHYSICS_STEPFAST_RATIO ) {
dWorldStepFast1( odeWorld->id(),
stepSize,
PHYSICS_STEPFAST_ITERATIONS );
} else {
odeWorld->step( stepSize );
stepfastSwitch = 0;
}
for ( poolableMap::iterator it = usedPool.begin( );
it != usedPool.end( ); ++it ) {
static_cast< physics* >( it->second )->updateDynamics( time ) ;
}
odeContactGroup->empty( );
}
timeLeftOver = allTime - ( steps * stepSize );
#if USE_PROFILER == 1
}
#endif
return true;
}
void physicsSystem::_doCollision( void *data, dxGeom *one, dxGeom *two ) {
// ODE thinks these two proxies are probably colliding, so we do
// some real collision testing
physics *bodyOne = static_cast< physics* >( dGeomGetData( one ) );
physics *bodyTwo = static_cast< physics* >( dGeomGetData( two ) );
bodyOne->testCollision( bodyTwo, one, two );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -