PixelLightAPI  .
SNCamera.h
Go to the documentation of this file.
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__


PixelLight PixelLight 0.9.10-R1
Copyright (C) 2002-2011 by The PixelLight Team
Last modified Fri Dec 23 2011 15:51:02
The content of this PixelLight document is published under the
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported