📄 oasisphysicssystem.cpp
字号:
/******************************************************************************
* This source file is part of Bad Camel Gaming
* Copyright (C) 2003 Zephie Greyvenstein
* See Readme.html for acknowledgements
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************************************
* FILENAME : oasisPhysicSystem.cpp
* DESCRIPTION : The physics system
* AUTHOR : Zephie Greyvenstein
*****************************************************************************/
#include "oasisPhysicsSystem.h"
#include "oasisPhysics.h"
#include "oasisPhysicsResource.h"
#include "oasisJoints.h"
#include "oasisMass.h"
#include "oasisProxies.h"
#include "oasisFrameListenerSystem.h"
#include "oasisPhysicsCommon.h"
#include "OgreStringVector.h"
#include "OgreSDDataChunk.h"
#include "OgreStringConverter.h"
#include "OgreProfiler.h"
/// Include optional profiler
#if USE_PROFILER == 1
#include "OgreProfiler.h"
#endif
namespace Oasis {
// Setup the singleton
template< > physicsSystem *singleton< physicsSystem >::singletonPtr = 0;
physicsSystem::physicsSystem( ) : system( "Physics" ), pool( "physics" ) {
// Create the ode world
odeWorld = new dWorld( );
if ( !odeWorld ) {
oasisError( exception::ET_NULL_POINTER,
"Could not create ODE world",
"physicsSystem::( )" );
}
// Create the contact joint group
odeContactGroup = new dJointGroup( );
if ( !odeContactGroup ) {
oasisError( exception::ET_NULL_POINTER,
"Could not create ODE contact group",
"physicsSystem::( )" );
}
// Create the space
dSpaceID space = 0;
#if PHYSICS_SPACE_HASH == 0
space = dSimpleSpaceCreate( space );
odeSpace = new dSimpleSpace( space );
#elif PHYSICS_SPACE_HASH == 1
space = dHashSpaceCreate( space );
odeSpace = new dHashSpace( space );
#endif
if ( !odeSpace ) {
oasisError( exception::ET_NULL_POINTER,
"Could not create ODE space",
"physicsSystem::( )" );
}
// Clear contacts
joints.clear( );
// Clear stepfast switch
stepfastSwitch = 0;
// Parse all physic scripts
_parseAllSources( ".physics" );
// Register ourselves with the frame listener
frameListenerSystem::get( ).addFrameListener( this );
}
physicsSystem::~physicsSystem( ) {
// We have to destroy everything before ODE stuff, else it cries
removeAllJoints( );
_destroyAll( );
unloadAndDestroyAll( );
if ( odeWorld ) {
delete odeWorld;
}
if ( odeContactGroup ) {
delete odeContactGroup;
}
if ( odeSpace ) {
delete odeSpace;
}
dCloseODE( );
}
physicsSystem &physicsSystem::get( void ) {
return singleton< physicsSystem >::get( );
}
physicsSystem *physicsSystem::getPtr( void ) {
return singleton< physicsSystem >::getPtr( );
}
void physicsSystem::reset( void ) {
// Clear the pool
clearPool( );
// Clear the joints
removeAllJoints( );
// Set defaults
setGravity( 0, PHYSICS_DEFAULT_GRAVITY, 0 );
setStepSize( PHYSICS_DEFAULT_STEPSIZE );
setERP( PHYSICS_DEFAULT_ERP );
setCFM( PHYSICS_DEFAULT_CFM );
timeLeftOver = 0;
}
void physicsSystem::update( real time ) {
frameStarted( time );
}
physicsResource *physicsSystem::getPhysicsTemplate( const string &name ) {
// Try and get the template
physicsResource *physicsFile = static_cast< physicsResource* >( getByName( name ) );
if ( !physicsFile ) {
oasisError( exception::ET_ITEM_NOT_FOUND,
"Physics template " + name + " not found!",
"physicsSystem::getPhysicTemplate" );
}
return physicsFile;
}
physicsResource *physicsSystem::createPhysicsTemplate( const string &name ) {
return static_cast< physicsResource* >( createResource( name ) );
}
physics *physicsSystem::createPhysics( const string &physicsName,
const string &templateName ) {
// Try and get the template
physicsResource *temp = getPhysicsTemplate( templateName );
// Get an object from the pool
physics *newPhysics = static_cast< physics* >( _getFreePoolable( physicsName ) );
// Set it up
newPhysics->setup( temp );
return newPhysics;
}
void physicsSystem::removePhysics( physics *oldPhysics ) {
// Return object to the pool
_consumePoolable( oldPhysics );
}
void physicsSystem::removePhysics( const string &physicsName ) {
// Return object to the pool
_consumePoolable( physicsName );
}
physics *physicsSystem::getPhysics( const string &physicsName ) {
physics *phy = static_cast< physics* >( _getUsedPoolable( physicsName ) );
if ( !phy ) {
oasisError( exception::ET_ITEM_NOT_FOUND,
"Physics " + physicsName + " does not exist!",
"physicsSystem::getPhysics" );
}
return phy;
}
joint *physicsSystem::createJoint( joint::JointType type,
const string &name,
physics *first,
physics *second ) {
jointMap::iterator it = joints.find( name );
if ( it != joints.end( ) ) {
oasisError( exception::ET_DUPLICATE_ITEM,
"A joint with name " + name + " already exists",
"physicsSystem::createJoint" );
}
joint *newJoint;
switch ( type ) {
case joint::JT_BALL:
newJoint = new ballJoint( odeWorld, first, second );
break;
case joint::JT_SLIDER:
newJoint = new sliderJoint( odeWorld, first, second );
break;
case joint::JT_HINGE:
newJoint = new hingeJoint( odeWorld, first, second );
break;
case joint::JT_HINGE2:
newJoint = new hinge2Joint( odeWorld, first, second );
break;
case joint::JT_UNIVERSAL:
newJoint = new universalJoint( odeWorld, first, second );
break;
}
joints[ name ] = newJoint;
return newJoint;
}
void physicsSystem::removeJoint( const string &name ) {
joint *oldJoint = getJoint( name );
delete oldJoint;
joints.erase( name );
}
void physicsSystem::removeAllJoints( void ) {
for( jointMap::iterator it = joints.begin( );
it != joints.end( ); ++it ) {
delete it->second;
}
joints.clear( );
}
joint *physicsSystem::getJoint( const string &name ) {
jointMap::iterator it = joints.find( name );
if ( it == joints.end( ) ) {
oasisError( exception::ET_ITEM_NOT_FOUND,
"Joint " + name + " not found",
"physicsSystem::getJoint" );
} else {
return it->second;
}
}
void physicsSystem::setGravity( real x, real y, real z ) {
setGravity( vector3( x, y, z ) );
}
void physicsSystem::setGravity( const vector3 &newGravity ) {
gravity = newGravity;
odeWorld->setGravity( gravity.x, gravity.y, gravity.z );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -