00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "ODEJoint.h"
00029
00030
00031 namespace opal
00032 {
00033 ODEJoint::ODEJoint( dWorldID worldID )
00034 {
00035 mJointID = NULL;
00036 mAMotorID = NULL;
00037 mWorldID = worldID;
00038 }
00039
00040 ODEJoint::~ODEJoint()
00041 {
00042 dJointDestroy( mJointID );
00043 if ( mAMotorID )
00044 {
00045 dJointDestroy( mAMotorID );
00046 }
00047 }
00048
00049 void ODEJoint::init( const JointData& data )
00050 {
00051 if ( mInitCalled )
00052 {
00053
00054
00055 dJointDestroy( mJointID );
00056 if ( mAMotorID )
00057 {
00058 dJointDestroy( mAMotorID );
00059 }
00060
00061
00062 mJointBreakEventHandler = NULL;
00063 }
00064
00065 Joint::init( data );
00066 mInitCalled = true;
00067
00068 switch ( data.getType() )
00069 {
00070 case HINGE_JOINT:
00071
00072 mJointID = dJointCreateHinge( mWorldID, 0 );
00073 mNumAxes = 1;
00074
00075
00076 mAxisRotational[ 0 ] = true;
00077 mAxisRotational[ 1 ] = false;
00078 mAxisRotational[ 2 ] = false;
00079
00080
00081 setJointParam( dParamFudgeFactor,
00082 defaults::ode::jointFudgeFactor );
00083 break;
00084 case UNIVERSAL_JOINT:
00085
00086 mJointID = dJointCreateUniversal( mWorldID, 0 );
00087 mNumAxes = 2;
00088
00089
00090 mAxisRotational[ 0 ] = true;
00091 mAxisRotational[ 1 ] = true;
00092 mAxisRotational[ 2 ] = false;
00093
00094
00095 setJointParam( dParamFudgeFactor,
00096 defaults::ode::jointFudgeFactor );
00097 setJointParam( dParamFudgeFactor2,
00098 defaults::ode::jointFudgeFactor );
00099 break;
00100 case BALL_JOINT:
00101
00102 mJointID = dJointCreateBall( mWorldID, 0 );
00103 mNumAxes = 3;
00104
00105
00106 mAxisRotational[ 0 ] = true;
00107 mAxisRotational[ 1 ] = true;
00108 mAxisRotational[ 2 ] = true;
00109
00110
00111
00112 mAMotorID = dJointCreateAMotor( mWorldID, 0 );
00113 dJointSetAMotorMode( mAMotorID, dAMotorEuler );
00114
00115
00116 setJointParam( dParamFudgeFactor,
00117 defaults::ode::jointFudgeFactor );
00118 setJointParam( dParamFudgeFactor2,
00119 defaults::ode::jointFudgeFactor );
00120 setJointParam( dParamFudgeFactor3,
00121 defaults::ode::jointFudgeFactor );
00122 break;
00123 case SLIDER_JOINT:
00124
00125 mJointID = dJointCreateSlider( mWorldID, 0 );
00126 mNumAxes = 1;
00127
00128
00129 mAxisRotational[ 0 ] = false;
00130 mAxisRotational[ 1 ] = false;
00131 mAxisRotational[ 2 ] = false;
00132
00133
00134 setJointParam( dParamFudgeFactor,
00135 defaults::ode::jointFudgeFactor );
00136 break;
00137 case WHEEL_JOINT:
00138
00139 mJointID = dJointCreateHinge2( mWorldID, 0 );
00140 mNumAxes = 2;
00141
00142
00143 mAxisRotational[ 0 ] = true;
00144 mAxisRotational[ 1 ] = true;
00145 mAxisRotational[ 2 ] = false;
00146
00147
00148 setJointParam( dParamFudgeFactor,
00149 defaults::ode::jointFudgeFactor );
00150 setJointParam( dParamFudgeFactor2,
00151 defaults::ode::jointFudgeFactor );
00152 break;
00153 case FIXED_JOINT:
00154
00155 mJointID = dJointCreateFixed( mWorldID, 0 );
00156 mNumAxes = 0;
00157
00158
00159 mAxisRotational[ 0 ] = false;
00160 mAxisRotational[ 1 ] = false;
00161 mAxisRotational[ 2 ] = false;
00162 break;
00163 default:
00164 assert( false );
00165 break;
00166 }
00167
00168
00169
00170
00171 mJointFeedback.f1[ 0 ] = 0;
00172 mJointFeedback.f1[ 1 ] = 0;
00173 mJointFeedback.f1[ 2 ] = 0;
00174 mJointFeedback.t1[ 0 ] = 0;
00175 mJointFeedback.t1[ 1 ] = 0;
00176 mJointFeedback.t1[ 2 ] = 0;
00177 mJointFeedback.f2[ 0 ] = 0;
00178 mJointFeedback.f2[ 1 ] = 0;
00179 mJointFeedback.f2[ 2 ] = 0;
00180 mJointFeedback.t2[ 0 ] = 0;
00181 mJointFeedback.t2[ 1 ] = 0;
00182 mJointFeedback.t2[ 2 ] = 0;
00183 dJointSetFeedback( mJointID, &mJointFeedback );
00184
00185
00186 filterSolidForStaticness( data.solid0, data.solid1 );
00187
00188 if ( !mData.isBroken )
00189 {
00190
00191 attachODEBodies( mData.solid0, mData.solid1 );
00192 }
00193
00194
00195 setAnchor( data.anchor );
00196
00197
00198 setAxis( 0, data.axis[ 0 ] );
00199 setAxis( 1, data.axis[ 1 ] );
00200 setAxis( 2, data.axis[ 2 ] );
00201
00202
00203 if ( BALL_JOINT == mData.getType() )
00204 {
00205 dJointSetData( mAMotorID, this );
00206 }
00207 else
00208 {
00209 dJointSetData( mJointID, this );
00210 }
00211 }
00212
00213 void ODEJoint::filterSolidForStaticness( Solid* s0, Solid* s1 )
00214 {
00215 Solid * temp0 = s0;
00216 Solid * temp1 = s1;
00217 mData.enabled = true;
00218 if ( s0 == s1 )
00219 {
00220 temp0 = NULL;
00221 temp1 = NULL;
00222 mData.enabled = false;
00223 }
00224 else
00225 {
00226 if ( s0 && s0->isStatic() )
00227 temp0 = NULL;
00228 if ( s1 && s1->isStatic() )
00229 temp1 = NULL;
00230
00231 if ( temp0 == NULL && temp1 == NULL )
00232 mData.enabled = false;
00233 }
00234
00235
00236 Joint::setSolids( temp0, temp1 );
00237 }
00238
00239 real ODEJoint::getAngle( int axisNum ) const
00240 {
00241 assert( axisNum >= 0 && axisNum < mNumAxes );
00242
00243 real value = 0;
00244
00245 switch ( mData.getType() )
00246 {
00247 case HINGE_JOINT:
00248 value = radToDeg( ( real ) dJointGetHingeAngle( mJointID ) );
00249 break;
00250 case UNIVERSAL_JOINT:
00251 if ( 0 == axisNum )
00252 {
00253 value =
00254 radToDeg( ( real ) dJointGetUniversalAngle1( mJointID ) );
00255 }
00256 else
00257 {
00258 value =
00259 radToDeg( ( real ) dJointGetUniversalAngle2( mJointID ) );
00260 }
00261 break;
00262 case BALL_JOINT:
00263 value =
00264 radToDeg( ( real ) dJointGetAMotorAngle( mAMotorID, axisNum ) );
00265 break;
00266 case SLIDER_JOINT:
00267 value = 0;
00268 break;
00269 case WHEEL_JOINT:
00270 if ( 0 == axisNum )
00271 {
00272 value = radToDeg( ( real ) dJointGetHinge2Angle1( mJointID ) );
00273 }
00274 else
00275 {
00276
00277 assert( false );
00278 }
00279 break;
00280 case FIXED_JOINT:
00281
00282 assert( false );
00283 break;
00284 default:
00285 assert( false );
00286 break;
00287 }
00288
00289 return value;
00290 }
00291
00292 real ODEJoint::getDistance( int axisNum ) const
00293 {
00294 assert( axisNum >= 0 && axisNum < mNumAxes );
00295
00296 real value = 0;
00297
00298 switch ( mData.getType() )
00299 {
00300 case HINGE_JOINT:
00301 value = 0;
00302 break;
00303 case UNIVERSAL_JOINT:
00304 value = 0;
00305 break;
00306 case BALL_JOINT:
00307 value = 0;
00308 break;
00309 case SLIDER_JOINT:
00310 value = ( real ) dJointGetSliderPosition( mJointID );
00311 break;
00312 case WHEEL_JOINT:
00313 value = 0;
00314 break;
00315 case FIXED_JOINT:
00316
00317 assert( false );
00318 break;
00319 default:
00320 assert( false );
00321 break;
00322 }
00323
00324 return value;
00325 }
00326
00327 real ODEJoint::getVelocity( int axisNum ) const
00328 {
00329 assert( axisNum >= 0 && axisNum < mNumAxes );
00330
00331 real value = 0;
00332
00333 switch ( mData.getType() )
00334 {
00335 case HINGE_JOINT:
00336 value = radToDeg( ( real ) dJointGetHingeAngleRate( mJointID ) );
00337 break;
00338 case UNIVERSAL_JOINT:
00339 if ( 0 == axisNum )
00340 {
00341 value = radToDeg(
00342 ( real ) dJointGetUniversalAngle1Rate( mJointID ) );
00343 }
00344 else
00345 {
00346 value = radToDeg(
00347 ( real ) dJointGetUniversalAngle2Rate( mJointID ) );
00348 }
00349 break;
00350 case BALL_JOINT:
00351 value = radToDeg(
00352 ( real ) dJointGetAMotorAngleRate( mAMotorID, axisNum ) );
00353 break;
00354 case SLIDER_JOINT:
00355 value = ( real ) dJointGetSliderPositionRate( mJointID );
00356 break;
00357 case WHEEL_JOINT:
00358 if ( 0 == axisNum )
00359 {
00360 value = radToDeg(
00361 ( real ) dJointGetHinge2Angle1Rate( mJointID ) );
00362 }
00363 else
00364 {
00365 value = radToDeg(
00366 ( real ) dJointGetHinge2Angle2Rate( mJointID ) );
00367 }
00368 break;
00369 case FIXED_JOINT:
00370
00371 assert( false );
00372 break;
00373 default:
00374 assert( false );
00375 break;
00376 }
00377
00378 return value;
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 void ODEJoint::setLimitHardness( int axisNum, real h )
00392 {
00393 Joint::setLimitHardness( axisNum, h );
00394
00395
00396
00397 real value = h * ( defaults::ode::maxERP - defaults::ode::minERP ) +
00398 defaults::ode::minERP;
00399
00400
00401 switch ( axisNum )
00402 {
00403 case 0:
00404 setJointParam( dParamStopERP, value );
00405 break;
00406 case 1:
00407 setJointParam( dParamStopERP2, value );
00408 break;
00409 case 2:
00410 setJointParam( dParamStopERP3, value );
00411 break;
00412 default:
00413 assert( false );
00414 break;
00415 }
00416
00417
00418
00419 if ( 1 == axisNum && WHEEL_JOINT == mData.getType() )
00420 {
00421 setJointParam( dParamSuspensionERP, value );
00422 }
00423 }
00424
00425 void ODEJoint::setLimitBounciness( int axisNum, real b )
00426 {
00427 Joint::setLimitBounciness( axisNum, b );
00428
00429
00430
00431 real value = b * ( defaults::ode::maxERP - defaults::ode::minERP ) +
00432 defaults::ode::minERP;
00433
00434
00435 switch ( axisNum )
00436 {
00437 case 0:
00438 setJointParam( dParamBounce, value );
00439 break;
00440 case 1:
00441 setJointParam( dParamBounce2, value );
00442 break;
00443 case 2:
00444 setJointParam( dParamBounce3, value );
00445 break;
00446 default:
00447 assert( false );
00448 break;
00449 }
00450 }
00451
00452 JointAxis ODEJoint::getAxis( int axisNum ) const
00453 {
00454
00455 if ( axisNum < 0 || axisNum >= mNumAxes )
00456 {
00457 return JointAxis();
00458 }
00459
00460
00461 dVector3 direction;
00462
00463 switch ( mData.getType() )
00464 {
00465 case HINGE_JOINT:
00466 dJointGetHingeAxis( mJointID, direction );
00467 break;
00468 case UNIVERSAL_JOINT:
00469 if ( 0 == axisNum )
00470 {
00471 dJointGetUniversalAxis1( mJointID, direction );
00472 }
00473 else
00474 {
00475 dJointGetUniversalAxis2( mJointID, direction );
00476 }
00477 break;
00478 case BALL_JOINT:
00479 if ( 0 == axisNum )
00480 {
00481 dJointGetAMotorAxis( mAMotorID, 0, direction );
00482 }
00483 else if ( 1 == axisNum )
00484 {
00485 dJointGetAMotorAxis( mAMotorID, 1, direction );
00486 }
00487 else
00488 {
00489 dJointGetAMotorAxis( mAMotorID, 2, direction );
00490 }
00491 break;
00492 case SLIDER_JOINT:
00493 dJointGetSliderAxis( mJointID, direction );
00494 break;
00495 case WHEEL_JOINT:
00496 if ( 0 == axisNum )
00497 {
00498 dJointGetHinge2Axis1( mJointID, direction );
00499 }
00500 else
00501 {
00502 dJointGetHinge2Axis2( mJointID, direction );
00503 }
00504 break;
00505 case FIXED_JOINT:
00506
00507 break;
00508 default:
00509 assert( false );
00510 break;
00511 }
00512
00513 JointAxis axis = mData.axis[ axisNum ];
00514
00515
00516
00517 axis.direction.set( ( real ) direction[ 0 ],
00518 ( real ) direction[ 1 ],
00519 ( real ) direction[ 2 ] );
00520
00521 return axis;
00522 }
00523
00524 Point3r ODEJoint::getAnchor() const
00525 {
00526
00527 dVector3 anchor;
00528
00529 switch ( mData.getType() )
00530 {
00531 case HINGE_JOINT:
00532 dJointGetHingeAnchor( mJointID, anchor );
00533 break;
00534 case UNIVERSAL_JOINT:
00535 dJointGetUniversalAnchor( mJointID, anchor );
00536 break;
00537 case BALL_JOINT:
00538 dJointGetBallAnchor( mJointID, anchor );
00539 break;
00540 case SLIDER_JOINT:
00541
00542 break;
00543 case WHEEL_JOINT:
00544 dJointGetHinge2Anchor( mJointID, anchor );
00545 break;
00546 case FIXED_JOINT:
00547
00548 break;
00549 default:
00550 assert( false );
00551 break;
00552 }
00553
00554 return Point3r( ( real ) anchor[ 0 ], ( real ) anchor[ 1 ], ( real ) anchor[ 2 ] );
00555 }
00556
00557 void ODEJoint::internal_update()
00558 {
00559 if ( mData.enabled )
00560 {
00561
00562 updateDamage( calcStress() );
00563 }
00564 }
00565
00566 void ODEJoint::internal_setDesiredVel( int axisNum, real value )
00567 {
00568 assert( axisNum >= 0 && axisNum < mNumAxes );
00569
00570 switch ( axisNum )
00571 {
00572 case 0:
00573 setJointParam( dParamVel, value );
00574 break;
00575 case 1:
00576 setJointParam( dParamVel2, value );
00577 break;
00578 case 2:
00579 setJointParam( dParamVel3, value );
00580 break;
00581 default:
00582 assert( false );
00583 break;
00584 }
00585 }
00586
00587 void ODEJoint::internal_setMaxTorque( int axisNum, real value )
00588 {
00589 assert( axisNum >= 0 && axisNum < mNumAxes );
00590
00591 switch ( axisNum )
00592 {
00593 case 0:
00594 setJointParam( dParamFMax, value );
00595 break;
00596 case 1:
00597 setJointParam( dParamFMax2, value );
00598 break;
00599 case 2:
00600 setJointParam( dParamFMax3, value );
00601 break;
00602 default:
00603 assert( false );
00604 break;
00605 }
00606 }
00607
00608 void ODEJoint::setAxis( int axisNum, const JointAxis& axis )
00609 {
00610
00611
00612 if ( axisNum < 0 || axisNum >= mNumAxes )
00613 {
00614 return ;
00615 }
00616
00617
00618 JointAxis normAxis = axis;
00619 normAxis.direction.normalize();
00620
00621
00622 Joint::setAxis( axisNum, normAxis );
00623
00624
00625 dVector3 newAxis = {( dReal ) normAxis.direction[ 0 ],
00626 ( dReal ) normAxis.direction[ 1 ], ( dReal ) normAxis.direction[ 2 ] };
00627
00628
00629 switch ( mData.getType() )
00630 {
00631 case HINGE_JOINT:
00632 dJointSetHingeAxis( mJointID, newAxis[ 0 ], newAxis[ 1 ],
00633 newAxis[ 2 ] );
00634 break;
00635 case UNIVERSAL_JOINT:
00636 if ( 0 == axisNum )
00637 {
00638 dJointSetUniversalAxis1( mJointID, newAxis[ 0 ], newAxis[ 1 ],
00639 newAxis[ 2 ] );
00640 }
00641 else
00642 {
00643 dJointSetUniversalAxis2( mJointID, newAxis[ 0 ], newAxis[ 1 ],
00644 newAxis[ 2 ] );
00645 }
00646 break;
00647 case BALL_JOINT:
00648
00649
00650
00651
00652
00653
00654
00655
00656 if ( 0 == axisNum )
00657 {
00658 dJointSetAMotorAxis( mAMotorID, 0, 1, newAxis[ 0 ],
00659 newAxis[ 1 ], newAxis[ 2 ] );
00660 }
00661 else if ( 2 == axisNum )
00662 {
00663 dJointSetAMotorAxis( mAMotorID, 2, 2, newAxis[ 0 ],
00664 newAxis[ 1 ], newAxis[ 2 ] );
00665 }
00666 break;
00667 case SLIDER_JOINT:
00668 dJointSetSliderAxis( mJointID, newAxis[ 0 ], newAxis[ 1 ],
00669 newAxis[ 2 ] );
00670 break;
00671 case WHEEL_JOINT:
00672 if ( 0 == axisNum )
00673 {
00674 dJointSetHinge2Axis1( mJointID, newAxis[ 0 ], newAxis[ 1 ],
00675 newAxis[ 2 ] );
00676 }
00677 else
00678 {
00679 dJointSetHinge2Axis2( mJointID, newAxis[ 0 ], newAxis[ 1 ],
00680 newAxis[ 2 ] );
00681 }
00682 break;
00683 case FIXED_JOINT:
00684
00685 break;
00686 default:
00687 assert( false );
00688 break;
00689 }
00690
00691
00692 setLimitsEnabled( axisNum, normAxis.limitsEnabled );
00693
00694
00695 setLimitRange( axisNum, normAxis.limits.low, normAxis.limits.high );
00696
00697
00698 setLimitHardness( axisNum, normAxis.limits.hardness );
00699
00700
00701 setLimitBounciness( axisNum, normAxis.limits.bounciness );
00702 }
00703
00704 void ODEJoint::setAnchor( const Point3r& anchor )
00705 {
00706 Joint::setAnchor( anchor );
00707 dVector3 newAnchor = {( dReal ) anchor[ 0 ], ( dReal ) anchor[ 1 ],
00708 ( dReal ) anchor[ 2 ] };
00709
00710 switch ( mData.getType() )
00711 {
00712 case HINGE_JOINT:
00713 dJointSetHingeAnchor( mJointID, newAnchor[ 0 ], newAnchor[ 1 ],
00714 newAnchor[ 2 ] );
00715 break;
00716 case UNIVERSAL_JOINT:
00717 dJointSetUniversalAnchor( mJointID, newAnchor[ 0 ],
00718 newAnchor[ 1 ], newAnchor[ 2 ] );
00719 break;
00720 case BALL_JOINT:
00721 dJointSetBallAnchor( mJointID, newAnchor[ 0 ], newAnchor[ 1 ],
00722 newAnchor[ 2 ] );
00723 break;
00724 case SLIDER_JOINT:
00725
00726 break;
00727 case WHEEL_JOINT:
00728 dJointSetHinge2Anchor( mJointID, newAnchor[ 0 ], newAnchor[ 1 ],
00729 newAnchor[ 2 ] );
00730 break;
00731 case FIXED_JOINT:
00732
00733 break;
00734 default:
00735 assert( false );
00736 break;
00737 }
00738 }
00739
00740 void ODEJoint::setLimitsEnabled( int axisNum, bool e )
00741 {
00742 Joint::setLimitsEnabled( axisNum, e );
00743
00744 if ( e )
00745 {
00746 real low = mData.axis[ axisNum ].limits.low;
00747 real high = mData.axis[ axisNum ].limits.high;
00748
00749 if ( isRotational( axisNum ) )
00750 {
00751 low = degToRad( low );
00752 high = degToRad( high );
00753 }
00754
00755 switch ( axisNum )
00756 {
00757 case 0:
00758
00759
00760 setJointParam( dParamLoStop, low );
00761 setJointParam( dParamHiStop, high );
00762 setJointParam( dParamLoStop, low );
00763 setJointParam( dParamHiStop, high );
00764 break;
00765 case 1:
00766
00767
00768 setJointParam( dParamLoStop2, low );
00769 setJointParam( dParamHiStop2, high );
00770 setJointParam( dParamLoStop2, low );
00771 setJointParam( dParamHiStop2, high );
00772 break;
00773 case 2:
00774
00775
00776 setJointParam( dParamLoStop3, low );
00777 setJointParam( dParamHiStop3, high );
00778 setJointParam( dParamLoStop3, low );
00779 setJointParam( dParamHiStop3, high );
00780 break;
00781 default:
00782 assert( false );
00783 break;
00784 }
00785 }
00786 else
00787 {
00788 switch ( axisNum )
00789 {
00790 case 0:
00791
00792
00793 setJointParam( dParamLoStop, -dInfinity );
00794 setJointParam( dParamHiStop, dInfinity );
00795 setJointParam( dParamLoStop, -dInfinity );
00796 setJointParam( dParamHiStop, dInfinity );
00797 break;
00798 case 1:
00799
00800
00801 setJointParam( dParamLoStop2, -dInfinity );
00802 setJointParam( dParamHiStop2, dInfinity );
00803 setJointParam( dParamLoStop2, -dInfinity );
00804 setJointParam( dParamHiStop2, dInfinity );
00805 break;
00806 case 2:
00807
00808
00809 setJointParam( dParamLoStop3, -dInfinity );
00810 setJointParam( dParamHiStop3, dInfinity );
00811 setJointParam( dParamLoStop3, -dInfinity );
00812 setJointParam( dParamHiStop3, dInfinity );
00813 break;
00814 default:
00815 assert( false );
00816 break;
00817 }
00818 }
00819 }
00820
00821 void ODEJoint::setEnabled( bool e )
00822 {
00823 if ( !mInitCalled )
00824 {
00825 return ;
00826 }
00827
00828
00829 if ( e == true )
00830 filterSolidForStaticness( mData.solid0, mData.solid1 );
00831
00832 if ( NULL == mData.solid0 && NULL == mData.solid1 )
00833 {
00834 return ;
00835 }
00836 else
00837 {
00838 Joint::setEnabled( e );
00839
00840 if ( e )
00841 {
00842
00843 attachODEBodies( mData.solid0, mData.solid1 );
00844 }
00845 else
00846 {
00847
00848 attachODEBodies( NULL, NULL );
00849 }
00850 }
00851 }
00852
00853 void ODEJoint::setLimitRange( int axisNum, real low, real high )
00854 {
00855 Joint::setLimitRange( axisNum, low, high );
00856
00857
00858
00859 if ( isRotational( axisNum ) )
00860 {
00861 low = degToRad( low );
00862 high = degToRad( high );
00863 }
00864
00865
00866
00867 switch ( axisNum )
00868 {
00869 case 0:
00870 if ( mData.axis[ axisNum ].limitsEnabled )
00871 {
00872
00873
00874 setJointParam( dParamLoStop, low );
00875 setJointParam( dParamHiStop, high );
00876 setJointParam( dParamLoStop, low );
00877 setJointParam( dParamHiStop, high );
00878 }
00879 break;
00880 case 1:
00881 if ( mData.axis[ axisNum ].limitsEnabled )
00882 {
00883
00884
00885 setJointParam( dParamLoStop2, low );
00886 setJointParam( dParamHiStop2, high );
00887 setJointParam( dParamLoStop2, low );
00888 setJointParam( dParamHiStop2, high );
00889 }
00890 break;
00891 case 2:
00892 if ( mData.axis[ axisNum ].limitsEnabled )
00893 {
00894
00895
00896 setJointParam( dParamLoStop3, low );
00897 setJointParam( dParamHiStop3, high );
00898 setJointParam( dParamLoStop3, low );
00899 setJointParam( dParamHiStop3, high );
00900 }
00901 break;
00902 default:
00903 assert( false );
00904 break;
00905 }
00906 }
00907
00908 void ODEJoint::setJointParam( int parameter, dReal value )
00909 {
00910 switch ( mData.getType() )
00911 {
00912 case HINGE_JOINT:
00913 dJointSetHingeParam( mJointID, parameter, value );
00914 break;
00915 case UNIVERSAL_JOINT:
00916 dJointSetUniversalParam( mJointID, parameter, value );
00917 break;
00918 case BALL_JOINT:
00919 dJointSetAMotorParam( mAMotorID, parameter, value );
00920 break;
00921 case SLIDER_JOINT:
00922 dJointSetSliderParam( mJointID, parameter, value );
00923 break;
00924 case WHEEL_JOINT:
00925 dJointSetHinge2Param( mJointID, parameter, value );
00926 break;
00927 case FIXED_JOINT:
00928 assert( false );
00929 break;
00930 default:
00931 assert( false );
00932 break;
00933 }
00934 }
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 real ODEJoint::calcStress()
00969 {
00970
00971
00972
00973 real currentStress = 0;
00974
00975 switch ( mData.breakMode )
00976 {
00977 case UNBREAKABLE_MODE:
00978
00979 break;
00980 case THRESHOLD_MODE:
00981
00982 case ACCUMULATED_MODE:
00983 {
00984 dJointFeedback* jf = dJointGetFeedback( mJointID );
00985 Vec3r f1( ( real ) jf->f1[ 0 ], ( real ) jf->f1[ 1 ], ( real ) jf->f1[ 2 ] );
00986 Vec3r t1( ( real ) jf->t1[ 0 ], ( real ) jf->t1[ 1 ], ( real ) jf->t1[ 2 ] );
00987 Vec3r f2( ( real ) jf->f2[ 0 ], ( real ) jf->f2[ 1 ], ( real ) jf->f2[ 2 ] );
00988 Vec3r t2( ( real ) jf->t2[ 0 ], ( real ) jf->t2[ 1 ], ( real ) jf->t2[ 2 ] );
00989
00990 f1 -= f2;
00991 t1 -= t2;
00992
00993
00994 currentStress = f1.length() + t1.length();
00995 break;
00996 }
00997 default:
00998 assert( false );
00999 }
01000
01001 return ( currentStress );
01002 }
01003
01004 dJointID ODEJoint::internal_getJointID() const
01005 {
01006 if ( BALL_JOINT == mData.getType() )
01007 {
01008 return mAMotorID;
01009 }
01010 else
01011 {
01012 return mJointID;
01013 }
01014 }
01015
01016 void ODEJoint::attachODEBodies( Solid* s0, Solid* s1 )
01017 {
01018 ODESolid * solid0 = ( ODESolid* ) s0;
01019 ODESolid* solid1 = ( ODESolid* ) s1;
01020
01021 if ( NULL == solid0 && NULL == solid1 )
01022 {
01023 dJointAttach( mJointID, 0, 0 );
01024 if ( BALL_JOINT == mData.getType() )
01025 {
01026 dJointAttach( mAMotorID, 0, 0 );
01027 }
01028 }
01029 else
01030 {
01031 if ( NULL == solid0 )
01032 {
01033 dJointAttach( mJointID, 0, solid1->internal_getBodyID() );
01034 if ( BALL_JOINT == mData.getType() )
01035 {
01036 dJointAttach( mAMotorID, 0, solid1->internal_getBodyID() );
01037 }
01038 }
01039 else if ( NULL == solid1 )
01040 {
01041 dJointAttach( mJointID, solid0->internal_getBodyID(), 0 );
01042 if ( BALL_JOINT == mData.getType() )
01043 {
01044 dJointAttach( mAMotorID, solid0->internal_getBodyID(), 0 );
01045 }
01046 }
01047 else
01048 {
01049 dJointAttach( mJointID, solid0->internal_getBodyID(),
01050 solid1->internal_getBodyID() );
01051 if ( BALL_JOINT == mData.getType() )
01052 {
01053 dJointAttach( mAMotorID, solid0->internal_getBodyID(),
01054 solid1->internal_getBodyID() );
01055 }
01056 }
01057
01058
01059
01060
01061 if ( FIXED_JOINT == mData.getType() )
01062 {
01063 dJointSetFixed( mJointID );
01064 }
01065 }
01066 }
01067 }