Simulator.cpp

Go to the documentation of this file.
00001 /*************************************************************************
00002 *                                                                       *
00003 * Open Physics Abstraction Layer                                        *
00004 * Copyright (C) 2004-2005                                               *
00005 * Alan Fischer  alan.fischer@gmail.com                                  *
00006 * Andres Reinot  andres@reinot.com                                      *
00007 * Tyler Streeter  tylerstreeter@gmail.com                               *
00008 * All rights reserved.                                                  *
00009 * Web: opal.sourceforge.net                                             *
00010 *                                                                       *
00011 * This library is free software; you can redistribute it and/or         *
00012 * modify it under the terms of EITHER:                                  *
00013 *   (1) The GNU Lesser General Public License as published by the Free  *
00014 *       Software Foundation; either version 2.1 of the License, or (at  *
00015 *       your option) any later version. The text of the GNU Lesser      *
00016 *       General Public License is included with this library in the     *
00017 *       file license-LGPL.txt.                                          *
00018 *   (2) The BSD-style license that is included with this library in     *
00019 *       the file license-BSD.txt.                                       *
00020 *                                                                       *
00021 * This library is distributed in the hope that it will be useful,       *
00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
00024 * license-LGPL.txt and license-BSD.txt for more details.                *
00025 *                                                                       *
00026 *************************************************************************/
00027 
00028 // class headers
00029 #include "Simulator.h"
00030 
00031 // project headers
00032 #include "BlueprintInstance.h"
00033 #include "BoxShapeData.h"
00034 #include "SphereShapeData.h"
00035 #include "CapsuleShapeData.h"
00036 #include "PlaneShapeData.h"
00037 #include "ThrusterMotor.h"
00038 #include "GearedMotor.h"
00039 #include "ServoMotor.h"
00040 #include "AttractorMotor.h"
00041 #include "SpringMotor.h"
00042 #include "AccelerationSensor.h"
00043 #include "InclineSensor.h"
00044 #include "RaycastSensor.h"
00045 #include "VolumeSensor.h"
00046 #include "PostStepEventHandler.h"
00047 #include "VelocityMotor.h"
00048 
00049 namespace opal
00050 {
00051         Simulator::Simulator()
00052         {
00053                 mTimeBuffer = 0;
00054                 setStepSize( defaults::stepSize );
00055                 //setMaxLinearVel(defaults::maxLinearVel);
00056                 //setMaxAngularVel(defaults::maxAngularVel);
00057                 setMaxCorrectingVel( defaults::maxCorrectingVel );
00058                 setMaxContacts( defaults::maxContacts );
00059                 setUserData( NULL );
00060                 mIsSolidDestructionSafe = true;
00061                 mIsJointDestructionSafe = true;
00062                 mStaticSleepingContactsEnabled =
00063                     defaults::staticSleepingContactsEnabled;
00064 
00065                 int i = 0;
00066                 for ( i = 0; i < 32; ++i )
00067                 {
00068                         mContactGroupFlags[ i ] = defaults::contactGroupFlags;
00069                 }
00070 
00071                 mRootSpace = NULL;
00072         }
00073 
00074         void Simulator::initData( SimulatorData data )
00075         {
00076                 mData = data;
00077         }
00078 
00079         Simulator::~Simulator()
00080         {
00081                 destroyAllSolids();
00082                 destroyAllJoints();
00083                 destroyAllMotors();
00084                 destroyAllSensors();
00085 
00086                 while ( !mSpaceList.empty() )
00087                 {
00088                         mSpaceList.back() ->internal_destroy();
00089                         mSpaceList.pop_back();
00090                 }
00091                 mRootSpace->internal_destroy();
00092 
00093                 mSolidGarbageList.clear();
00094                 mJointGarbageList.clear();
00095         }
00096 
00097         bool Simulator::simulate( real dt )
00098         {
00099                 mTimeBuffer += dt;
00100 
00101                 // Use this to return true if at least one step occurred.
00102                 bool stepOccurred = false;
00103                 if ( mTimeBuffer >= mStepSize )
00104                 {
00105                         stepOccurred = true;
00106                 }
00107 
00108                 //if (mAllowPartialFrames && mTimeBuffer >= (real)defaults::maxStepsPerFrame * mStepSize)
00109                 //{
00110                 //  mTimeBuffer = defaults::maxStepsPerFrame * mStepSize;
00111                 //}
00112 
00113                 while ( mTimeBuffer >= mStepSize )
00114                 {
00115                         // Update Sensors.
00116                         std::vector<Sensor*>::iterator sensorIter;
00117                         for ( sensorIter = mSensorList.begin();
00118                                 sensorIter != mSensorList.end(); ++sensorIter )
00119                         {
00120                                 ( *sensorIter ) ->internal_update();
00121                         }
00122 
00123                         // Update Motors.
00124                         std::vector<Motor*>::iterator motorIter;
00125                         for ( motorIter = mMotorList.begin();
00126                                 motorIter != mMotorList.end(); ++motorIter )
00127                         {
00128                                 ( *motorIter ) ->internal_update();
00129                         }
00130 
00131                         // Apply forces/torques to Solids.
00132                         std::vector<Solid*>::iterator solidIter;
00133                         for ( solidIter = mSolidList.begin();
00134                                 solidIter != mSolidList.end(); ++solidIter )
00135                         {
00136                                 ( *solidIter ) ->internal_applyForces( mStepSize );
00137                         }
00138 
00139                         // Update Joints.
00140                         mIsJointDestructionSafe = false;
00141                         std::vector<Joint*>::iterator jointIter;
00142                         for ( jointIter = mJointList.begin();
00143                                 jointIter != mJointList.end(); ++jointIter )
00144                         {
00145                                 // If a Joint gets broken here, it will automatically
00146                                 // send a Joint break event to the Joint's
00147                                 // JointBreakEventHandler (assuming one exists).
00148                                 ( *jointIter ) ->internal_update();
00149                         }
00150                         mIsJointDestructionSafe = true;
00151 
00152                         // Now do physics engine-specific stuff; collision events will
00153                         // be sent from here.
00154                         stepPhysics();
00155 
00156                         // Loop over Solids again to handle a few more things...
00157                         mIsSolidDestructionSafe = false;
00158                         for ( solidIter = mSolidList.begin();
00159                                 solidIter != mSolidList.end(); ++solidIter )
00160                         {
00161                                 Solid* solid = *solidIter;
00162 
00163                                 // Get each dynamic, awake Solid's new transform from the
00164                                 // physics engine.
00165                                 if ( !solid->isStatic() && !solid->isSleeping() )
00166                                 {
00167                                         solid->internal_updateOPALTransform();
00168                                         solid->setMovingState( true );
00169                                 }
00170 
00171                                 // Update the sleeping value from the physics engine.  This
00172                                 // needs to be updated to keep the Solid's SolidData valid.
00173                                 //solid->internal_updateSleeping();
00174                                 // Update... Now this gets updated in the Solid::getData
00175                                 // function.
00176 
00177                                 // Update the Solid's CollisionEventHandler if applicable.
00178                                 if ( solid->getCollisionEventHandler() )
00179                                 {
00180                                         solid->getCollisionEventHandler() ->
00181                                         internal_handlePendingCollisionEvents();
00182                                 }
00183 
00184                                 if ( solid->getMovementEventHandler() )
00185                                 {
00186                                         if ( solid->isMoving() )
00187                                         {
00188                                                 MovementEvent move( solid );
00189                                                 solid->getMovementEventHandler() ->handleMovementEvent( move );
00190                                         }
00191                                 }
00192                         }
00193                         mIsSolidDestructionSafe = true;
00194 
00195                         // Fire an event to the PostStepEventHandler, if one exists.
00196                         if ( getNumPostStepEventHandlers() > 0 )
00197                         {
00198                                 for ( size_t i = 0; i < mPostStepEventHandlers.size(); ++i )
00199                                         mPostStepEventHandlers[ i ] ->handlePostStepEvent();
00200                         }
00201 
00202                         if ( getNumGlobalCollisionEventHandlers() > 0 )
00203                         {
00204                                 for ( size_t i = 0; i < mCollisionEventHandlers.size(); ++i )
00205                                         mCollisionEventHandlers[ i ] ->internal_handlePendingCollisionEvents();
00206                         }
00207 
00208                         // Destroy garbage now that it's safe.
00209                         destroyGarbage();
00210 
00211                         //Decrement the time buffer
00212                         mTimeBuffer -= mStepSize;
00213                 }
00214 
00215                 return stepOccurred;
00216         }
00217 
00218         void Simulator::internal_recordCollision( const CollisionEvent & event )
00219         {
00220                 if ( mCollisionEventHandlers.size() > 0 )
00221                 {
00222                         for ( size_t i = 0; i < mCollisionEventHandlers.size(); ++i )
00223                         {
00224                                 mCollisionEventHandlers[ i ] ->internal_pushCollisionEvent( event );
00225                         }
00226                 }
00227         }
00228 
00229         void Simulator::setStepSize( real stepSize )
00230         {
00231                 assert( stepSize > 0 );
00232                 mStepSize = stepSize;
00233         }
00234 
00235         real Simulator::getStepSize()
00236         {
00237                 return mStepSize;
00238         }
00239 
00240         void Simulator::addPostStepEventHandler(
00241             PostStepEventHandler* eventHandler )
00242         {
00243                 mPostStepEventHandlers.push_back( eventHandler );
00244         }
00245 
00246         PostStepEventHandler* Simulator::getPostStepEventHandler( unsigned int id ) const
00247         {
00248                 return mPostStepEventHandlers[ id ];
00249         }
00250 
00251         void Simulator::removePostStepEventHandler(
00252             PostStepEventHandler * eventHandler )
00253         {
00254                 for ( size_t i = 0; i < mPostStepEventHandlers.size(); ++i )
00255                 {
00256                         if ( mPostStepEventHandlers[ i ] == eventHandler )
00257                         {
00258                                 mPostStepEventHandlers.erase( mPostStepEventHandlers.begin() + i );
00259                         }
00260                 }
00261         }
00262 
00263         size_t Simulator::getNumPostStepEventHandlers() const
00264         {
00265                 return mPostStepEventHandlers.size();
00266         }
00267 
00268         void Simulator::addGlobalCollisionEventHandler(
00269             CollisionEventHandler* eventHandler )
00270         {
00271                 mCollisionEventHandlers.push_back( eventHandler );
00272         }
00273 
00274         CollisionEventHandler* Simulator::getGlobalCollisionEventHandler( unsigned int id ) const
00275         {
00276                 return mCollisionEventHandlers[ id ];
00277         }
00278 
00279         void Simulator::removeGlobalCollisionEventHandler(
00280             CollisionEventHandler * eventHandler )
00281         {
00282                 for ( size_t i = 0; i < mCollisionEventHandlers.size(); ++i )
00283                 {
00284                         if ( mCollisionEventHandlers[ i ] == eventHandler )
00285                         {
00286                                 mCollisionEventHandlers.erase( mCollisionEventHandlers.begin() + i );
00287                                 break;
00288                         }
00289                 }
00290         }
00291 
00292         size_t Simulator::getNumGlobalCollisionEventHandlers() const
00293         {
00294                 return mCollisionEventHandlers.size();
00295         }
00296 
00297         void Simulator::instantiateBlueprint(
00298             BlueprintInstance& instance, const Blueprint& bp,
00299             const Matrix44r& offset, real scale )
00300         {
00301                 assert( scale > 0 );
00302 
00303                 if ( !bp.isFinalized() )
00304                 {
00305                         OPAL_LOGGER( "warning" )
00306                         << "opal::Simulator::instantiateBlueprint: Cannot \
00307                         instantiate a Blueprint before it is finalized.  Ignoring \
00308                         the Blueprint." << std::endl;
00309                         return ;
00310                 }
00311 
00312                 bool useOffset = false;
00313                 if ( Matrix44r() != offset )
00314                 {
00315                         useOffset = true;
00316                 }
00317 
00318                 bool useScale = false;
00319                 //Matrix44r scaleMat;
00320                 if ( 1 != scale )
00321                 {
00322                         useScale = true;
00323                         //scaleMat.makeScale(scale);
00324                 }
00325 
00326                 // For each object created here, only the ones with names get added
00327                 // to the BlueprintInstance.
00328 
00329                 // Some of the objects depend on the presence of others, so
00330                 // they must be created in a specific order: Solids depend on
00331                 // nothing, Joints depend on Solids, Motors depend on Joints
00332                 // and Solids, and Sensors depend on Joints and Solids.
00333 
00334                 // For the objects with references to their dependencies (i.e.
00335                 // Joints, Motors, and Sensors), use the stored indices to
00336                 // find pointers in the appropriate array.
00337 
00338                 // Create these temporary arrays of pointers.  Other objects
00339                 // will use these to find pointers to their dependencies.
00340                 std::vector<Solid*> solidList;
00341                 std::vector<Joint*> jointList;
00342                 unsigned int i;
00343 
00344                 // Create all Solids in the Blueprint.
00345                 for ( i = 0; i < bp.getNumSolids(); ++i )
00346                 {
00347                         Solid* s = createSolid();
00348 
00349                         // Make a local copy of the Solid's data, including all of its
00350                         // Shapes.
00351                         SolidData sd = *bp.getSolidData( i );
00352 
00353                         if ( useScale )
00354                         {
00355                                 // Scale the Solid's transform.
00356                                 sd.transform[ 12 ] *= scale;
00357                                 sd.transform[ 13 ] *= scale;
00358                                 sd.transform[ 14 ] *= scale;
00359 
00360                                 // Scale the Solid's Shape's offsets and dimensions.
00361                                 unsigned int i = 0;
00362                                 for ( i = 0; i < sd.getNumShapes(); ++i )
00363                                 {
00364                                         ShapeData* shapeData = sd.getShapeData( i );
00365                                         shapeData->offset[ 12 ] *= scale;
00366                                         shapeData->offset[ 13 ] *= scale;
00367                                         shapeData->offset[ 14 ] *= scale;
00368 
00369                                         switch ( shapeData->getType() )
00370                                         {
00371                                                 case BOX_SHAPE:
00372                                                         {
00373                                                                 BoxShapeData * boxData =
00374                                                                     ( BoxShapeData* ) shapeData;
00375                                                                 boxData->dimensions =
00376                                                                     scale * boxData->dimensions;
00377                                                                 break;
00378                                                         }
00379                                                 case SPHERE_SHAPE:
00380                                                         {
00381                                                                 SphereShapeData* sphereData =
00382                                                                     ( SphereShapeData* ) shapeData;
00383                                                                 sphereData->radius =
00384                                                                     scale * sphereData->radius;
00385                                                                 break;
00386                                                         }
00387                                                 case CAPSULE_SHAPE:
00388                                                         {
00389                                                                 CapsuleShapeData* capsuleData =
00390                                                                     ( CapsuleShapeData* ) shapeData;
00391                                                                 capsuleData->radius =
00392                                                                     scale * capsuleData->radius;
00393                                                                 capsuleData->length =
00394                                                                     scale * capsuleData->length;
00395                                                                 break;
00396                                                         }
00397                                                 case PLANE_SHAPE:
00398                                                         {
00399                                                                 PlaneShapeData* planeData =
00400                                                                     ( PlaneShapeData* ) shapeData;
00401                                                                 planeData->abcd[ 3 ] =
00402                                                                     scale * planeData->abcd[ 3 ];
00403                                                                 break;
00404                                                         }
00405                                                         //case RAY_SHAPE:
00406                                                         //{
00407                                                         //  RayShapeData* rayData =
00408                                                         //      (RayShapeData*)shapeData;
00409                                                         //  Point3r origin = rayData->ray.getOrigin();
00410                                                         //  origin = scale * origin;
00411                                                         //  rayData->ray.setOrigin(origin);
00412                                                         //  break;
00413                                                         //}
00414                                                 case MESH_SHAPE:
00415                                                         {
00416                                                                 // Not implemented.  Scaling the Mesh data
00417                                                                 // should be handled elsewhere.
00418                                                                 break;
00419                                                         }
00420                                                 default:
00421                                                         assert( false );
00422                                         }
00423                                 }
00424                         }
00425 
00426                         if ( useOffset )
00427                         {
00428                                 // Offset the Solid's transform.
00429                                 sd.transform = offset * sd.transform;
00430                         }
00431 
00432                         s->init( sd );
00433                         solidList.push_back( s );
00434 
00435                         // Add the Solid to the BlueprintInstance.
00436                         instance.internal_addSolid( s );
00437                 }
00438 
00439                 // Create all Joints in the Blueprint.
00440                 for ( i = 0; i < bp.getNumJoints(); ++i )
00441                 {
00442                         Joint* j = createJoint();
00443 
00444                         // Create a local copy of the Joint's data.
00445                         JointData jd = *bp.getJointData( i );
00446 
00447                         // Setup the Solid reference pointers.  If one of the Solid 
00448                         // indices is -1, the Joint will attach that side to the 
00449                         // static environment automatically.
00450                         if (-1 == jd.internal_solid0Index)
00451                         {
00452                                 jd.solid0 = NULL;
00453                         }
00454                         else
00455                         {
00456                                 jd.solid0 = solidList.at( jd.internal_solid0Index );
00457                         }
00458 
00459                         if (-1 == jd.internal_solid1Index)
00460                         {
00461                                 jd.solid1 = NULL;
00462                         }
00463                         else
00464                         {
00465                                 jd.solid1 = solidList.at( jd.internal_solid1Index );
00466                         }
00467 
00468                         if ( useScale )
00469                         {
00470                                 // Scale the Joint's anchor.
00471                                 jd.anchor = scale * jd.anchor;
00472                         }
00473 
00474                         if ( useOffset )
00475                         {
00476                                 // Offset the Joint's anchor and axes.
00477                                 jd.anchor = offset * jd.anchor;
00478                                 jd.axis[ 0 ].direction = offset * jd.axis[ 0 ].direction;
00479                                 jd.axis[ 1 ].direction = offset * jd.axis[ 1 ].direction;
00480                                 jd.axis[ 2 ].direction = offset * jd.axis[ 2 ].direction;
00481                         }
00482 
00483                         j->init( jd );
00484                         jointList.push_back( j );
00485 
00486                         // Add the Joint to the BlueprintInstance.
00487                         instance.internal_addJoint( j );
00488                 }
00489 
00490                 // Create all Motors in the Blueprint.
00491                 for ( i = 0; i < bp.getNumMotors(); ++i )
00492                 {
00493                         Motor* m = NULL;
00494                         MotorData* motorData = bp.getMotorData( i );
00495 
00496                         // Allocate and setup the right type of Motor.
00497                         switch ( bp.getMotorData( i ) ->getType() )
00498                         {
00499                                 case ATTRACTOR_MOTOR:
00500                                         {
00501                                                 // Make a local copy of the Motor's data.
00502                                                 AttractorMotorData data = *( AttractorMotorData* ) motorData;
00503 
00504                                                 // Setup the Solid reference pointers.
00505                                                 data.solid0 = solidList.at( data.internal_solid0Index );
00506                                                 data.solid1 = solidList.at( data.internal_solid1Index );
00507 
00508                                                 m = createAttractorMotor();
00509                                                 ( ( AttractorMotor* ) m ) ->init( data );
00510                                                 break;
00511                                         }
00512                                 case GEARED_MOTOR:
00513                                         {
00514                                                 // Make a local copy of the Motor's data.
00515                                                 GearedMotorData data = *( GearedMotorData* ) motorData;
00516 
00517                                                 // Setup the Joint reference pointer.
00518                                                 data.joint = jointList.at( data.internal_jointIndex );
00519 
00520                                                 m = createGearedMotor();
00521                                                 ( ( GearedMotor* ) m ) ->init( data );
00522                                                 break;
00523                                         }
00524                                 case SERVO_MOTOR:
00525                                         {
00526                                                 // Make a local copy of the Motor's data.
00527                                                 ServoMotorData data = *( ServoMotorData* ) motorData;
00528 
00529                                                 // Setup the Joint reference pointer.
00530                                                 data.joint = jointList.at( data.internal_jointIndex );
00531 
00532                                                 m = createServoMotor();
00533                                                 ( ( ServoMotor* ) m ) ->init( data );
00534                                                 break;
00535                                         }
00536                                 case SPRING_MOTOR:
00537                                         {
00538                                                 // Make a local copy of the Motor's data.
00539                                                 SpringMotorData data = *( SpringMotorData* ) motorData;
00540 
00541                                                 // Setup the Solid reference pointer.
00542                                                 data.solid = solidList.at( data.internal_solidIndex );
00543 
00544                                                 m = createSpringMotor();
00545                                                 ( ( SpringMotor* ) m ) ->init( data );
00546                                                 break;
00547                                         }
00548                                 case THRUSTER_MOTOR:
00549                                         {
00550                                                 // Make a local copy of the Motor's data.
00551                                                 ThrusterMotorData data = *( ThrusterMotorData* ) motorData;
00552 
00553                                                 // Setup the Solid reference pointer.
00554                                                 data.solid = solidList.at( data.internal_solidIndex );
00555 
00556                                                 m = createThrusterMotor();
00557                                                 ( ( ThrusterMotor* ) m ) ->init( data );
00558                                                 break;
00559                                         }
00560                                 default:
00561                                         assert( false );
00562                         }
00563 
00564                         // Add the Motor to the BlueprintInstance.
00565                         instance.internal_addMotor( m );
00566                 }
00567 
00568                 // Create all Sensors in the Blueprint.
00569                 for ( i = 0; i < bp.getNumSensors(); ++i )
00570                 {
00571                         Sensor* s = NULL;
00572                         SensorData* sensorData = bp.getSensorData( i );
00573 
00574                         // These are necessary because we don't want to change teh
00575                         // Blueprint's Sensor data directly; we need a local copy.
00576                         Solid* solidPtr = NULL;
00577                         Matrix44r transform = sensorData->transform;
00578 
00579                         // Setup the Solid reference pointer.
00580                         if ( -1 == sensorData->internal_solidIndex )
00581                         {
00582                                 // This Sensor must not be attached to any Solid.
00583                                 solidPtr = NULL;
00584                         }
00585                         else
00586                         {
00587                                 // This Sensor is attached to a Solid.
00588                                 solidPtr = solidList.at( sensorData->internal_solidIndex );
00589                         }
00590 
00591                         if ( useScale )
00592                         {
00593                                 // Scale the Solid's transform.
00594                                 transform[ 12 ] *= scale;
00595                                 transform[ 13 ] *= scale;
00596                                 transform[ 14 ] *= scale;
00597                         }
00598 
00599                         if ( useOffset && !solidPtr )
00600                         {
00601                                 // If the Sensor is not attached to a Solid, offset the 
00602                                 // Sensor's transform.
00603                                 transform = offset * transform;
00604                         }
00605 
00606                         // Allocate the right type of Sensor.
00607                         switch ( sensorData->getType() )
00608                         {
00609                                 case ACCELERATION_SENSOR:
00610                                         {
00611                                                 // Make a local copy of the Sensor's data.
00612                                                 AccelerationSensorData data =
00613                                                     *( AccelerationSensorData* ) sensorData;
00614                                                 data.solid = solidPtr;
00615                                                 data.transform = transform;
00616 
00617                                                 s = createAccelerationSensor();
00618                                                 ( ( AccelerationSensor* ) s ) ->init( data );
00619                                                 break;
00620                                         }
00621                                 case INCLINE_SENSOR:
00622                                         {
00623                                                 // Make a local copy of the Sensor's data.
00624                                                 InclineSensorData data = *( InclineSensorData* ) sensorData;
00625                                                 data.solid = solidPtr;
00626                                                 data.transform = transform;
00627 
00628                                                 s = createInclineSensor();
00629                                                 ( ( InclineSensor* ) s ) ->init( data );
00630                                                 break;
00631                                         }
00632                                 case RAYCAST_SENSOR:
00633                                         {
00634                                                 // Make a local copy of the Sensor's data.
00635                                                 RaycastSensorData data = *( RaycastSensorData* ) sensorData;
00636                                                 data.solid = solidPtr;
00637                                                 data.transform = transform;
00638 
00639                                                 s = createRaycastSensor();
00640                                                 ( ( RaycastSensor* ) s ) ->init( data );
00641                                                 break;
00642                                         }
00643                                 case VOLUME_SENSOR:
00644                                         {
00645                                                 // Make a local copy of the Sensor's data.
00646                                                 VolumeSensorData data = *( VolumeSensorData* ) sensorData;
00647                                                 data.solid = solidPtr;
00648                                                 data.transform = transform;
00649 
00650                                                 s = createVolumeSensor();
00651                                                 ( ( VolumeSensor* ) s ) ->init( data );
00652                                                 break;
00653                                         }
00654                                 default:
00655                                         assert( false );
00656                         }
00657 
00658                         // Add the Sensor to the BlueprintInstance.
00659                         instance.internal_addSensor( s );
00660                 }
00661 
00662                 solidList.clear();
00663                 jointList.clear();
00664         }
00665 
00666         //void Simulator::setMaxLinearVel(real max)
00667         //{
00668         //  assert(max >= 0.0);
00669         //  mMaxLinearVel = max;
00670         //}
00671 
00672         //real Simulator::getMaxLinearVel()const
00673         //{
00674         //  return mMaxLinearVel;
00675         //}
00676 
00677         //void Simulator::setMaxAngularVel(real max)
00678         //{
00679         //  assert(max >= 0.0);
00680         //  mMaxAngularVel = max;
00681         //}
00682 
00683         //real Simulator::getMaxAngularVel()const
00684         //{
00685         //  return mMaxAngularVel;
00686         //}
00687 
00688         //void Simulator::setDefaultLinearDamping(real ld)
00689         //{
00690         //  assert(ld >= 0.0);
00691         //  mDefaultLinearDamping = ld;
00692         //}
00693 
00694         //real Simulator::getDefaultLinearDamping()const
00695         //{
00696         //  return mDefaultLinearDamping;
00697         //}
00698 
00699         //void Simulator::setDefaultAngularDamping(real ad)
00700         //{
00701         //  assert(ad >= 0.0);
00702         //  mDefaultAngularDamping = ad;
00703         //}
00704 
00705         //real Simulator::getDefaultAngularDamping()const
00706         //{
00707         //  return mDefaultAngularDamping;
00708         //}
00709 
00710         void Simulator::setUserData( void* data )
00711         {
00712                 mUserData = data;
00713         }
00714 
00715         void* Simulator::getUserData()
00716         {
00717                 return mUserData;
00718         }
00719 
00720         void Simulator::setupContactGroups( unsigned int group0,
00721                                             unsigned int group1, bool makeContacts )
00722         {
00723                 if ( group0 > 31 )
00724                 {
00725                         OPAL_LOGGER( "warning" ) << "opal::Simulator::setupContactGroups: "
00726                         << "Invalid contact group " << group0
00727                         << ". Request will be ignored." << std::endl;
00728                         return ;
00729                 }
00730 
00731                 if ( group1 > 31 )
00732                 {
00733                         OPAL_LOGGER( "warning" ) << "opal::Simulator::setupContactGroups: "
00734                         << "Invalid contact group " << group1
00735                         << ". Request will be ignored." << std::endl;
00736                         return ;
00737                 }
00738 
00739                 // The interaction always goes both ways, so we need to set the bit
00740                 // flags both ways.
00741 
00742                 unsigned long int group0Bit = 1 << group0;
00743                 unsigned long int group1Bit = 1 << group1;
00744 
00745                 if ( makeContacts )
00746                 {
00747                         // Raise the group1 bit in group0's array.
00748                         mContactGroupFlags[ group0 ] |= group1Bit;
00749 
00750                         // Raise the group0 bit in group1's array.
00751                         mContactGroupFlags[ group1 ] |= group0Bit;
00752                 }
00753                 else
00754                 {
00755                         unsigned long int tempMask = 0xFFFFFFFF;
00756                         unsigned long int notGroup0Bit = group0Bit ^ tempMask;
00757                         unsigned long int notGroup1Bit = group1Bit ^ tempMask;
00758 
00759                         // Lower the group1 bit in group0's array.
00760                         mContactGroupFlags[ group0 ] &= notGroup1Bit;
00761 
00762                         // Lower the group0 bit in group1's array.
00763                         mContactGroupFlags[ group1 ] &= notGroup0Bit;
00764                 }
00765         }
00766 
00767         void Simulator::setupContactGroup( unsigned int group,
00768                                            bool makeContacts )
00769         {
00770                 int i = 0;
00771                 for ( i = 0; i < 32; ++i )
00772                 {
00773                         setupContactGroups( group, i, makeContacts );
00774                 }
00775         }
00776 
00777         bool Simulator::groupsMakeContacts( unsigned int group0,
00778                                             unsigned int group1 )
00779         {
00780                 // We only need to check for "one side" of the contact groups
00781                 // here because the groups are always setup both ways (i.e.
00782                 // the interaction between object 0's contact group and
00783                 // object 1's contact group is always symmetric).
00784 
00785                 unsigned long int group1Bit = 1 << group1;
00786                 if ( internal_getContactGroupFlags( group0 ) & group1Bit )
00787                 {
00788                         return true;
00789                 }
00790                 else
00791                 {
00792                         return false;
00793                 }
00794         }
00795 
00796         void Simulator::setStaticSleepingContactsEnabled( bool enable )
00797         {
00798                 mStaticSleepingContactsEnabled = enable;
00799         }
00800 
00801         bool Simulator::areStaticSleepingContactsEnabled()
00802         {
00803                 return mStaticSleepingContactsEnabled;
00804         }
00805 
00806         unsigned long int Simulator::internal_getContactGroupFlags(
00807             unsigned int groupNum ) const
00808         {
00809                 return mContactGroupFlags[ groupNum ];
00810         }
00811 
00812         Solid* Simulator::createPlane( real a, real b, real c, real d,
00813                                        const Material& m )
00814         {
00815                 // Create the plane's Solid and make it static.
00816                 Solid * plane = createSolid();
00817                 plane->setStatic( true );
00818 
00819                 // Setup the plane's Shape data.
00820                 opal::PlaneShapeData planeData;
00821                 planeData.material = m;
00822                 planeData.abcd[ 0 ] = a;
00823                 planeData.abcd[ 1 ] = b;
00824                 planeData.abcd[ 2 ] = c;
00825                 planeData.abcd[ 3 ] = d;
00826 
00827                 // Add the Shape to the Solid.
00828                 plane->addShape( planeData );
00829 
00830                 return plane;
00831         }
00832 
00833         unsigned int Simulator::getNumSolids() const
00834         {
00835                 return ( unsigned int ) ( mSolidList.size() );
00836         }
00837 
00838         Solid* Simulator::getSolid( unsigned int i ) const
00839         {
00840                 return mSolidList.at( i );
00841         }
00842 
00843         void Simulator::destroySolid( Solid* s )
00844         {
00845                 if ( mIsSolidDestructionSafe )
00846                 {
00847                         removeSolid( s );
00848                 }
00849                 else
00850                 {
00851                         mSolidGarbageList.push_back( s );
00852                 }
00853         }
00854 
00855         void Simulator::destroyAllSolids()
00856         {
00857                 for ( size_t i = 0; i < mSolidList.size(); ++i )
00858                 {
00859                         removeSolid( mSolidList[ i ] );
00860                 }
00861         }
00862 
00863         void Simulator::destroyJoint( Joint* j )
00864         {
00865                 if ( mIsJointDestructionSafe )
00866                 {
00867                         removeJoint( j );
00868                 }
00869                 else
00870                 {
00871                         mJointGarbageList.push_back( j );
00872                 }
00873         }
00874 
00875         void Simulator::destroyAllJoints()
00876         {
00877                 for ( size_t i = 0; i < mJointList.size(); ++i )
00878                 {
00879                         removeJoint( mJointList[ i ] );
00880                 }
00881         }
00882 
00883         ThrusterMotor* Simulator::createThrusterMotor()
00884         {
00885                 ThrusterMotor * newMotor = new ThrusterMotor();
00886                 addMotor( newMotor );
00887                 return newMotor;
00888         }
00889 
00890         VelocityMotor* Simulator::createVelocityMotor()
00891         {
00892                 VelocityMotor * newMotor = new VelocityMotor( this );
00893                 addMotor( newMotor );
00894                 return newMotor;
00895         }
00896 
00897         GearedMotor* Simulator::createGearedMotor()
00898         {
00899                 GearedMotor * newMotor = new GearedMotor();
00900                 addMotor( newMotor );
00901                 return newMotor;
00902         }
00903 
00904         ServoMotor* Simulator::createServoMotor()
00905         {
00906                 ServoMotor * newMotor = new ServoMotor();
00907                 addMotor( newMotor );
00908                 return newMotor;
00909         }
00910 
00911         AttractorMotor* Simulator::createAttractorMotor()
00912         {
00913                 AttractorMotor * newMotor = new AttractorMotor();
00914                 addMotor( ( Motor* ) newMotor );
00915                 return newMotor;
00916         }
00917 
00918         SpringMotor* Simulator::createSpringMotor()
00919         {
00920                 SpringMotor * newMotor = new SpringMotor();
00921                 addMotor( ( Motor* ) newMotor );
00922                 return newMotor;
00923         }
00924 
00925         //void Simulator::registerCustomMotor(Motor* m)
00926         //{
00927         //  m->internal_setCustom(true);
00928         //  addMotor(m);
00929         //}
00930 
00931         void Simulator::destroyMotor( Motor* m )
00932         {
00933                 removeMotor( m );
00934         }
00935 
00936         void Simulator::destroyAllMotors()
00937         {
00938                 for ( size_t i = 0; i < mMotorList.size(); ++i )
00939                 {
00940                         removeMotor( mMotorList[ i ] );
00941                 }
00942         }
00943 
00944         AccelerationSensor* Simulator::createAccelerationSensor()
00945         {
00946                 AccelerationSensor * newSensor = new AccelerationSensor( this );
00947                 addSensor( newSensor );
00948                 return newSensor;
00949         }
00950 
00951         InclineSensor* Simulator::createInclineSensor()
00952         {
00953                 InclineSensor * newSensor = new InclineSensor();
00954                 addSensor( newSensor );
00955                 return newSensor;
00956         }
00957 
00958         RaycastSensor* Simulator::createRaycastSensor()
00959         {
00960                 RaycastSensor * newSensor = new RaycastSensor( this );
00961                 addSensor( newSensor );
00962                 return newSensor;
00963         }
00964 
00965         VolumeSensor* Simulator::createVolumeSensor()
00966         {
00967                 VolumeSensor * newSensor = new VolumeSensor( this );
00968                 addSensor( newSensor );
00969                 return newSensor;
00970         }
00971 
00972         void Simulator::destroySensor( Sensor* s )
00973         {
00974                 removeSensor( s );
00975         }
00976 
00977         void Simulator::destroyAllSensors()
00978         {
00979                 for ( size_t i = 0; i < mSensorList.size(); ++i )
00980                 {
00981                         removeSensor( mSensorList[ i ] );
00982                 }
00983         }
00984 
00985         void Simulator::setSolverAccuracy( SolverAccuracyLevel level )
00986         {
00987                 mSolverAccuracyLevel = level;
00988         }
00989 
00990         SolverAccuracyLevel Simulator::getSolverAccuracy() const
00991         {
00992                 return mSolverAccuracyLevel;
00993         }
00994 
00995         void Simulator::setMaxCorrectingVel( real vel )
00996         {
00997                 assert( vel > 0 );
00998                 mMaxCorrectingVel = vel;
00999         }
01000 
01001         real Simulator::getMaxCorrectingVel() const
01002         {
01003                 return mMaxCorrectingVel;
01004         }
01005 
01006         void Simulator::setMaxContacts( unsigned int mc )
01007         {
01008                 assert( mc <= globals::maxMaxContacts );
01009                 mMaxContacts = mc;
01010         }
01011 
01012         unsigned int Simulator::getMaxContacts() const
01013         {
01014                 return mMaxContacts;
01015         }
01016 
01017         void Simulator::addSolid( Solid* s )
01018         {
01019                 mSolidList.push_back( s );
01020         }
01021 
01022         void Simulator::removeSolid( Solid* s )
01023         {
01024                 // TODO: make this more efficient by not iterating through all Motors,
01025                 // Sensors, and Joints; maybe have the Solid maintain pointers to
01026                 // things that depend on it.
01027 
01028                 // Disable Motors that depend on the given Solid.
01029                 std::vector<Motor*>::iterator iter;
01030                 for ( iter = mMotorList.begin(); iter != mMotorList.end(); ++iter )
01031                 {
01032                         if ( ( *iter ) ->internal_dependsOnSolid( s ) )
01033                         {
01034                                 ( *iter ) ->setEnabled( false );
01035                         }
01036                 }
01037 
01038                 // Disable Joints that depend on the given Solid.
01039                 std::vector<Joint*>::iterator iter2;
01040                 for ( iter2 = mJointList.begin(); iter2 != mJointList.end(); ++iter2 )
01041                 {
01042                         if ( ( *iter2 ) ->internal_dependsOnSolid( s ) )
01043                         {
01044                                 ( *iter2 ) ->setEnabled( false );
01045                         }
01046                 }
01047 
01048                 // Disable Sensors that depend on the given Solid.
01049                 std::vector<Sensor*>::iterator iter3;
01050                 for ( iter3 = mSensorList.begin(); iter3 != mSensorList.end(); ++iter3 )
01051                 {
01052                         if ( ( *iter3 ) ->internal_dependsOnSolid( s ) )
01053                         {
01054                                 ( *iter3 ) ->setEnabled( false );
01055                         }
01056                 }
01057 
01058                 // Now remove the Solid.
01059                 for ( size_t i = 0; i < mSolidList.size(); ++i )
01060                 {
01061                         if ( mSolidList[ i ] == s )
01062                         {
01063                                 s->internal_destroy();
01064                                 mSolidList[ i ] = mSolidList.back();
01065                                 mSolidList.pop_back();
01066 
01067                                 return ;
01068                         }
01069                 }
01070         }
01071 
01072         void Simulator::addJoint( Joint* j )
01073         {
01074                 mJointList.push_back( j );
01075         }
01076 
01077         void Simulator::removeJoint( Joint* j )
01078         {
01079                 // TODO: make this more efficient by not iterating through all Motors;
01080                 // maybe have the Solid maintain pointers to things that
01081                 // depend on it.
01082 
01083                 // Disable Motors that depend on the given Joint.
01084                 std::vector<Motor*>::iterator iter;
01085                 for ( iter = mMotorList.begin(); iter != mMotorList.end(); ++iter )
01086                 {
01087                         if ( ( *iter ) ->internal_dependsOnJoint( j ) )
01088                         {
01089                                 ( *iter ) ->setEnabled( false );
01090                         }
01091                 }
01092 
01093                 // Now remove the Joint.
01094                 for ( size_t i = 0; i < mJointList.size(); ++i )
01095                 {
01096                         if ( mJointList[ i ] == j )
01097                         {
01098                                 j->internal_destroy();
01099                                 mJointList[ i ] = mJointList.back();
01100                                 mJointList.pop_back();
01101 
01102                                 return ;
01103                         }
01104                 }
01105         }
01106 
01107         void Simulator::addMotor( Motor* m )
01108         {
01109                 mMotorList.push_back( m );
01110         }
01111 
01112         void Simulator::removeMotor( Motor* m )
01113         {
01114                 for ( size_t i = 0; i < mMotorList.size(); ++i )
01115                 {
01116                         if ( mMotorList[ i ] == m )
01117                         {
01118                                 //if (!m->internal_isCustom())
01119                                 //{
01120                                 //  delete m;
01121                                 //}
01122                                 m->internal_destroy();
01123                                 mMotorList[ i ] = mMotorList.back();
01124                                 mMotorList.pop_back();
01125 
01126                                 return ;
01127                         }
01128                 }
01129         }
01130 
01131         void Simulator::addSensor( Sensor* s )
01132         {
01133                 mSensorList.push_back( s );
01134         }
01135 
01136         void Simulator::removeSensor( Sensor* s )
01137         {
01138                 for ( size_t i = 0; i < mSensorList.size(); ++i )
01139                 {
01140                         if ( mSensorList[ i ] == s )
01141                         {
01142                                 s->internal_destroy();
01143                                 mSensorList[ i ] = mSensorList.back();
01144                                 mSensorList.pop_back();
01145 
01146                                 return ;
01147                         }
01148                 }
01149         }
01150 
01151         void Simulator::addSpace( Space* s )
01152         {
01153                 mSpaceList.push_back( s );
01154         }
01155 
01156         Space* Simulator::getRootSpace()
01157         {
01158                 return mRootSpace;
01159         }
01160 
01161         void Simulator::destroyGarbage()
01162         {
01163                 // Destroy garbage Solids.
01164                 while ( !mSolidGarbageList.empty() )
01165                 {
01166                         destroySolid( mSolidGarbageList.back() );
01167                         mSolidGarbageList.pop_back();
01168                 }
01169 
01170                 // Destroy garbage Joints.
01171                 while ( !mJointGarbageList.empty() )
01172                 {
01173                         destroyJoint( mJointGarbageList.back() );
01174                         mJointGarbageList.pop_back();
01175                 }
01176         }
01177 }

Generated on Tue May 16 17:49:52 2006 for OPAL by  doxygen 1.4.6-NO