[solution] NPC face player with OgreNewt::PlayerController

majc

20-08-2010 18:57:42

I'm doing a function to my npcs or objects face another entity giving the entity's coordinates.
I can't use lookat function because I'm using OgreNewt and i can't change the node orientation but i have to change the physical body orientation.
Then i made this function:

Ogre::Radian cNonPlayerCharacterAI::lookAtLocation(Ogre::Vector3 currentLocation, Ogre::Quaternion orientation, Ogre::Vector3 targetLocation)
{
goalHeading = targetLocation - currentLocation;
goalHeading.y = 0.0f;
goalHeading.normalise();
curHeading = orientation * Ogre::Vector3::NEGATIVE_UNIT_Z;
curHeading.normalise();
delta_o = Ogre::Radian(Math::ACos( curHeading.dotProduct( goalHeading ) ));
return delta_o;
}


As resource i used this website:

http://www.euclideanspace.com/maths/alg ... /index.htm

The problem is i start the level in front of the NPC and when i make debug:
- in front of the NPC writes 0 degrees(right)
- in the right side of the NPC writes 90 degrees(right)
but in the left side writes 90 degrees again(wrong)
- in the back side writes 180 degrees(right)

This is where i call the function:

Ogre::Vector3 position = cPhysicsInterface::getSingleton().getPosition(nonPlayerBody);
Ogre::Quaternion orientation = ((Ogre::SceneNode*)nonPlayerBody->getOgreNode())->getOrientation();//cPhysicsInterface::getSingleton().getOrientation(nonPlayerBody);

Ogre::Vector3 targetLocation = cPhysicsInterface::getSingleton().getPosition(mEntityBody);

heading = mNonPlayerAI->lookAtLocation(position, orientation, targetLocation);

mNonPlayerController->setVelocity(forwardSpeed, sideSpeed,heading );


The NPC it isn't facing the player right.
Why in the left side don't write 270 degrees and write in the both sides 90 degrees? What I'm missing?

Thanks in advance!

majc

21-08-2010 02:52:41

Ok i solved the problem here is the solution:

Ogre::Radian cNonPlayerCharacterAI::lookAtLocation(Ogre::Vector3 currentLocation, Ogre::Quaternion orientation, Ogre::Vector3 targetLocation)
{
goalHeading = targetLocation - currentLocation;
goalHeading.y = 0.0f;
goalHeading.normalise();
curHeading = orientation * Ogre::Vector3::NEGATIVE_UNIT_Z;
curHeading.normalise();

delta_o = Ogre::Radian(Math::ACos( curHeading.dotProduct( goalHeading ) ));

//changes ------------------------------------------------------------------------------------
//I had to calculate the cross product to know if the entity is turning left or right

rot_axis = curHeading.crossProduct( goalHeading ).normalisedCopy();

if(rot_axis.y < 0)
delta_o = -delta_o;
//----------------------------------------------------------------------------------------------
return delta_o;
}


I also had a mistake in the code snippet where i call this function(the changes are in bold in this case is the plus sign):

heading += mNonPlayerAI->lookAtLocation(position, orientation, targetLocation);