I've been playing around in the tutorials and wrote this chase camera class for the SpaceApp.
It has some jerky behaviour sometimes that I think is related to the direct setOrientation I use. However, I don't know how else to keep the camera node lined up with the target node in the "up" direction. Maybe there is some math trick to do it smoothly...? (ie to use rotateSpeed)
/*
FollowingCamera.h
Takes a camera and a scene node and has the camera follow the node
@author K. Carter Dodd (aka Longstreet)
*/
#include "ExampleFrameListener.h"
#include "OgreMath.h"
class FollowingCamera : public ExampleFrameListener
{
public:
FollowingCamera(RenderWindow* win, Camera* cam, SceneNode* followednode, Vector3 offset, Real chaseSpeed, Real rotateSpeed) : ExampleFrameListener(win, cam)
{
// attatch camera to the chasing node
mCameraNode = followednode->getParentSceneNode()->createChildSceneNode();
mCameraNode->attachObject(cam);
// turn it so its not upside down... ?
cam->rotate(Vector3::UNIT_Z, Angle(180));
// node to chase
mFollowedNode = followednode;
// offset for camera to chase (ie not right on top of target)
mCameraOffset = offset;
// speed multipliers
moveMultiplier = chaseSpeed;
rotateMultiplier = rotateSpeed;
}
bool frameStarted(const FrameEvent& evt)
{
// get the vector toward the ideal position
Vector3 moveVector = (mFollowedNode->getOrientation()*(mCameraOffset*mFollowedNode->getScale()) + mFollowedNode->getPosition()) - mCameraNode->getPosition();
// move a bit of that distance
mCameraNode->translate(moveVector * evt.timeSinceLastFrame * moveMultiplier);
// update camera orienation around target
mCameraNode->setOrientation(mFollowedNode->getOrientation());
// turn camera toward target center
mCameraNode->setDirection(mFollowedNode->getPosition() - mCameraNode->getPosition());
return true;
}
protected:
SceneNode* mCameraNode;
SceneNode* mFollowedNode;
Vector3 mCameraOffset;
Real moveMultiplier, rotateMultiplier;
};
Through basically trial and error I have come to this bit of code. I feel there must be a better way to do this though and keep the camera stable. The only change is the extra flip around UNIT_X, and this keeps the camera from going bonkers when the camera and target z axis are lined up (i.e. when it doesn't know which way is best to rotate the camera).
I've updated the .exe with this too, and some other things.
// get the vector toward the ideal position
Vector3 moveVector = (mFollowedNode->getOrientation()*(mCameraOffset*mFollowedNode->getScale()) + mFollowedNode->getPosition()) - mCameraNode->getPosition();
// move a bit of that distance
mCameraNode->translate(moveVector * evt.timeSinceLastFrame * moveMultiplier);
// update camera orienation around target
mCameraNode->setOrientation(mFollowedNode->getOrientation());
// flip the camera around to -z
mCameraNode->rotate(Vector3::UNIT_X, Angle(180));
// turn camera toward target center
mCameraNode->setDirection(mFollowedNode->getPosition() - mCameraNode->getPosition());