1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
// compute the aimed-at orientation
Q1.FromAngleAxis( Ogre::Radian(mRoll), Ogre::Vector3( 0,0,1) );
Q2.FromAngleAxis ( Ogre::Radian(mPitch), Ogre::Vector3( 1,0,0) );
Q3.FromAngleAxis ( Ogre::Radian(mYaw), Ogre::Vector3( 0,1,0) );
aimQ=Q3*Q1*Q2; // the order is important.
aimQ.normalise();
curQ=mPhysBody->getOrientation();
// take 3 points ( axis ) in the two different orientations
// ( current and aimed-at )
// We really only need two points/planes,
// but it looks better like that ! :)
AimYaw=aimQ*Ogre::Vector3(0,0,1);
CurYaw=curQ*Ogre::Vector3(0,0,1);
AimPitch=aimQ*Ogre::Vector3(0,1,0);
CurPitch=curQ*Ogre::Vector3(0,1,0);
AimRoll=aimQ*Ogre::Vector3(1,0,0);
CurRoll=curQ*Ogre::Vector3(1,0,0);
// Yaw :
// Find the yaw direction to go from the current position
// to the aimed-at position.
// CurRoll is used here as the normal of the plane passing through
// the CurYaw point and perpendicular to the "Yaw plane".
mYawPs=CurRoll.dotProduct( AimYaw );
if( AimYaw.crossProduct( CurYaw ) != CurRoll ) { // stop condition
forceYaw=mYawPs<0?-impulseYaw:impulseYaw; // apply forces even if the dot product is 0
}
else forceYaw=0;
// Pitch
mPitchPs=CurYaw.dotProduct( AimPitch );
if( AimPitch.crossProduct( CurPitch ) != CurYaw ) {
forcePitch=mPitchPs<0?-impulsePitch:impulsePitch;
}
else forcePitch=0;
// Roll
mRollPs=CurPitch.dotProduct( AimRoll );
if( AimRoll.crossProduct( CurRoll ) != CurPitch ) {
forceRoll=mRollPs<0?-impulseRoll:impulseRoll;
}
else forceRoll=0;
// and finally :
mPhysBody->addRelativeTorque ( Ogre::Vector3( forcePitch, forceYaw, forceRoll )); |
Partager