PixelLightAPI  .
GMMSurface.h
Go to the documentation of this file.
00001 /*********************************************************\
00002  *  File: GMMSurface.h                                   *
00003  *
00004  *  Copyright (C) 2002-2012 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_SCENENODE_GMMSURFACE_H__
00024 #define __PLSCENE_SCENENODE_GMMSURFACE_H__
00025 #pragma once
00026 
00027 
00028 //[-------------------------------------------------------]
00029 //[ Includes                                              ]
00030 //[-------------------------------------------------------]
00031 #include <PLMath/Quadtree.h>
00032 #include "PLScene/PLScene.h"
00033 
00034 
00035 //[-------------------------------------------------------]
00036 //[ Forward declarations                                  ]
00037 //[-------------------------------------------------------]
00038 namespace PLRenderer {
00039     class Texture;
00040     class Renderer;
00041     class VertexBuffer;
00042     class TextureHandler;
00043     class MaterialHandler;
00044 }
00045 namespace PLScene {
00046     class GMMSurfacePatch;
00047     class GMMSurfaceLevel;
00048 }
00049 
00050 
00051 //[-------------------------------------------------------]
00052 //[ Namespace                                             ]
00053 //[-------------------------------------------------------]
00054 namespace PLScene {
00055 
00056 
00057 //[-------------------------------------------------------]
00058 //[ Classes                                               ]
00059 //[-------------------------------------------------------]
00060 /**
00061 *  @brief
00062 *    Geometrically MipMapping surface
00063 *
00064 *  @remarks
00065 *    This surface takes a hight map and displays it with an optimal level of detail
00066 *    using height variance and distance to camera.
00067 *
00068 *  @note
00069 *    - For optimal frustum culling a quadtree is used
00070 *    - The standard usage of this surface type is a terrain
00071 *    - Similar to the ROAM surface but this technique is quite better for modern hardware
00072 */
00073 class GMMSurface {
00074 
00075 
00076     //[-------------------------------------------------------]
00077     //[ Public structures                                     ]
00078     //[-------------------------------------------------------]
00079     public:
00080         /**
00081         *  @brief
00082         *    GMM surface vertex
00083         */
00084         struct Vertex {
00085             float x, y, z;  /**< Position */
00086             float u, v;     /**< Texture coordinate */
00087         };
00088 
00089 
00090     //[-------------------------------------------------------]
00091     //[ Public functions                                      ]
00092     //[-------------------------------------------------------]
00093     public:
00094         /**
00095         *  @brief
00096         *    Constructor
00097         *
00098         *  @param[in] cRenderer
00099         *    Renderer to use
00100         */
00101         PLS_API GMMSurface(PLRenderer::Renderer &cRenderer);
00102 
00103         /**
00104         *  @brief
00105         *    Destructor
00106         */
00107         PLS_API ~GMMSurface();
00108 
00109         /**
00110         *  @brief
00111         *    Creates the GMM surface
00112         *
00113         *  @param[in] nHeightMapSize
00114         *    Height map size
00115         *  @param[in] fHeightMap
00116         *    Reference to the height map
00117         *  @param[in] nPatchSize
00118         *    Patch size
00119         *  @param[in] nGeoMipMaps
00120         *    Number of geometrically mip maps, -1 = automatic
00121         *
00122         *  @return
00123         *    'true' if all went fine, else 'false'
00124         *
00125         *  @note
00126         *    - The reference to the height map is used directly, short the reference must
00127         *      be valid as long as the GMM surface is used!!
00128         *    - The GMM takes place in the single patches of the surface further they
00129         *      are used for frustum culling and each patch could have another material
00130         */
00131         PLS_API bool Create(PLCore::uint32 nHeightMapSize, float fHeightMap[], PLCore::uint32 nPatchSize = 16, int nGeoMipMaps = -1);
00132 
00133         /**
00134         *  @brief
00135         *    Kills the GMM surface
00136         */
00137         PLS_API void Destroy();
00138 
00139         /**
00140         *  @brief
00141         *    Returns the viewer position
00142         *
00143         *  @return
00144         *    Viewer position
00145         */
00146         PLS_API const PLMath::Vector3 &GetViewerPos() const;
00147 
00148         /**
00149         *  @brief
00150         *    Sets the viewer position
00151         *
00152         *  @param[in] vPos
00153         *    Viewer position
00154         */
00155         PLS_API void SetViewerPos(const PLMath::Vector3 &vPos);
00156 
00157         /**
00158         *  @brief
00159         *    Returns the size of the height map
00160         *
00161         *  @return
00162         *    The size of the height map
00163         */
00164         PLS_API PLCore::uint32 GetHeightMapSize() const;
00165 
00166         /**
00167         *  @brief
00168         *    Returns a pointer to the height map
00169         *
00170         *  @return
00171         *    Pointer to the height map, can be a null pointer
00172         */
00173         PLS_API const float *GetHeightMap() const;
00174 
00175         /**
00176         *  @brief
00177         *    Returns the number of surface vertices
00178         *
00179         *  @return
00180         *    Number of surface vertices
00181         */
00182         PLS_API PLCore::uint32 GetVertices() const;
00183 
00184         /**
00185         *  @brief
00186         *    Returns a pointer to a surface vertex
00187         *
00188         *  @param[in] nID
00189         *    ID of the vertex
00190         *
00191         *  @return
00192         *    Pointer to a surface vertex, a null pointer if there was an error
00193         */
00194         PLS_API Vertex *GetVertex(PLCore::uint32 nID = 0) const;
00195 
00196         /**
00197         *  @brief
00198         *    Returns the height of a height map coordinate
00199         *
00200         *  @param[in] nX
00201         *    Height map x coordinate
00202         *  @param[in] nY
00203         *    Height map y coordinate
00204         *
00205         *  @return
00206         *    The height of a height map coordinate
00207         */
00208         PLS_API float GetHeight(PLCore::uint32 nX, PLCore::uint32 nY) const;
00209 
00210         /**
00211         *  @brief
00212         *    Sets the height of a height map coordinate
00213         *
00214         *  @param[in] nX
00215         *    Height map x coordinate
00216         *  @param[in] nY
00217         *    Height map y coordinate
00218         *  @param[in] fHeight
00219         *    New height at the coordinate
00220         *
00221         *  @return
00222         *    'true' if all went fine, else 'false'
00223         *
00224         *  @note
00225         *    - If a height value in the height map is manipulated the patch using this
00226         *      coordinate must be recalculated during the next GMM surface update
00227         */
00228         PLS_API bool SetHeight(PLCore::uint32 nX, PLCore::uint32 nY, float fHeight = 0);
00229 
00230         /**
00231         *  @brief
00232         *    Returns the size of a patch
00233         *
00234         *  @return
00235         *    Size of a patch
00236         */
00237         PLS_API PLCore::uint32 GetPatchSize() const;
00238 
00239         /**
00240         *  @brief
00241         *    Returns the number of patches per column/row
00242         *
00243         *  @return
00244         *    Number of patches per column/row
00245         */
00246         PLS_API PLCore::uint32 GetXYPatches() const;
00247 
00248         /**
00249         *  @brief
00250         *    Returns the total number of patches in the GMM surface
00251         *
00252         *  @return
00253         *    The total number of patches in the GMM surface
00254         */
00255         PLS_API PLCore::uint32 GetPatches() const;
00256 
00257         /**
00258         *  @brief
00259         *    Returns a pointer to the patch with the given ID
00260         *
00261         *  @param[in] nID
00262         *    ID of the patch which should be returned
00263         *
00264         *  @return
00265         *    A pointer to the patch with the given ID, a null pointer if there was an error
00266         */
00267         PLS_API GMMSurfacePatch *GetPatch(PLCore::uint32 nID) const;
00268 
00269         /**
00270         *  @brief
00271         *    Returns the number of geometrically mip maps
00272         *
00273         *  @return
00274         *    Number of geometrically mip maps
00275         */
00276         PLS_API PLCore::uint32 GetGeoMipMaps() const;
00277 
00278         /**
00279         *  @brief
00280         *    Sets the neighbour GMM surfaces
00281         *
00282         *  @param[in] pLeft
00283         *    The left neighbour GMM surface
00284         *  @param[in] pTop
00285         *    The top neighbour GMM surface
00286         *  @param[in] pRight
00287         *    The right neighbour GMM surface
00288         *  @param[in] pBottom
00289         *    The bottom neighbour GMM surface
00290         */
00291         PLS_API void SetNeighbours(GMMSurface *pLeft = nullptr, GMMSurface *pTop    = nullptr,
00292                                   GMMSurface *pRight = nullptr, GMMSurface *pBottom = nullptr);
00293 
00294         /**
00295         *  @brief
00296         *    Returns the surface material handler
00297         *
00298         *  @return
00299         *    Surface material handler
00300         */
00301         PLS_API PLRenderer::MaterialHandler &GetMaterialHandler();
00302 
00303         /**
00304         *  @brief
00305         *    Returns the GMM surface quadtree
00306         *
00307         *  @return
00308         *    GMM surface quadtree
00309         */
00310         PLS_API PLMath::Quadtree &GetQuadtree();
00311 
00312         /**
00313         *  @brief
00314         *    Updates the GMM surface
00315         *
00316         *  @note
00317         *    - Must be done before the GMM surface is drawn!! (updates detail etc.)
00318         */
00319         PLS_API void Update();
00320 
00321         /**
00322         *  @brief
00323         *    Draws the GMM surface
00324         *
00325         *  @note
00326         *    - The GMM surface must be updated before it's drawn! (updates detail etc.)
00327         */
00328         PLS_API void Draw() const;
00329 
00330 
00331     //[-------------------------------------------------------]
00332     //[ Private functions                                     ]
00333     //[-------------------------------------------------------]
00334     private:
00335         /**
00336         *  @brief
00337         *    Draws a patch
00338         *
00339         *  @param[in] cPatch
00340         *    Patch to draw
00341         */
00342         void DrawPatch(GMMSurfacePatch &cPatch) const;
00343 
00344         /**
00345         *  @brief
00346         *    Initializes the GMM surface
00347         */
00348         void Init();
00349 
00350 
00351     //[-------------------------------------------------------]
00352     //[ Private definitions                                   ]
00353     //[-------------------------------------------------------]
00354     private:
00355         /**
00356         *  @brief
00357         *    Side
00358         */
00359         enum ESide {
00360             Right,  /**< Right side */
00361             Top,    /**< Top side */
00362             Left,   /**< Left side */
00363             Bottom  /**< Bottom side */
00364         };
00365 
00366 
00367     //[-------------------------------------------------------]
00368     //[ Private data                                          ]
00369     //[-------------------------------------------------------]
00370     private:
00371         // General
00372         PLRenderer::Renderer         *m_pRenderer;          /**< Used renderer (always valid!) */
00373         PLMath::Vector3               m_vViewerPos;         /**< Viewer position */
00374         GMMSurface                   *m_pNeighbour[4];      /**< Neighbour GMM surfaces, can be a null pointer */
00375         PLCore::uint32                m_nVertices;          /**< Number of surface vertices */
00376         PLRenderer::VertexBuffer     *m_pVertexBuffer;      /**< Vertex buffer, can be a null pointer */
00377         Vertex                       *m_pVertex;            /**< Surface vertices, can be a null pointer */
00378         PLRenderer::MaterialHandler  *m_pMaterialHandler;   /**< Surface material (always valid!) */
00379 
00380         // Height map
00381         PLCore::uint32   m_nHeightMapSize;  /**< Height map size */
00382         float           *m_pfHeightMap;     /**< Height map data, can be a null pointer */
00383 
00384         // Patches
00385         PLCore::uint32    m_nPatchSize, /**< Patch size */
00386                           m_nXYPatches, /**< Patches per column / row */
00387                           m_nPatches;   /**< Total number of patches */
00388         GMMSurfacePatch **m_ppPatches;  /**< The patches, can be a null pointer */
00389 
00390         // Levels
00391         PLCore::uint32      m_nGeoMipMaps;  /**< Number of geometrically mip maps */
00392         GMMSurfaceLevel   **m_ppLevels;     /**< Levels, can be a null pointer */
00393 
00394         // Quadtree
00395         PLMath::Quadtree m_cQuadtree;   /**< Quadtree for frustum culling */
00396 
00397 
00398 };
00399 
00400 
00401 //[-------------------------------------------------------]
00402 //[ Namespace                                             ]
00403 //[-------------------------------------------------------]
00404 } // PLScene
00405 
00406 
00407 #endif // __PLSCENE_SCENENODE_GMMSURFACE_H__


PixelLight PixelLight 0.9.11-R1
Copyright (C) 2002-2012 by The PixelLight Team
Last modified Thu Feb 23 2012 14:08:56
The content of this PixelLight document is published under the
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported