PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: SNCamera.h * 00003 * 00004 * Copyright (C) 2002-2011 The PixelLight Team (http://www.pixellight.org/) 00005 * 00006 * This file is part of PixelLight. 00007 * 00008 * PixelLight is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published by 00010 * the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * PixelLight is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with PixelLight. If not, see <http://www.gnu.org/licenses/>. 00020 \*********************************************************/ 00021 00022 00023 #ifndef __PLSCENE_CAMERA_H__ 00024 #define __PLSCENE_CAMERA_H__ 00025 #pragma once 00026 00027 00028 //[-------------------------------------------------------] 00029 //[ Includes ] 00030 //[-------------------------------------------------------] 00031 #include <PLMath/Frustum.h> 00032 #include <PLMath/Matrix4x4.h> 00033 #include "PLScene/Scene/SceneNode.h" 00034 00035 00036 //[-------------------------------------------------------] 00037 //[ Namespace ] 00038 //[-------------------------------------------------------] 00039 namespace PLScene { 00040 00041 00042 //[-------------------------------------------------------] 00043 //[ Forward declarations ] 00044 //[-------------------------------------------------------] 00045 class SceneRenderer; 00046 class SceneRendererHandler; 00047 00048 00049 //[-------------------------------------------------------] 00050 //[ Classes ] 00051 //[-------------------------------------------------------] 00052 /** 00053 * @brief 00054 * PixelLight standard camera scene node 00055 * 00056 * @remarks 00057 * PixelLight is using a right-handed coordinate system like OpenGL does, therefore the camera usually looks 00058 * along the negative z-axis. While this fact may be ok in 'low level' functionality, it makes cameras less 00059 * comfortable within the scene graph because this 'look along negative z' doesn't go along with universal 00060 * features like 'look at this point'. So, we decided to 'break' the right-handed coordinate system convention 00061 * within the camera scene node when it's coming to 'look along negative z'. Instead we 'look along positive z' 00062 * and we profit from an universal behavior and don't need to care about flipping axis - although it's still 00063 * possible to flip axis. 00064 * 00065 * @note 00066 * - Scene node scale is ignored 00067 */ 00068 class SNCamera : public SceneNode { 00069 00070 00071 //[-------------------------------------------------------] 00072 //[ Public definitions ] 00073 //[-------------------------------------------------------] 00074 public: 00075 /** 00076 * @brief 00077 * Scene node flags (SceneNode flags extension) 00078 */ 00079 enum EFlags { 00080 FlipY = 1<<10, /**< Flip y axis */ 00081 InvCullMode = 1<<11, /**< Invert cull mode */ 00082 NoZFar = 1<<12 /**< Do not use the far clipping plane */ 00083 }; 00084 pl_enum(EFlags) 00085 pl_enum_base(SceneNode::EFlags) 00086 pl_enum_value(FlipY, "Flip y axis") 00087 pl_enum_value(InvCullMode, "Invert cull mode") 00088 pl_enum_value(NoZFar, "Do not use the far clipping plane") 00089 pl_enum_end 00090 00091 /** 00092 * @brief 00093 * Scene node debug flags (SceneNode debug flags extension) 00094 */ 00095 enum EDebugFlags { 00096 DebugNoFrustum = 1<<8, /**< Do not draw the (green) frustum */ 00097 DebugFrustumVertices = 1<<9 /**< Draw the (green) frustum vertices */ 00098 }; 00099 pl_enum(EDebugFlags) 00100 pl_enum_base(SceneNode::EDebugFlags) 00101 pl_enum_value(DebugNoFrustum, "Do not draw the (green) frustum") 00102 pl_enum_value(DebugFrustumVertices, "Draw the (green) frustum vertices") 00103 pl_enum_end 00104 00105 00106 //[-------------------------------------------------------] 00107 //[ RTTI interface ] 00108 //[-------------------------------------------------------] 00109 pl_class(PLS_RTTI_EXPORT, SNCamera, "PLScene", PLScene::SceneNode, "PixelLight standard camera scene node") 00110 // Properties 00111 pl_properties 00112 pl_property("Icon", "Data/Textures/IconCamera.dds") 00113 pl_properties_end 00114 // Attributes 00115 pl_attribute(FOV, float, 45.0f, ReadWrite, GetSet, "Field of view in degree", "Min='10.0' Max='170.0'") 00116 pl_attribute(Aspect, float, 1.0f, ReadWrite, GetSet, "Aspect factor", "") 00117 pl_attribute(ZNear, float, 0.01f, ReadWrite, GetSet, "Near clipping plane", "") 00118 pl_attribute(ZFar, float, 1000.0f, ReadWrite, GetSet, "Far clipping plane", "") 00119 pl_attribute(SceneRendererFilename, PLCore::String, "", ReadWrite, GetSet, "Filename of the scene renderer to use, if empty the default scene renderer of the scene graph surface painter is used", "Type='SceneRenderer'") 00120 // Overwritten SceneNode attributes 00121 pl_attribute(Flags, pl_flag_type(EFlags), 0, ReadWrite, GetSet, "Flags", "") 00122 pl_attribute(DebugFlags, pl_flag_type(EDebugFlags), 0, ReadWrite, GetSet, "Debug flags", "") 00123 // Constructors 00124 pl_constructor_0(DefaultConstructor, "Default constructor", "") 00125 pl_class_end 00126 00127 00128 //[-------------------------------------------------------] 00129 //[ Public RTTI get/set functions ] 00130 //[-------------------------------------------------------] 00131 public: 00132 PLS_API float GetFOV() const; 00133 PLS_API void SetFOV(float fValue); 00134 PLS_API float GetAspect() const; 00135 PLS_API void SetAspect(float fValue); 00136 PLS_API float GetZNear() const; 00137 PLS_API void SetZNear(float fValue); 00138 PLS_API float GetZFar() const; 00139 PLS_API void SetZFar(float fValue); 00140 PLS_API PLCore::String GetSceneRendererFilename() const; 00141 PLS_API void SetSceneRendererFilename(const PLCore::String &sValue); 00142 PLS_API virtual void SetFlags(PLCore::uint32 nValue); 00143 00144 00145 //[-------------------------------------------------------] 00146 //[ Public static functions ] 00147 //[-------------------------------------------------------] 00148 public: 00149 /** 00150 * @brief 00151 * Returns the current set camera 00152 * 00153 * @return 00154 * The current set camera, a null pointer if no camera is currently set 00155 */ 00156 static PLS_API SNCamera *GetCamera(); 00157 00158 /** 00159 * @brief 00160 * Sets the current set camera 00161 * 00162 * @param[in] pCamera 00163 * The current set camera, a null pointer if no camera is currently set 00164 * @param[in] pRenderer 00165 * Renderer to use, if a null pointer nothing happens 00166 */ 00167 static PLS_API void SetCamera(SNCamera *pCamera, PLRenderer::Renderer *pRenderer); 00168 00169 00170 //[-------------------------------------------------------] 00171 //[ Public functions ] 00172 //[-------------------------------------------------------] 00173 public: 00174 /** 00175 * @brief 00176 * Default constructor 00177 */ 00178 PLS_API SNCamera(); 00179 00180 /** 00181 * @brief 00182 * Destructor 00183 */ 00184 PLS_API virtual ~SNCamera(); 00185 00186 /** 00187 * @brief 00188 * Returns the used scene renderer 00189 * 00190 * @return 00191 * The used scene renderer, can be a null pointer 00192 */ 00193 PLS_API SceneRenderer *GetSceneRenderer() const; 00194 00195 /** 00196 * @brief 00197 * Sets the camera 00198 * 00199 * @param[in] cRenderer 00200 * Renderer to use 00201 * @param[in] bSetProjection 00202 * Set projection matrix? 00203 * @param[in] bSetView 00204 * Set view matrix? 00205 * 00206 * @return 00207 * 'true' if all went fine, else 'false' 00208 * 00209 * @note 00210 * - The projection and view matrix will be set using the camera settings 00211 */ 00212 PLS_API bool SetCamera(PLRenderer::Renderer &cRenderer, bool bSetProjection = true, bool bSetView = true); 00213 00214 /** 00215 * @brief 00216 * Returns whether the camera projection and view matrix and the frustum are updated automatically 00217 * 00218 * @return 00219 * 'true' if the camera projection and view matrix and the frustum are updated automatically, 00220 * else 'false' 00221 * 00222 * @note 00223 * - If this is 'true', the mentioned things will be updated within 'SetCamera()' 00224 */ 00225 PLS_API bool GetAutoUpdate() const; 00226 00227 /** 00228 * @brief 00229 * Sets whether the camera projection and view matrix and the frustum are updated automatically 00230 * 00231 * @param[in] bAutoUpdate 00232 * 'true' if the camera projection and view matrix and the frustum are updated automatically, 00233 * else 'false' 00234 * 00235 * @see 00236 * - GetAutoUpdate() 00237 */ 00238 PLS_API void SetAutoUpdate(bool bAutoUpdate = true); 00239 00240 /** 00241 * @brief 00242 * Returns the projection matrix 00243 * 00244 * @param[in] cViewport 00245 * Viewport to use 00246 * 00247 * @return 00248 * Projection matrix 00249 * 00250 * @see 00251 * - GetAutoUpdate() 00252 */ 00253 PLS_API PLMath::Matrix4x4 &GetProjectionMatrix(const PLMath::Rectangle &cViewport); 00254 00255 /** 00256 * @brief 00257 * Returns the view rotation offset 00258 * 00259 * @return 00260 * View rotation offset 00261 * 00262 * @remarks 00263 * By using the view rotation offset, a camera can be rotated towards one direction while viewing towards another one. 00264 * This view rotation offset can for example be controlled by a head tracker system. 00265 */ 00266 PLS_API const PLMath::Quaternion &GetViewRotationOffset() const; 00267 00268 /** 00269 * @brief 00270 * Sets the view rotation offset 00271 * 00272 * @param[in] qViewRotationOffset 00273 * New view rotation offset to set 00274 * 00275 * @see 00276 * - GetViewRotationOffset() 00277 */ 00278 PLS_API void SetViewRotationOffset(const PLMath::Quaternion &qViewRotationOffset); 00279 00280 /** 00281 * @brief 00282 * Returns the view matrix 00283 * 00284 * @return 00285 * View matrix 00286 * 00287 * @remarks 00288 * PixelLight is using a right-handed coordinate system like OpenGL does, therefore the view matrix 'looks' 00289 * along the negative z-axis. (unlike the camera scene node itself, have a look into the class documentation) 00290 * 00291 * @see 00292 * - GetAutoUpdate() 00293 */ 00294 PLS_API PLMath::Matrix3x4 &GetViewMatrix(); 00295 00296 /** 00297 * @brief 00298 * Returns the camera frustum 00299 * 00300 * @param[in] cViewport 00301 * Viewport to use 00302 * 00303 * @return 00304 * Camera frustum in 'scene container space' 00305 * 00306 * @see 00307 * - GetAutoUpdate() 00308 */ 00309 PLS_API PLMath::Frustum &GetFrustum(const PLMath::Rectangle &cViewport); 00310 00311 /** 00312 * @brief 00313 * Returns the 8 camera frustum vertices 00314 * 00315 * @param[in] cViewport 00316 * Viewport to use 00317 * 00318 * @return 00319 * 8 camera vertices in 'scene container space' 00320 * 00321 * @note 00322 * - This vertices can for instance be used to check the camera frustum visibility 00323 */ 00324 PLS_API const PLCore::Array<PLMath::Vector3> &GetFrustumVertices(const PLMath::Rectangle &cViewport); 00325 00326 /** 00327 * @brief 00328 * Gets the current camera viewport corners 00329 * 00330 * @param[out] vUpperRight 00331 * Will receive the upper/right corner 00332 * @param[out] vLowerRight 00333 * Will receive the lower/right corner 00334 * @param[out] vLowerLeft 00335 * Will receive the lower/left corner 00336 * @param[out] vUpperLeft 00337 * Will receive the upper/left corner 00338 * @param[in] bContainerSpace 00339 * Transform corners into container space? (else they are within local scene node space) 00340 * @param[in] fDistance 00341 * Distance from 0, use for example GetNearPlane() to get the viewport corners on the near plane 00342 * 00343 * @return 00344 * 'true' if all went fine, else 'false' (maybe no camera is set?) 00345 */ 00346 PLS_API bool GetViewportCorners(PLMath::Vector3 &vUpperRight, PLMath::Vector3 &vLowerRight, 00347 PLMath::Vector3 &vLowerLeft, PLMath::Vector3 &vUpperLeft, 00348 bool bContainerSpace, float fDistance); 00349 00350 00351 //[-------------------------------------------------------] 00352 //[ Protected definitions ] 00353 //[-------------------------------------------------------] 00354 protected: 00355 /** 00356 * @brief 00357 * Flags which hold internal camera information 00358 */ 00359 enum EInternalCameraFlags { 00360 RecalculateProjectionMatrix = 1<<0, /**< Recalculation of projection matrix required */ 00361 RecalculateViewMatrix = 1<<1, /**< Recalculation of view matrix required */ 00362 RecalculateFrustum = 1<<2, /**< Recalculation of frustum required */ 00363 RecalculateFrustumVertices = 1<<3 /**< Recalculation of frustum vertices required */ 00364 }; 00365 00366 00367 //[-------------------------------------------------------] 00368 //[ Private static data ] 00369 //[-------------------------------------------------------] 00370 private: 00371 // [TODO] Remove this 00372 static SNCamera *m_pCamera; /**< Current set camera, can be a null pointer */ 00373 00374 00375 //[-------------------------------------------------------] 00376 //[ Private functions ] 00377 //[-------------------------------------------------------] 00378 private: 00379 /** 00380 * @brief 00381 * Called when the scene node position or rotation changed 00382 */ 00383 void OnPositionRotation(); 00384 00385 /** 00386 * @brief 00387 * Calculates and returns the current view rotation 00388 * 00389 * @return 00390 * The current view rotation 00391 */ 00392 PLMath::Quaternion CalculateViewRotation() const; 00393 00394 00395 //[-------------------------------------------------------] 00396 //[ Private event handlers ] 00397 //[-------------------------------------------------------] 00398 private: 00399 PLCore::EventHandler<> EventHandlerPositionRotation; 00400 00401 00402 //[-------------------------------------------------------] 00403 //[ Private data ] 00404 //[-------------------------------------------------------] 00405 private: 00406 float m_fFOV; /**< Field of view in degree */ 00407 float m_fAspect; /**< Aspect factor */ 00408 float m_fZNear; /**< Near clipping plane */ 00409 float m_fZFar; /**< Far clipping plane */ 00410 PLCore::String m_sSceneRendererFilename; /**< Filename of the scene renderer to use, if empty the default scene renderer of the scene graph surface painter is used */ 00411 PLCore::uint8 m_nInternalCameraFlags; /**< Internal camera flags */ 00412 bool m_bAutoUpdate; /**< Update projection & view matrix and frustum automatically? */ 00413 PLMath::Matrix4x4 m_mProj; /**< Current projection matrix */ 00414 PLMath::Quaternion m_qViewRotationOffset; /**< View rotation offset */ 00415 PLMath::Matrix3x4 m_mView; /**< Current view matrix */ 00416 PLMath::Frustum m_cFrustum; /**< Current frustum */ 00417 PLCore::Array<PLMath::Vector3> m_cFrustumVertices; /**< Current frustum vertices */ 00418 PLCore::uint32 m_nViewportWidth; /**< Current viewport width */ 00419 PLCore::uint32 m_nViewportHeight; /**< Current viewport height */ 00420 SceneRendererHandler *m_pSceneRendererHandler; /**< Scene renderer handler, always valid! */ 00421 00422 00423 //[-------------------------------------------------------] 00424 //[ Public virtual SceneNode functions ] 00425 //[-------------------------------------------------------] 00426 public: 00427 PLS_API virtual void DrawDebug(PLRenderer::Renderer &cRenderer, const VisNode *pVisNode = nullptr) override; 00428 00429 00430 //[-------------------------------------------------------] 00431 //[ Protected virtual SceneNode functions ] 00432 //[-------------------------------------------------------] 00433 protected: 00434 PLS_API virtual void UpdateAABoundingBox() override; 00435 00436 00437 }; 00438 00439 00440 //[-------------------------------------------------------] 00441 //[ Namespace ] 00442 //[-------------------------------------------------------] 00443 } // PLScene 00444 00445 00446 #endif // __PLSCENE_CAMERA_H__
|