Here is the code, which I hope is fairly clear.
some stuff for you to know. the cData class is a singleton accessed through the get function, and that stores most of the global data, like the device, resolution of the screen, and a few other things. You could modify the code so that you can get to them from elsewhere (cData::Get().Device() returns a refrence to the current device, while cData::Get().CameraSpeed() returns .01f as of right now.) The zooming system could probably do with a bit of an improvement(mainly, it's too fast zooming at closer levels, but slower at higher levels)class cFollowCamera: public IEventReceiver
{
public:
ISceneNode *Target() {
return m_target;
}
void Target(ISceneNode *value) {
m_target = value;
m_lastTargetPos = value->getPosition();
m_target->grab();
}
void Update() {
if (!m_Cam || !m_target) return;
if (MouseX <= cData::Get().Width()*.05f) {
m_updated = true;
m_yRotationAngle += cData::Get().CameraSpeed();
while (m_yRotationAngle > 2*PI)
m_yRotationAngle -= 2*PI;
}
else if (MouseX >= cData::Get().Width()*.95f) {
m_updated = true;
m_yRotationAngle -= cData::Get().CameraSpeed();
while (m_yRotationAngle < 2*PI)
m_yRotationAngle += 2*PI;
}
if (m_lastTargetPos != m_target->getPosition()) {
m_updated = true;
m_lastTargetPos = m_target->getPosition();
}
if (m_updated) {
m_updated = false;
vector3df m_Camerapos = m_lastTargetPos;
m_Camerapos.X += distance*sin(m_yRotationAngle);
m_Camerapos.Z += distance*cos(m_yRotationAngle);
m_Camerapos.Y += distance;
m_Cam->setPosition(m_Camerapos);
m_Cam->setTarget(m_lastTargetPos);
}
}
void Zoom(float amount) {
distance *= amount;
if (distance == 0) distance = 2; //there should be more elaborate capping of things here..
m_updated = true;
}
bool OnEvent(SEvent event) {
if (event.EventType == EET_MOUSE_INPUT_EVENT) {
switch (event.MouseInput.Event) {
case EMIE_MOUSE_WHEEL:
Zoom(((-event.MouseInput.Wheel)+1)/2+.5f); //make it be from .5 to 1.5
return true;
break;
case EMIE_MOUSE_MOVED:
MouseX = event.MouseInput.X;
return true;
break;
}
}
return false;
}
cFollowCamera(ISceneNode *target) {
Target(target);
m_Cam = cData::Get().Device().getSceneManager()->addCameraSceneNode(0,m_lastTargetPos + vector3df(0,20,20),m_lastTargetPos);
m_yRotationAngle = 0.0f;
distance = 20;
}
~cFollowCamera(void) {
m_target->drop();
}
private:
ISceneNode* m_target;
ICameraSceneNode* m_Cam;
vector3df m_lastTargetPos;
bool m_updated;
int MouseX;
float distance;
float m_yRotationAngle; //the angle about the Y axis
};
If you have any questions about the code, feel free to ask me.
Edit: I inverted the Wheel input, so that moving the wheel forward will zoom you in instead of out. oh, and I removed the random end quote thing at the end.
