I'm trying to implement a LookAt function into my game. I have an enemy character ,i'd like to keep rotated towards the player wherever it goes.
If the enemy needs to turn left,everything is fine ,it follows the player correctly.But if it needs to turn right,it choses the long path,so it makes a big ugly rotation around itself,instead of chosing the short path.
I have read many forums,and they all said i need to check the dotProduct between the two quaternions,and if it's negative, need to negate one of them.
i tried differents methods,but they gave the same results,still chosing the longest path on "turning right".
Code: Select all
btQuaternion orig = mRigidBody->getWorldTransform().getRotation();
//angle is the angle between the quaternions
btQuaternion dest = orig * btQuaternion(btVector3(0,1,0),angle);
//QuatBlend calculates the dot product and negating,if necessary
btQuaternion result = QuatBlend(orig,dest,1);
//apply the transformations
mRigidBody->getWorldTransform().setRotation(result);
Code: Select all
btQuaternion QuatBlend(const btQuaternion& i, const btQuaternion& f, float blend)
{
btQuaternion result;
float dot = i.w()*f.w() + i.x()*f.x() + i.y()*f.y() + i.z()*f.z();
float blendI = 1.0f - blend;
if(dot < 0.0f)
{
btQuaternion tmpF;
tmpF.setW(-f.w());
tmpF.setX(-f.x());
tmpF.setY(-f.y());
tmpF.setZ(-f.z());
result.setW(blendI*i.w() + blend*tmpF.w());
result.setX(blendI*i.x() + blend*tmpF.x());
result.setY(blendI*i.y() + blend*tmpF.y());
result.setZ(blendI*i.w() + blend*tmpF.z());
}
else
{
result.setW(blendI*i.w() + blend*f.w());
result.setX(blendI*i.x() + blend*f.x());
result.setY(blendI*i.y() + blend*f.y());
result.setZ(blendI*i.z() + blend*f.z());
}
result = result.normalize();
return result;
}