/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Christian Meyer co-programmer: Benjamin Grauer */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY #include "camera.h" #include "event_handler.h" using namespace std; /** * creates a Camera */ Camera::Camera() { this->setClassID(CL_CAMERA, "Camera"); this->setName("camera"); this->target = new CameraTarget(); EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_VIEW0); EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_VIEW1); EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_VIEW2); EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_VIEW3); EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_VIEW4); EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_VIEW5); this->setFovy(90); this->setAspectRatio(1.2f); this->setClipRegion(.1, 2000); this->setViewMode(VIEW_NORMAL); this->setParentMode(PNODE_ALL); } /** * default destructor */ Camera::~Camera() {} /** * focuses the Camera onto a Target * @param target the new PNode the Camera should look at. */ void Camera::lookAt(PNode* target) { this->target->setParent(target); } /** * @returns The PNode of the Target (from there you can get position and so on */ PNode* Camera::getTargetNode() const { return (PNode*)this->target; } /** * sets a new AspectRatio * @param aspectRatio the new aspect ratio to set (width / height) */ void Camera::setAspectRatio(float aspectRatio) { this->aspectRatio = aspectRatio; } /** * sets the Field of View to fofy * @param fovy new field of view factor (in degrees) */ void Camera::setFovy(float fovy) { this->fovy = fovy; } /** * Sets a new clipping region * @param nearClip The near clip plane * @param farClip The far clip plane */ void Camera::setClipRegion(float nearClip, float farClip) { this->nearClip = nearClip; this->farClip = farClip; } /** * sets the new VideoMode and initializes iteration to it. * @param mode the mode to change to. */ void Camera::setViewMode(ViewMode mode) { currentMode = mode; switch (mode) { default: case VIEW_NORMAL: this->toFovy = 60.0; this->setRelCoorSoft(-10, 5, 0); this->target->setRelCoorSoft(0,0,0); break; case VIEW_BEHIND: break; case VIEW_FRONT: this->toFovy = 120.0; this->setRelCoorSoft(4, 0, 0, 5); this->target->setRelCoorSoft(Vector(10,0,0), 5); break; case VIEW_LEFT: this->toFovy = 90; this->setRelCoorSoft(0, 1, -10, .5); this->target->setRelCoorSoft(0,0,0); break; case VIEW_RIGHT: this->toFovy = 90; this->setRelCoorSoft(Vector(0, 1, 10)); this->target->setRelCoorSoft(0,0,0); break; case VIEW_TOP: this->toFovy= 120; this->setRelCoorSoft(Vector(30, 50, 0)); this->target->setRelCoorSoft(35,0,0); } } /** * Updates the position of the camera. * @param dt: The time that elapsed. */ void Camera::tick(float dt) { //update frustum plane this->viewVector = (this->target->getAbsCoor() - this->getAbsCoor()).getNormalized(); this->frustumPlane = Plane(this->viewVector, this->getAbsCoor() + this->viewVector * 0.1); this->upVector = this->getAbsDirV(); float tmpFovy = (this->toFovy - this->fovy) ; if (tmpFovy > 0.01) this->fovy += tmpFovy * fabsf(dt); } /** * initialize rendering perspective according to this camera * * This is called immediately before the rendering cycle starts, it sets all global * rendering options as well as the GL_PROJECTION matrix according to the camera. */ void Camera::apply () { // switching to Projection Matrix glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(this->fovy, this->aspectRatio, this->nearClip, this->farClip); // setting up the perspective // speed-up feature Vector cameraPosition = this->getAbsCoor(); Vector targetPosition = this->target->getAbsCoor(); // Setting the Camera Eye, lookAt and up Vectors gluLookAt(cameraPosition.x, cameraPosition.y, cameraPosition.z, targetPosition.x, targetPosition.y, targetPosition.z, this->upVector.x, this->upVector.y, this->upVector.z); glMatrixMode (GL_MODELVIEW); glLoadIdentity(); } /** * processes an event * @param event: the event to process */ void Camera::process(const Event &event) { if( event.type == KeyMapper::PEV_VIEW0) { this->setViewMode(VIEW_NORMAL); } else if( event.type == KeyMapper::PEV_VIEW1) { this->setViewMode(VIEW_BEHIND); } else if( event.type == KeyMapper::PEV_VIEW2) { this->setViewMode(VIEW_FRONT); } else if( event.type == KeyMapper::PEV_VIEW3) { this->setViewMode(VIEW_LEFT); } else if( event.type == KeyMapper::PEV_VIEW4) { this->setViewMode(VIEW_RIGHT); } else if( event.type == KeyMapper::PEV_VIEW5) { this->setViewMode(VIEW_TOP); } } /////////////////// // CAMERA-TARGET // /////////////////// CameraTarget::CameraTarget() { this->setClassID(CL_CAMERA_TARGET, "CameraTarget"); // this->setParentMode(PNODE_MOVEMENT); }