PixelLightAPI  .
MeshLODLevel.h
Go to the documentation of this file.
00001 /*********************************************************\
00002  *  File: MeshLODLevel.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 __PLMESH_MESH_LODLEVEL_H__
00024 #define __PLMESH_MESH_LODLEVEL_H__
00025 #pragma once
00026 
00027 
00028 //[-------------------------------------------------------]
00029 //[ Includes                                              ]
00030 //[-------------------------------------------------------]
00031 #include <PLCore/Container/Array.h>
00032 #include "PLMesh/Mesh.h"
00033 #include "PLMesh/Geometry.h"
00034 
00035 
00036 //[-------------------------------------------------------]
00037 //[ Forward declarations                                  ]
00038 //[-------------------------------------------------------]
00039 namespace PLRenderer {
00040     class IndexBuffer;
00041     class VertexBuffer;
00042 }
00043 namespace PLMesh {
00044     class MeshOctree;
00045 }
00046 
00047 
00048 //[-------------------------------------------------------]
00049 //[ Namespace                                             ]
00050 //[-------------------------------------------------------]
00051 namespace PLMesh {
00052 
00053 
00054 //[-------------------------------------------------------]
00055 //[ Classes                                               ]
00056 //[-------------------------------------------------------]
00057 /**
00058 *  @brief
00059 *    Mesh LOD level
00060 *
00061 *  @remark
00062 *    A LOD level for a mesh can redefine one or more of the mesh's base data
00063 *    Index data (indices into the vertex data)
00064 *    Geometries (that structure the index data in different parts)
00065 */
00066 class MeshLODLevel {
00067 
00068 
00069     //[-------------------------------------------------------]
00070     //[ Public functions                                      ]
00071     //[-------------------------------------------------------]
00072     public:
00073         //[-------------------------------------------------------]
00074         //[ Main functions                                        ]
00075         //[-------------------------------------------------------]
00076         /**
00077         *  @brief
00078         *    Constructor
00079         *
00080         *  @param[in] pMesh
00081         *    Pointer to the owner mesh, can be a null pointer
00082         */
00083         PLMESH_API MeshLODLevel(Mesh *pMesh = nullptr);
00084 
00085         /**
00086         *  @brief
00087         *    Destructor
00088         */
00089         PLMESH_API ~MeshLODLevel();
00090 
00091         /**
00092         *  @brief
00093         *    Returns the mesh the LOD level belongs to
00094         *
00095         *  @return
00096         *    Pointer to the owner mesh, can be a null pointer
00097         */
00098         PLMESH_API Mesh *GetMesh() const;
00099 
00100         /**
00101         *  @brief
00102         *    Sets the mesh the LOD level belongs to
00103         *
00104         *  @param[in] pMesh
00105         *    Pointer to the owner mesh, can be a null pointer
00106         */
00107         PLMESH_API void SetMesh(Mesh *pMesh = nullptr);
00108 
00109         /**
00110         *  @brief
00111         *    Returns the distance for using this LOD level
00112         *
00113         *  @return
00114         *    Distance for the LOD level
00115         */
00116         PLMESH_API float GetLODDistance() const;
00117 
00118         /**
00119         *  @brief
00120         *    Sets the distance for using this LOD level
00121         *
00122         *  @param[in] fDistance
00123         *    Distance for the LOD level
00124         */
00125         PLMESH_API void SetLODDistance(float fDistance = 0.0f);
00126 
00127         /**
00128         *  @brief
00129         *    Copy operator
00130         *
00131         *  @param[in] cSource
00132         *    Source to copy from
00133         *
00134         *  @return
00135         *    Reference to this instance
00136         */
00137         PLMESH_API MeshLODLevel &operator =(const MeshLODLevel &cSource);
00138 
00139         //[-------------------------------------------------------]
00140         //[ Index buffer functions                                ]
00141         //[-------------------------------------------------------]
00142         /**
00143         *  @brief
00144         *    Clears the index buffer for this LOD level
00145         */
00146         PLMESH_API void ClearIndexBuffer();
00147 
00148         /**
00149         *  @brief
00150         *    Creates the index buffer for this LOD level
00151         *
00152         *  @note
00153         *    - If you don't want to overwrite the mesh's index buffer
00154         *      (if the LOD level only alters the vertex buffers or geometries),
00155         *      you don't have to call this function. In this case
00156         *      the meshes standard index buffer will be used.
00157         */
00158         PLMESH_API void CreateIndexBuffer();
00159 
00160         /**
00161         *  @brief
00162         *    Returns the index buffer for this LOD level
00163         *
00164         *  @return
00165         *    The LOD level's index buffer, can be a null pointer
00166         */
00167         PLMESH_API PLRenderer::IndexBuffer *GetIndexBuffer() const;
00168 
00169         //[-------------------------------------------------------]
00170         //[ Geometry functions                                    ]
00171         //[-------------------------------------------------------]
00172         /**
00173         *  @brief
00174         *    Returns the total number of LOD level triangles
00175         *
00176         *  @return
00177         *    Total number of LOD level triangles
00178         */
00179         PLMESH_API PLCore::uint32 GetNumOfTriangles() const;
00180 
00181         /**
00182         *  @brief
00183         *    Clears the geometries for this LOD level
00184         */
00185         PLMESH_API void ClearGeometries();
00186 
00187         /**
00188         *  @brief
00189         *    Creates the geometries for this LOD level
00190         *
00191         *  @note
00192         *     - If you don't want to overwrite the mesh's geometries
00193         *       (if the LOD level only alters the index or vertex buffers),
00194         *       you don't have to call this function. In this case
00195         *       the meshes standard geometries will be used.
00196         */
00197         PLMESH_API void CreateGeometries();
00198 
00199         /**
00200         *  @brief
00201         *    Gets the geometries of this LOD level
00202         *
00203         *  @return
00204         *    List of geometries, can be a null pointer
00205         */
00206         PLMESH_API PLCore::Array<Geometry> *GetGeometries() const;
00207 
00208         //[-------------------------------------------------------]
00209         //[ Visibility functions                                  ]
00210         //[-------------------------------------------------------]
00211         /**
00212         *  @brief
00213         *    Creates the LOD level octree
00214         *
00215         *  @param[in]  nSubdivide
00216         *    Octree subdivide
00217         *  @param[in]  nMinGeometries
00218         *    Minimum number of geometries per octree
00219         *  @param[out] plstOctreeIDList
00220         *    Will optionally store a list of octrees each geometry is on, can be a null pointer
00221         *
00222         *  @return
00223         *    'true' if all went fine, else 'false'
00224         *
00225         *  @note
00226         *    - This function doesn't manipulate the geometries etc. Therefore an octree
00227         *      can only be efficient if there are different smaller geometries because
00228         *      the octree later checks which geometries are currently visible!
00229         *    - The tool function GenerateOctreeGeometries() will split up the geometries
00230         *      in octree friendly parts
00231         */
00232         PLMESH_API bool CreateOctree(PLCore::uint32 nSubdivide = 1, PLCore::uint32 nMinGeometries = 10,
00233                                      PLCore::Array<PLCore::Array<PLCore::uint32>*> *plstOctreeIDList = nullptr);
00234 
00235         /**
00236         *  @brief
00237         *    Destroys the LOD level octree
00238         */
00239         PLMESH_API void DestroyOctree();
00240 
00241         /**
00242         *  @brief
00243         *    Returns the LOD level octree
00244         *
00245         *  @return
00246         *    LOD level octree, a null pointer if there's no octree
00247         *
00248         *  @note
00249         *    - The octree is used for fast visibility and collision determination
00250         */
00251         PLMESH_API MeshOctree *GetOctree() const;
00252 
00253         //[-------------------------------------------------------]
00254         //[ Tool functions                                        ]
00255         //[-------------------------------------------------------]
00256         /**
00257         *  @brief
00258         *    Builds the connectivity information
00259         *
00260         *  @note
00261         *    - This function calls BuildTriangleList() and BuildEdgeList()
00262         */
00263         PLMESH_API void BuildConnectivity();
00264 
00265         /**
00266         *  @brief
00267         *    Builds the current triangle list
00268         *
00269         *  @note
00270         *    - The triangle list must be updated after manipulating geometries!
00271         */
00272         PLMESH_API void BuildTriangleList();
00273 
00274         /**
00275         *  @brief
00276         *    Gets the triangle list
00277         *
00278         *  @return
00279         *    Triangle list
00280         *
00281         *  @see
00282         *    - BuildTriangleList()
00283         */
00284         PLMESH_API PLCore::Array<MeshTriangle> &GetTriangleList();
00285 
00286         /**
00287         *  @brief
00288         *    Builds the current edge list
00289         *
00290         *  @note
00291         *    - The edge list must be updated after manipulating geometries!
00292         *    - The triangle list must be build before the edge list can be constructed!
00293         *      (see BuildTriangleList())
00294         */
00295         PLMESH_API void BuildEdgeList();
00296 
00297         /**
00298         *  @brief
00299         *    Gets the edge list
00300         *
00301         *  @return
00302         *    Edge list
00303         *
00304         *  @see
00305         *    - BuildEdgeList()
00306         */
00307         PLMESH_API PLCore::Array<MeshEdge> &GetEdgeList();
00308 
00309         /**
00310         *  @brief
00311         *    Gets a triangle of a geometry
00312         *
00313         *  @param[in]  nGeometry
00314         *    Geometry ID
00315         *  @param[in]  nIndex
00316         *    Triangle index
00317         *  @param[out] nVertex1
00318         *    Will receive the first triangle vertex index
00319         *  @param[out] nVertex2
00320         *    Will receive the second triangle vertex index
00321         *  @param[out] nVertex3
00322         *    Will receive the third triangle vertex index
00323         *
00324         *  @return
00325         *    'true' if all went fine, else 'false'
00326         *
00327         *  @note
00328         *    - When requesting many triangle vertices you should lock the index buffer
00329         *      using GetIndexBuffer() for more performance by self!
00330         *    - GetTrianglePlaneList() is faster because it is using a precalculated triangle
00331         *      list
00332         */
00333         PLMESH_API bool GetTriangle(PLCore::uint32 nGeometry, PLCore::uint32 nIndex, PLCore::uint32 &nVertex1, PLCore::uint32 &nVertex2, PLCore::uint32 &nVertex3) const;
00334 
00335         /**
00336         *  @brief
00337         *    Splits up geometries to geometries of single triangles
00338         *
00339         *  @param[in] bSingleGeometries
00340         *    One geometry per triangle? Recommended if octrees should be build but
00341         *    not good when preparing the mesh for optimize!
00342         *  @param[in] pSplit
00343         *    Optional index list of the geometries to split, if a null pointer all geometries will be split
00344         *  @param[in] nSplitNumber
00345         *    If pSplit isn't a null pointer this indicates the number of geometries to split
00346         *
00347         *  @return
00348         *    'true' if all went fine, else 'false'
00349         *
00350         *  @note
00351         *    - If there was an octree it will be destroyed!
00352         */
00353         PLMESH_API bool SplitGeometries(bool bSingleGeometries = false, PLCore::uint32 *pSplit = nullptr, PLCore::uint32 nSplitNumber = 0);
00354 
00355         /**
00356         *  @brief
00357         *    Joins geometries with the same properties to one single geometry
00358         *
00359         *  @param[in] pJoin
00360         *    Optional index list of the geometries to join, if a null pointer all geometries will be joined
00361         *  @param[in] nJoinNumber
00362         *    If pJoin isn't a null pointer, this indicates the number of geometries to join
00363         *
00364         *  @return
00365         *    'true' if all went fine, else 'false'
00366         *
00367         *  @note
00368         *    - If there was an octree it will be destroyed!
00369         *    - Geometries of the primitive type PLRenderer::Primitive::LineStrip,
00370         *      PLRenderer::Primitive::TriangleStrip and PLRenderer::Primitive::TriangleFan can't be joined!
00371         */
00372         PLMESH_API bool JoinGeometries(PLCore::uint32 *pJoin = nullptr, PLCore::uint32 nJoinNumber = 0);
00373 
00374         /**
00375         *  @brief
00376         *    Optimizes the geometries for an octree
00377         *
00378         *  @param[in] nSubdivide
00379         *    Octree subdivide
00380         *  @param[in] nMinGeometries
00381         *    Minimum number of geometries per octree
00382         *
00383         *  @return
00384         *    'true' if all went fine, else 'false'
00385         *
00386         *  @note
00387         *    - If there was an octree it will be destroyed!
00388         *    - The octree itself can be created using CreateOctree()
00389         *    - Its recommended to use GenerateStrips() to optimize the new
00390         *      geometries!
00391         *    - This may take some time so don't do it during runtime!
00392         */
00393         PLMESH_API bool GenerateOctreeGeometries(PLCore::uint32 nSubdivide = 1, PLCore::uint32 nMinGeometries = 10);
00394 
00395         /**
00396         *  @brief
00397         *    Optimizes the geometries using triangle strips
00398         *
00399         *  @param[in] nVertexCacheSize
00400         *    Sets the cache size which the stripfier uses to optimize the data.
00401         *    Controls the length of the generated individual strips.
00402         *    CacheSize should be 0 to disable the cache optimizer, 10 for a GeForce 256
00403         *    or a GeForce 2, 16 or 18 for a GeForce 3 or a GeForce 4.
00404         *    Play a bit with this setting to find the best value for your 3D card.
00405         *  @param[in] nMinStripLength
00406         *    Sets the minimum acceptable size for a strip, in triangles.
00407         *    All strips generated which are shorter than this will be thrown into
00408         *    one big, separate list.
00409         *
00410         *  @return
00411         *    'true' if all went fine, else 'false'
00412         *
00413         *  @note
00414         *    - This may take some time so don't do it during runtime!
00415         *    - Ensure that there are ONLY geometries of triangles, (PLRenderer::Primitive::TriangleList)
00416         *      else this function will not work! (see SplitGeometries())
00417         */
00418         PLMESH_API bool GenerateStrips(PLCore::uint32 nVertexCacheSize = 18, PLCore::uint32 nMinStripLength = 3);
00419 
00420         /**
00421         *  @brief
00422         *    Calculates the LOD level bounding box
00423         *
00424         *  @param[in]  lstGeometries
00425         *    The LOD level geometries to use
00426         *  @param[in]  cVertexBuffer
00427         *    Vertex buffer to use
00428         *  @param[out] vMinPos
00429         *    Will receive the minimum bounding box position
00430         *  @param[out] vMaxPos
00431         *    Will receive the maximum bounding box position
00432         *
00433         *  @return
00434         *    'true' if all went fine, else 'false'
00435         */
00436         PLMESH_API bool CalculateBoundingBox(const PLCore::Array<const Geometry*> &lstGeometries, PLRenderer::VertexBuffer &cVertexBuffer, PLMath::Vector3 &vMinPos, PLMath::Vector3 &vMaxPos) const;
00437 
00438         /**
00439         *  @brief
00440         *    Calculates the LOD level bounding sphere
00441         *
00442         *  @param[in]  lstGeometries
00443         *    The LOD level geometries to use
00444         *  @param[in]  cVertexBuffer
00445         *    Vertex buffer to use
00446         *  @param[out] vPos
00447         *    Will receive the bounding sphere position
00448         *  @param[out] fRadius
00449         *    Will receive the bounding sphere radius
00450         *
00451         *  @return
00452         *    'true' if all went fine, else 'false'
00453         */
00454         PLMESH_API bool CalculateBoundingSphere(const PLCore::Array<const Geometry*> &lstGeometries, PLRenderer::VertexBuffer &cVertexBuffer, PLMath::Vector3 &vPos, float &fRadius) const;
00455 
00456 
00457     //[-------------------------------------------------------]
00458     //[ Private data                                          ]
00459     //[-------------------------------------------------------]
00460     private:
00461         // Internal data
00462         Mesh *m_pMesh;  /**< Owner mesh, can be a null pointer */
00463 
00464         // LOD data
00465         float m_fDistance;  /**< LOD distance */
00466 
00467         // Overwritten data
00468         PLRenderer::IndexBuffer *m_pIndexBuffer;    /**< Index buffer, can be a null pointer */
00469         PLCore::Array<Geometry> *m_plstGeometries;  /**< Geometries, can be a null pointer */
00470 
00471         // Visibility
00472         MeshOctree *m_pOctree;  /**< Octree for geometry visibility determination, can be a null pointer */
00473 
00474         // Precalculated data
00475         PLCore::Array<MeshTriangle> m_lstTriangles; /**< List of triangles */
00476         PLCore::Array<MeshEdge>     m_lstEdges;     /**< List of edges */
00477 
00478 
00479 };
00480 
00481 
00482 //[-------------------------------------------------------]
00483 //[ Namespace                                             ]
00484 //[-------------------------------------------------------]
00485 } // PLMesh
00486 
00487 
00488 #endif // __PLMESH_MESH_LODLEVEL_H__ 


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