1 /* 2 * This file is part of the Colobot: Gold Edition source code 3 * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam 4 * http://epsitec.ch; http://colobot.info; http://github.com/colobot 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 * See the GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see http://gnu.org/licenses 18 */ 19 20 /** 21 * \file graphics/engine/camera.h 22 * \brief Camera handling - CCamera class 23 */ 24 25 #pragma once 26 27 #include "graphics/engine/engine.h" 28 29 30 class CObject; 31 class CRobotMain; 32 class CInput; 33 struct Event; 34 35 36 // Graphics module namespace 37 namespace Gfx 38 { 39 40 41 /** 42 \enum CameraType 43 \brief Type of camera */ 44 enum CameraType 45 { 46 //! Undefined 47 CAM_TYPE_NULL = 0, 48 //! Free camera 49 CAM_TYPE_FREE, 50 //! Camera while editing a program 51 CAM_TYPE_EDIT, 52 //! Camera on board a robot 53 CAM_TYPE_ONBOARD, 54 //! Camera behind a robot 55 CAM_TYPE_BACK, 56 //! Static camera following robot 57 CAM_TYPE_FIX, 58 //! Camera steady after explosion 59 CAM_TYPE_EXPLO, 60 //! Camera during a cutscene 61 CAM_TYPE_SCRIPT, 62 //! Visit camera, rotates around given position 63 CAM_TYPE_VISIT, 64 //! Static camera height 65 CAM_TYPE_PLANE, 66 }; 67 68 enum CameraSmooth 69 { 70 //! Sharp 71 CAM_SMOOTH_NONE = 0, 72 //! Normal 73 CAM_SMOOTH_NORM = 1, 74 //! Hard 75 CAM_SMOOTH_HARD = 2, 76 }; 77 78 enum CenteringPhase 79 { 80 CAM_PHASE_NULL = 0, 81 CAM_PHASE_START = 1, 82 CAM_PHASE_WAIT = 2, 83 CAM_PHASE_STOP = 3, 84 }; 85 86 enum CameraEffect 87 { 88 //! No effect 89 CAM_EFFECT_NULL = 0, 90 //! Digging in 91 CAM_EFFECT_TERRAFORM = 1, 92 //! Hard landing 93 CAM_EFFECT_CRASH = 2, 94 //! Explosion 95 CAM_EFFECT_EXPLO = 3, 96 //! Shot by an enemy 97 CAM_EFFECT_SHOT = 4, 98 //! Vibration during construction 99 CAM_EFFECT_VIBRATION = 5, 100 //! Overheated reactor 101 CAM_EFFECT_PET = 6, 102 }; 103 104 enum CameraOverEffect 105 { 106 //! No effect 107 CAM_OVER_EFFECT_NULL = 0, 108 //! Flash red 109 CAM_OVER_EFFECT_BLOOD = 1, 110 //! White -> nothing 111 CAM_OVER_EFFECT_FADEIN_WHITE = 2, 112 //! Nothing -> white 113 CAM_OVER_EFFECT_FADEOUT_WHITE = 3, 114 //! Nothing -> blue 115 CAM_OVER_EFFECT_FADEOUT_BLACK = 4, 116 //! Lightning 117 CAM_OVER_EFFECT_LIGHTNING = 5, 118 }; 119 120 121 /** 122 \class CCamera 123 \brief Camera moving in 3D scene 124 125 This class manages everything related to animating the camera in 3D scene. 126 Calculated values are then passed to Gfx::CEngine. 127 */ 128 class CCamera 129 { 130 public: 131 CCamera(); 132 ~CCamera(); 133 134 //! Management of an event 135 bool EventProcess(const Event &event); 136 137 /** 138 * \brief Initializes the camera 139 * \param eye Initial eye position 140 * \param lookat Initial lookat position 141 * \param delay Time of the initial entry animation 142 */ 143 void Init(Math::Vector eye, Math::Vector lookat, float delay); 144 145 //! Sets the object controlling the camera 146 void SetControllingObject(CObject* object); 147 //! Gets the object controlling the camera 148 CObject* GetControllingObject(); 149 150 //! Change the type of camera 151 void SetType(CameraType type); 152 //! Get the type of the camera 153 CameraType GetType(); 154 155 //! Set smoothing mode 156 void SetSmooth(CameraSmooth type); 157 //! Get smoothing mode 158 CameraSmooth GetSmooth(); 159 160 161 //! Returns the current point of view of the camera 162 void GetCamera(Math::Vector &eye, Math::Vector &lookat); 163 164 //! \name Visit camera management (CAM_TYPE_VISIT) - camera in this mode shows a position, constantly rotating around it 165 //@{ 166 //! Start visit camera 167 void StartVisit(Math::Vector goal, float dist); 168 //! Stop visit camera 169 void StopVisit(); 170 //@} 171 172 //! \name Camera "centering" - moves the camera to show some happening action (e.g. sniffer sniffing) 173 //@{ 174 //! Move camera to show happening action 175 bool StartCentering(CObject *object, float angleH, float angleV, float dist, float time); 176 //! Go back to normal position after showing some happening action 177 bool StopCentering(CObject *object, float time); 178 //! Abort centering animation in the current position 179 void AbortCentering(); 180 //@} 181 182 //! \name Camera shake effects 183 //@{ 184 //! Starts a camera shake effect 185 void StartEffect(CameraEffect effect, Math::Vector pos, float force); 186 //! Removes the camera shake effect 187 void FlushEffect(); 188 //@} 189 190 //! \name Camera overlay effects 191 //@{ 192 //! Starts camera overlay effect 193 void StartOver(CameraOverEffect effect, Math::Vector pos, float force); 194 //! Removes camera overlay effect 195 void FlushOver(); 196 //! Specifies camera overlay effect base color 197 void SetOverBaseColor(Color color); 198 //@} 199 200 //! \name Script camera - cutscenes controlled by external code 201 //@{ 202 //! Script camera: Set camera position 203 void SetScriptCamera(Math::Vector eye, Math::Vector lookat); 204 //! Script camera: Animate to given camera position 205 void SetScriptCameraAnimate(Math::Vector eye, Math::Vector lookat); 206 //! Script camera: Animate to given eye position 207 void SetScriptCameraAnimateEye(Math::Vector eye); 208 //! Script camera: Animate to given lookat position 209 void SetScriptCameraAnimateLookat(Math::Vector lookat); 210 //@} 211 212 //! \name Configuration settings 213 //@{ 214 void SetEffect(bool enable); 215 bool GetEffect(); 216 void SetBlood(bool enable); 217 bool GetBlood(); 218 void SetOldCameraScroll(bool scroll); 219 bool GetOldCameraScroll(); 220 void SetCameraInvertX(bool invert); 221 bool GetCameraInvertX(); 222 void SetCameraInvertY(bool invert); 223 bool GetCameraInvertY(); 224 //@} 225 226 //! Temporarily freeze camera movement 227 void SetFreeze(bool freeze); 228 229 //! Set camera speed 230 void SetCameraSpeed(float speed); 231 232 protected: 233 //! Advances the effect of the camera 234 void EffectFrame(const Event &event); 235 //! Advanced overlay effect in the foreground 236 void OverFrame(const Event &event); 237 238 bool EventFrameFree(const Event &event, bool keysAllowed); 239 bool EventFrameBack(const Event &event); 240 bool EventFrameFix(const Event &event); 241 bool EventFrameExplo(const Event &event); 242 bool EventFrameOnBoard(const Event &event); 243 bool EventFrameVisit(const Event &event); 244 bool EventFrameScript(const Event &event); 245 246 /** 247 * \brief Calculates camera animation and sends updated camera position to the 3D engine 248 * \param eyePt Eye point 249 * \param lookatPt Lookat point 250 * \param rTime Time since last time this function was called (used to calculate animation) 251 * \see SetViewParams 252 */ 253 void UpdateCameraAnimation(const Math::Vector &eyePt, const Math::Vector &lookatPt, float rTime); 254 255 /** 256 * \brief Avoid the obstacles 257 * 258 * For CAM_TYPE_BACK: make obstacles transparent 259 * For CAM_TYPE_FIX or CAM_TYPE_PLANE: adjust eye not to hit the obstacles 260 * 261 * \param eye Eye position, may be adjusted 262 * \param lookat Lookat point 263 */ 264 void IsCollision(Math::Vector &eye, Math::Vector lookat); 265 //! Avoid the obstacles (CAM_TYPE_BACK) 266 void IsCollisionBack(); 267 //! Avoid the obstacles (CAM_TYPE_FIX or CAM_TYPE_PLANE) 268 void IsCollisionFix(Math::Vector &eye, Math::Vector lookat); 269 270 //! Adjusts the camera not to enter the ground 271 Math::Vector ExcludeTerrain(Math::Vector eye, Math::Vector lookat, float &angleH, float &angleV); 272 //! Adjusts the camera not to enter an object 273 Math::Vector ExcludeObject(Math::Vector eye, Math::Vector lookat, float &angleH, float &angleV); 274 275 /** 276 * \brief Updates the location and direction of the camera in the 3D engine 277 * \param eye Eye point 278 * \param lookat Lookat point 279 * \param up Up vector 280 * \see CEngine::SetViewParams 281 */ 282 void SetViewParams(const Math::Vector &eye, const Math::Vector &lookat, const Math::Vector &up = Math::Vector(0.0f, 1.0f, 0.0f)); 283 284 /** 285 * \brief Calculate camera movement (from user inputs) to apply 286 * \return Math::Vector where x, y represent respectively horizontal and vertical angle change in radians and z represents zoom (distance change) 287 * \remarks Should not be called more often than once every EVENT_FRAME 288 **/ 289 Math::Vector CalculateCameraMovement(const Event &event, bool keysAllowed = true); 290 291 protected: 292 CEngine* m_engine; 293 CRobotMain* m_main; 294 CTerrain* m_terrain; 295 CWater* m_water; 296 CInput* m_input; 297 298 //! The type of camera 299 CameraType m_type; 300 //! Type of smoothing 301 CameraSmooth m_smooth; 302 //! Object linked to the camera 303 CObject* m_cameraObj; 304 305 //! Remaining time of initial camera entry animation 306 float m_initDelay; 307 308 //! Current eye 309 Math::Vector m_actualEye; 310 //! Current aim 311 Math::Vector m_actualLookat; 312 //! Final eye 313 Math::Vector m_finalEye; 314 //! Final lookat 315 Math::Vector m_finalLookat; 316 //! Eye position at the moment of entering CAM_TYPE_INFO/CAM_TYPE_VISIT 317 Math::Vector m_prevEye; 318 //! Lookat position at the moment of entering CAM_TYPE_INFO/CAM_TYPE_VISIT 319 Math::Vector m_prevLookat; 320 321 float m_focus; 322 323 //! CAM_TYPE_FREE: eye 324 Math::Vector m_eyePt; 325 //! CAM_TYPE_FREE: horizontal direction 326 float m_directionH; 327 //! CAM_TYPE_FREE: vertical direction 328 float m_directionV; 329 //! CAM_TYPE_FREE: height above the ground 330 float m_heightEye; 331 //! CAM_TYPE_FREE: height above the ground 332 float m_heightLookat; 333 //! CAM_TYPE_FREE: speed of movement 334 float m_speed; 335 336 //! CAM_TYPE_BACK: distance 337 float m_backDist; 338 //! CAM_TYPE_BACK: minimal distance 339 float m_backMin; 340 //! CAM_TYPE_BACK: additional horizontal direction 341 float m_addDirectionH; 342 //! CAM_TYPE_BACK: additional vertical direction 343 float m_addDirectionV; 344 345 //! CAM_TYPE_FIX: distance 346 float m_fixDist; 347 //! CAM_TYPE_FIX: horizontal direction 348 float m_fixDirectionH; 349 //! CAM_TYPE_FIX: vertical direction 350 float m_fixDirectionV; 351 352 //! CAM_TYPE_VISIT: target position 353 Math::Vector m_visitGoal; 354 //! CAM_TYPE_VISIT: distance 355 float m_visitDist; 356 //! CAM_TYPE_VISIT: relative time 357 float m_visitTime; 358 //! CAM_TYPE_VISIT: initial type 359 CameraType m_visitType; 360 //! CAM_TYPE_VISIT: direction 361 float m_visitDirectionV; 362 363 //! Last known mouse position, used to calculate change since last frame 364 Math::Point m_mousePos = Math::Point(0.5f, 0.5f); 365 //! Change of mouse position since last frame 366 Math::Point m_mouseDelta = Math::Point(0.0f, 0.0f); 367 //! Change of camera position caused by edge camera 368 Math::Point m_mouseDeltaEdge = Math::Point(0.0f, 0.0f); 369 //! Change of mouse wheel since last frame 370 float m_mouseWheelDelta = 0.0f; 371 372 CenteringPhase m_centeringPhase; 373 float m_centeringAngleH; 374 float m_centeringAngleV; 375 float m_centeringDist; 376 float m_centeringCurrentH; 377 float m_centeringCurrentV; 378 float m_centeringTime; 379 float m_centeringProgress; 380 381 CameraEffect m_effectType; 382 Math::Vector m_effectPos; 383 float m_effectForce; 384 float m_effectProgress; 385 Math::Vector m_effectOffset; 386 387 CameraOverEffect m_overType; 388 float m_overForce; 389 float m_overTime; 390 Color m_overColorBase; 391 Color m_overColor; 392 int m_overMode; 393 float m_overFadeIn; 394 float m_overFadeOut; 395 396 Math::Vector m_scriptEye; 397 Math::Vector m_scriptLookat; 398 399 //! Is camera frozen? 400 bool m_freeze = false; 401 402 //! \name Configuration settings 403 //@{ 404 bool m_effect; 405 bool m_blood; 406 bool m_oldCameraScroll; 407 bool m_cameraInvertX; 408 bool m_cameraInvertY; 409 //@} 410 }; 411 412 413 } // namespace Gfx 414