NWN style camera
Posted: Tue Jul 20, 2004 5:00 am
Ok, I've been asking so many questions, I figure it's time to donate something back to the community. I've made a Never Winter Nights style camera(where you move the mouse to the edge of the screen for it to rotate around an object, and if you scroll the middle mouse button, it will zoom in and out. There is also if you hold the middle mouse button, it's a free roam around the object, but I haven't put that in yet. I'll probably post that when I'm done with that as well.)
Here is the code, which I hope is fairly clear.
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.
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.