PixelLightAPI
.
|
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__
|