Joint.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 #include "Joint.h"
00029 #include "Solid.h"
00030 
00031 namespace opal
00032 {
00033     Joint::Joint()
00034     {
00035         // "mData" is initialized in its own constructor.
00036         setJointBreakEventHandler( NULL );
00037         setUserData( NULL );
00038         mInitCalled = false;
00039         mNumAxes = 0;
00040         mAxisRotational[ 0 ] = false;
00041         mAxisRotational[ 1 ] = false;
00042         mAxisRotational[ 2 ] = false;
00043     }
00044 
00045     Joint::~Joint()
00046     {}
00047 
00048     void Joint::internal_destroy()
00049     {
00050         delete this;
00051     }
00052 
00053     void Joint::init( const JointData& data )
00054     {
00055         mData = data;
00056     }
00057 
00058     const JointData& Joint::getData()
00059     {
00060         // Update parameters that don't get updated automatically.
00061         for ( int i = 0; i < mNumAxes; ++i )
00062         {
00063             mData.axis[ i ] = getAxis( i );
00064         }
00065 
00066         mData.anchor = getAnchor();
00067 
00068         return mData;
00069     }
00070 
00071     void Joint::setName( const std::string& name )
00072     {
00073         mData.name = name;
00074     }
00075 
00076     const std::string& Joint::getName() const
00077     {
00078         return mData.name;
00079     }
00080 
00081     void Joint::setContactsEnabled( bool e )
00082     {
00083         mData.contactsEnabled = e;
00084     }
00085 
00086     bool Joint::areContactsEnabled() const
00087     {
00088         return mData.contactsEnabled;
00089     }
00090 
00091     JointType Joint::getType() const
00092     {
00093         return mData.getType();
00094     }
00095 
00096     void Joint::setBreakParams( JointBreakMode mode, real breakThresh,
00097                                 real accumThresh )
00098     {
00099         mData.breakMode = mode;
00100         mData.breakThresh = breakThresh;
00101         mData.accumThresh = accumThresh;
00102     }
00103 
00104     bool Joint::isBroken() const
00105     {
00106         return mData.isBroken;
00107     }
00108 
00109     JointBreakMode Joint::getBreakingMode() const
00110     {
00111         return mData.breakMode;
00112     }
00113 
00114     real Joint::getBreakThresh() const
00115     {
00116         return mData.breakThresh;
00117     }
00118 
00119     real Joint::getAccumulatedDamage() const
00120     {
00121         return mData.accumDamage;
00122     }
00123 
00124     real Joint::getAccumulatedThresh() const
00125     {
00126         return mData.accumThresh;
00127     }
00128 
00129     void Joint::repairAccumDamage()
00130     {
00131         mData.accumDamage = 0;
00132         //mIsBroken = false;
00133     }
00134 
00135     //bool Joint::internal_isBroken()
00136     //{
00137     //  return mIsBroken;
00138     //}
00139 
00140     void Joint::setJointBreakEventHandler(
00141         JointBreakEventHandler* eventHandler )
00142     {
00143         mJointBreakEventHandler = eventHandler;
00144     }
00145 
00146     JointBreakEventHandler* Joint::getJointBreakEventHandler() const
00147     {
00148         return mJointBreakEventHandler;
00149     }
00150 
00151     void Joint::setLimitsEnabled( int axisNum, bool e )
00152     {
00153         assert( axisNum >= 0 && axisNum < mNumAxes );
00154         mData.axis[ axisNum ].limitsEnabled = e;
00155     }
00156 
00157     bool Joint::areLimitsEnabled( int axisNum )
00158     {
00159         assert( axisNum >= 0 && axisNum < mNumAxes );
00160         return mData.axis[ axisNum ].limitsEnabled;
00161     }
00162 
00163     //void Joint::setLimits(int axisNum, JointLimits l)
00164     //{
00165     //  assert(axisNum >= 0 && axisNum < mNumAxes);
00166     //  assert(l.bounciness >= 0 && l.bounciness <= 1);
00167     //  assert(l.hardness >= 0 && l.hardness <= 1);
00168     //  mData.axis[axisNum].limits = l;
00169     //}
00170 
00171     //const Joint::JointLimits& getLimits(int axisNum)const
00172     //{
00173     //  assert(axisNum >= 0 && axisNum < mNumAxes);
00174     //  return mData.axis[axisNum].limits;
00175     //}
00176 
00177     void Joint::setLimitRange( int axisNum, real low, real high )
00178     {
00179         assert( high >= low );
00180         assert( axisNum >= 0 && axisNum < mNumAxes );
00181         mData.axis[ axisNum ].limits.low = low;
00182         mData.axis[ axisNum ].limits.high = high;
00183     }
00184 
00185     real Joint::getLowLimit( int axisNum ) const
00186     {
00187         assert( axisNum >= 0 && axisNum < mNumAxes );
00188         return mData.axis[ axisNum ].limits.low;
00189     }
00190 
00191     real Joint::getHighLimit( int axisNum ) const
00192     {
00193         assert( axisNum >= 0 && axisNum < mNumAxes );
00194         return mData.axis[ axisNum ].limits.high;
00195     }
00196 
00197     void Joint::setLimitHardness( int axisNum, real h )
00198     {
00199         assert( h >= 0 && h <= 1 );
00200         assert( axisNum >= 0 && axisNum < mNumAxes );
00201         mData.axis[ axisNum ].limits.hardness = h;
00202     }
00203 
00204     real Joint::getLimitHardness( int axisNum ) const
00205     {
00206         assert( axisNum >= 0 && axisNum < mNumAxes );
00207         return mData.axis[ axisNum ].limits.hardness;
00208     }
00209 
00210     void Joint::setLimitBounciness( int axisNum, real b )
00211     {
00212         assert( b >= 0 && b <= 1 );
00213         assert( axisNum >= 0 && axisNum < mNumAxes );
00214         mData.axis[ axisNum ].limits.bounciness = b;
00215     }
00216 
00217     real Joint::getLimitBounciness( int axisNum ) const
00218     {
00219         assert( axisNum >= 0 && axisNum < mNumAxes );
00220         return mData.axis[ axisNum ].limits.bounciness;
00221     }
00222 
00223     void Joint::addForce( int axisNum, real magnitude, real duration,
00224                           bool singleStep )
00225     {
00226         assert( axisNum >= 0 && axisNum < mNumAxes );
00227 
00228         if ( mData.enabled )
00229         {
00230             Force f;
00231             f.singleStep = singleStep;
00232 
00233             // We only care about the duration if this is not a single-step
00234             // force.
00235             if ( !f.singleStep )
00236             {
00237                 f.duration = duration;
00238             }
00239 
00240             f.type = LOCAL_FORCE;
00241             Vec3r direction = mData.axis[ axisNum ].direction;
00242             f.vec = magnitude * direction;
00243 
00244             if ( mData.solid0 )
00245             {
00246                 mData.solid0->addForce( f );
00247             }
00248 
00249             f.vec *= ( real ) - 1.0;
00250 
00251             if ( mData.solid1 )
00252             {
00253                 mData.solid1->addForce( f );
00254             }
00255         }
00256     }
00257 
00258     void Joint::addTorque( int axisNum, real magnitude, real duration,
00259                            bool singleStep )
00260     {
00261         assert( axisNum >= 0 && axisNum < mNumAxes );
00262 
00263         if ( mData.enabled )
00264         {
00265             Force f;
00266             f.singleStep = singleStep;
00267 
00268             // We only care about the duration if this is not a single-step
00269             // force.
00270             if ( !f.singleStep )
00271             {
00272                 f.duration = duration;
00273             }
00274 
00275             f.type = LOCAL_TORQUE;
00276             Vec3r axis = mData.axis[ axisNum ].direction;
00277             f.vec = magnitude * axis;
00278 
00279             if ( mData.solid0 )
00280             {
00281                 mData.solid0->addForce( f );
00282             }
00283 
00284             f.vec *= ( real ) - 1.0;
00285 
00286             if ( mData.solid1 )
00287             {
00288                 mData.solid1->addForce( f );
00289             }
00290         }
00291     }
00292 
00293     void Joint::wakeSolids()
00294     {
00295         if ( mData.solid0 )
00296             mData.solid0->setSleeping( false );
00297         if ( mData.solid1 )
00298             mData.solid1->setSleeping( false );
00299     }
00300 
00301     void Joint::setSolids( Solid* s0, Solid* s1 )
00302     {
00303         mData.solid0 = s0;
00304         mData.solid1 = s1;
00305     }
00306 
00307     Solid* Joint::getSolid0() const
00308     {
00309         return mData.solid0;
00310     }
00311 
00312     Solid* Joint::getSolid1() const
00313     {
00314         return mData.solid1;
00315     }
00316 
00317     void Joint::setAxis( int axisNum, const JointAxis& axis )
00318     {
00319         assert( axisNum >= 0 && axisNum < mNumAxes );
00320         mData.axis[ axisNum ] = axis;
00321     }
00322 
00323     int Joint::getNumAxes() const
00324     {
00325         return mNumAxes;
00326     }
00327 
00328     void Joint::setAnchor( const Point3r& anchor )
00329     {
00330         mData.anchor = anchor;
00331     }
00332 
00333     bool Joint::isEnabled() const
00334     {
00335         return mData.enabled;
00336     }
00337 
00338     void Joint::setEnabled( bool e )
00339     {
00340         if ( !mInitCalled )
00341         {
00342             return ;
00343         }
00344 
00345         mData.enabled = e;
00346     }
00347 
00348     bool Joint::isRotational( int axisNum ) const
00349     {
00350         assert( axisNum >= 0 && axisNum < mNumAxes );
00351         return mAxisRotational[ axisNum ];
00352     }
00353 
00354     void Joint::setUserData( void* data )
00355     {
00356         mUserData = data;
00357     }
00358 
00359     void* Joint::getUserData()
00360     {
00361         return mUserData;
00362     }
00363 
00364     bool Joint::internal_dependsOnSolid( Solid* s )
00365     {
00366         if ( s == mData.solid0 || s == mData.solid1 )
00367         {
00368             return true;
00369         }
00370         else
00371         {
00372             return false;
00373         }
00374     }
00375 
00376     void Joint::updateDamage( real currentStress )
00377     {
00378         switch ( mData.breakMode )
00379         {
00380             case UNBREAKABLE_MODE:
00381             //nothing to do
00382             break;
00383             case THRESHOLD_MODE:
00384             {
00385                 if ( currentStress >= mData.breakThresh )
00386                 {
00387                     mData.isBroken = true;
00388                 }
00389                 break;
00390             }
00391             case ACCUMULATED_MODE:
00392             {
00393                 if ( currentStress >= mData.accumThresh )
00394                 {
00395                     mData.accumDamage += currentStress;
00396                 }
00397 
00398                 if ( mData.accumDamage >= mData.breakThresh )
00399                 {
00400                     mData.isBroken = true;
00401                 }
00402                 break;
00403             }
00404             default:
00405             assert( false );
00406         }
00407 
00408         if ( mData.isBroken )
00409         {
00410             setEnabled( false );
00411             if ( mJointBreakEventHandler )
00412             {
00413                 mJointBreakEventHandler->handleJointBreakEvent( this );
00414             }
00415         }
00416     }
00417 }

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