PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: Mesh.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_H__ 00024 #define __PLMESH_MESH_H__ 00025 #pragma once 00026 00027 00028 //[-------------------------------------------------------] 00029 //[ Includes ] 00030 //[-------------------------------------------------------] 00031 #include <PLCore/Container/Resource.h> 00032 #include <PLMath/Vector3.h> 00033 #include "PLMesh/Weight.h" 00034 #include "PLMesh/AnchorPoint.h" 00035 #include "PLMesh/VertexWeights.h" 00036 #include "PLMesh/MorphTargetAni.h" 00037 00038 00039 //[-------------------------------------------------------] 00040 //[ Forward declarations ] 00041 //[-------------------------------------------------------] 00042 namespace PLRenderer { 00043 class Renderer; 00044 class Material; 00045 class MaterialHandler; 00046 } 00047 namespace PLMesh { 00048 class Skeleton; 00049 class MeshManager; 00050 class MeshLODLevel; 00051 class MeshMorphTarget; 00052 class SkeletonHandler; 00053 } 00054 00055 00056 //[-------------------------------------------------------] 00057 //[ Namespace ] 00058 //[-------------------------------------------------------] 00059 namespace PLMesh { 00060 00061 00062 //[-------------------------------------------------------] 00063 //[ Classes ] 00064 //[-------------------------------------------------------] 00065 /** 00066 * @brief 00067 * Mesh triangle 00068 */ 00069 class MeshTriangle { 00070 public: 00071 PLCore::uint32 nGeometry; /**< Index of the geometry this triangle is in */ 00072 PLCore::uint32 nVertex[3]; /**< The three vertex indices */ 00073 int nNeighbour[3]; /**< Neighbor triangles */ 00074 00075 PLMESH_API MeshTriangle &operator =(const MeshTriangle &cSource); 00076 PLMESH_API bool operator ==(const MeshTriangle &cMeshTriangle) const; 00077 }; 00078 00079 /** 00080 * @brief 00081 * Mesh edge 00082 */ 00083 class MeshEdge { 00084 public: 00085 PLCore::uint32 nVertex[2]; /**< The two edge vertex indices */ 00086 PLCore::uint32 nTriangle[2]; /**< The two edge triangles */ 00087 00088 PLMESH_API MeshEdge &operator =(const MeshEdge &cSource); 00089 PLMESH_API bool operator ==(const MeshEdge &cMeshEdge) const; 00090 }; 00091 00092 /** 00093 * @brief 00094 * Mesh class 00095 * 00096 * @remarks 00097 * A mesh defining a 3D mesh consists of several information:\n 00098 * Animations (list of predefined animations)\n 00099 * Anchor points (anchor points are in fact a kind of index to a vertex)\n 00100 * Morph targets (that contains the vertex data for every frame)\n 00101 * LOD levels (each of which can define the geometries and/or index data)\n 00102 * Skeleton (that defines a hierarchical structure on the mesh)\n 00103 * Materials (list of materials used by the mesh) 00104 */ 00105 class Mesh : public PLCore::Resource<Mesh> { 00106 00107 00108 //[-------------------------------------------------------] 00109 //[ Friends ] 00110 //[-------------------------------------------------------] 00111 friend class MeshManager; 00112 friend class MeshMorphTarget; 00113 00114 00115 //[-------------------------------------------------------] 00116 //[ Public definitions ] 00117 //[-------------------------------------------------------] 00118 public: 00119 /** 00120 * @brief 00121 * Mesh draw flags 00122 */ 00123 enum EFlags { 00124 DrawVertices = 1<<0, /**< Draw vertices */ 00125 DrawNormals = 1<<1, /**< Draw normals */ 00126 DrawOctree = 1<<2 /**< Draw (optional) octree */ 00127 }; 00128 00129 00130 //[-------------------------------------------------------] 00131 //[ Public functions ] 00132 //[-------------------------------------------------------] 00133 public: 00134 //[-------------------------------------------------------] 00135 //[ Main functions ] 00136 //[-------------------------------------------------------] 00137 /** 00138 * @brief 00139 * Destructor 00140 */ 00141 PLMESH_API virtual ~Mesh(); 00142 00143 /** 00144 * @brief 00145 * Returns the owner mesh manager 00146 * 00147 * @return 00148 * Pointer to the owner mesh manager, a null pointer on error 00149 */ 00150 PLMESH_API MeshManager *GetMeshManager() const; 00151 00152 /** 00153 * @brief 00154 * Returns the used renderer 00155 * 00156 * @return 00157 * Pointer to the renderer the mesh uses, can be a null pointer 00158 */ 00159 PLMESH_API PLRenderer::Renderer *GetRenderer() const; 00160 00161 /** 00162 * @brief 00163 * Checks all LODs and returns the maximum number of vertices 00164 * 00165 * @return 00166 * Maximum number of vertices 00167 */ 00168 PLMESH_API PLCore::uint32 GetMaxNumOfVertices() const; 00169 00170 /** 00171 * @brief 00172 * Checks all LODs and returns the maximum number of geometries 00173 * 00174 * @return 00175 * Maximum number of geometries 00176 */ 00177 PLMESH_API PLCore::uint32 GetMaxNumOfGeometries() const; 00178 00179 /** 00180 * @brief 00181 * Checks all LODs and returns the maximum number of triangles 00182 * 00183 * @return 00184 * Maximum number of triangles 00185 */ 00186 PLMESH_API PLCore::uint32 GetMaxNumOfTriangles() const; 00187 00188 /** 00189 * @brief 00190 * Draws the mesh 00191 * 00192 * @param[in] mWorldViewProjection 00193 * World view projection matrix to use 00194 * @param[in] bBlend 00195 * Draw only mesh parts which use a blended material? 00196 * @param[in] nFlags 00197 * Draw flags (use EFlags) 00198 * @param[in] nLODLevel 00199 * Which LOD level to use 00200 * @param[in] nMorphTarget 00201 * Which morph target to use 00202 * @param[in] bUseMaterials 00203 * Use the mesh materials? If 'false' no material is bound. 00204 * 00205 * @note 00206 * - Use this function only if you know that there's only one special 00207 * usage of the mesh. (for instance you dynamically change it) 00208 * Normally you should use a mesh handler to handle the mesh 00209 */ 00210 PLMESH_API void Draw(const PLMath::Matrix4x4 &mWorldViewProjection, bool bBlend = false, PLCore::uint32 nFlags = 0, PLCore::uint32 nLODLevel = 0, 00211 PLCore::uint32 nMorphTarget = 0, bool bUseMaterials = true) const; 00212 00213 /** 00214 * @brief 00215 * Copy operator 00216 * 00217 * @param[in] cSource 00218 * Source to copy from 00219 * 00220 * @return 00221 * This mesh 00222 */ 00223 PLMESH_API Mesh &operator =(const Mesh &cSource); 00224 00225 //[-------------------------------------------------------] 00226 //[ Mesh data ] 00227 //[-------------------------------------------------------] 00228 /** 00229 * @brief 00230 * Returns the anchor point manager 00231 * 00232 * @return 00233 * The anchor point manager of the mesh 00234 * 00235 * @remarks 00236 * To add an anchor point to the manager you can e.g. do the following:\n 00237 * AnchorPoint *pAnchorPoint = new AnchorPoint("LeftHand", 0,\n 00238 * 99, &pMyMesh->GetAnchorPointManager()); 00239 */ 00240 PLMESH_API AnchorPointManager &GetAnchorPointManager(); 00241 00242 //[-------------------------------------------------------] 00243 //[ Morph target functions ] 00244 //[-------------------------------------------------------] 00245 /** 00246 * @brief 00247 * Clears all morph targets 00248 */ 00249 PLMESH_API void ClearMorphTargets(); 00250 00251 /** 00252 * @brief 00253 * Returns the number of morph targets 00254 * 00255 * @return 00256 * Number of morph targets the mesh contains 00257 */ 00258 PLMESH_API PLCore::uint32 GetNumOfMorphTargets() const; 00259 00260 /** 00261 * @brief 00262 * Adds a new morph target 00263 * 00264 * @return 00265 * Pointer to the new morph target, a null pointer on error 00266 */ 00267 PLMESH_API MeshMorphTarget *AddMorphTarget(); 00268 00269 /** 00270 * @brief 00271 * Gets one of the mesh's morph targets by index 00272 * 00273 * @param[in] nMorphTarget 00274 * Number of the morph target to get 00275 * 00276 * @return 00277 * Pointer to the morph target, or a null pointer 00278 */ 00279 PLMESH_API MeshMorphTarget *GetMorphTarget(PLCore::uint32 nMorphTarget = 0) const; 00280 00281 /** 00282 * @brief 00283 * Gets one of the mesh's morph targets by name 00284 * 00285 * @param[in] sName 00286 * Name of the morph target to get 00287 * 00288 * @return 00289 * Pointer to the morph target, or a null pointer 00290 */ 00291 PLMESH_API MeshMorphTarget *GetMorphTarget(const PLCore::String &sName) const; 00292 00293 /** 00294 * @brief 00295 * Returns the index of a given morph target 00296 * 00297 * @param[in] sName 00298 * Name of the morph target the index should be returned 00299 * 00300 * @return 00301 * The index of the given morph target, < 0 if the morph target wasn't found 00302 */ 00303 PLMESH_API int GetMorphTargetIndex(const PLCore::String &sName) const; 00304 00305 /** 00306 * @brief 00307 * Returns the morph target animation manager 00308 * 00309 * @return 00310 * The morph target animation manager 00311 * 00312 * @remarks 00313 * To add an morph target animation to the manager you can e.g. do the following:\n 00314 * MorphTargetAni *pAnimation = new MorphTargetAni(&pMyMesh->GetMorphTargetAnimationManager()); 00315 */ 00316 PLMESH_API MorphTargetAniManager &GetMorphTargetAnimationManager(); 00317 00318 /** 00319 * @brief 00320 * Adds a morph target animation 00321 * 00322 * @param[in] sFilename 00323 * Morph target animation filename 00324 * 00325 * @return 00326 * 'true' if all went fine, else 'false' 00327 */ 00328 PLMESH_API bool AddMorphTargetAnimation(const PLCore::String &sFilename); 00329 00330 //[-------------------------------------------------------] 00331 //[ LOD functions ] 00332 //[-------------------------------------------------------] 00333 /** 00334 * @brief 00335 * Clears all LOD levels 00336 */ 00337 PLMESH_API void ClearLODLevels(); 00338 00339 /** 00340 * @brief 00341 * Returns the number of LOD levels 00342 * 00343 * @return 00344 * Number of LOD levels the mesh contains 00345 */ 00346 PLMESH_API PLCore::uint32 GetNumOfLODLevels() const; 00347 00348 /** 00349 * @brief 00350 * Adds a new LOD level 00351 * 00352 * @return 00353 * Pointer to the new LOD level, a null pointer on error 00354 */ 00355 PLMESH_API MeshLODLevel *AddLODLevel(); 00356 00357 /** 00358 * @brief 00359 * Gets one of the mesh's LOD levels 00360 * 00361 * @param[in] nLODLevel 00362 * Number of the LOD level to get 00363 * 00364 * @return 00365 * Pointer to the LOD level, or a null pointer 00366 */ 00367 PLMESH_API MeshLODLevel *GetLODLevel(PLCore::uint32 nLODLevel = 0) const; 00368 00369 //[-------------------------------------------------------] 00370 //[ Material functions ] 00371 //[-------------------------------------------------------] 00372 /** 00373 * @brief 00374 * Clears all materials 00375 */ 00376 PLMESH_API void ClearMaterials(); 00377 00378 /** 00379 * @brief 00380 * Returns the number of materials 00381 * 00382 * @return 00383 * Number of materials 00384 */ 00385 PLMESH_API PLCore::uint32 GetNumOfMaterials() const; 00386 00387 /** 00388 * @brief 00389 * Adds a new material 00390 * 00391 * @param[in] pMaterial 00392 * Material to add, if a null pointer, nothing happens 00393 * 00394 * @return 00395 * Pointer to the added material, a null pointer on error 00396 */ 00397 PLMESH_API PLRenderer::Material *AddMaterial(PLRenderer::Material *pMaterial); 00398 00399 /** 00400 * @brief 00401 * Deletes a material 00402 * 00403 * @param[in] nMaterial 00404 * Number of the material to delete 00405 * 00406 * @return 00407 * 'true' if all went fine else 'false' 00408 * 00409 * @note 00410 * - If the deleted material was used by a geometry the geometry 00411 * material index will be set to 0 00412 * - The material index of the geometries will automatically corrected 00413 * if the material index has changed 00414 */ 00415 PLMESH_API bool DeleteMaterial(PLCore::uint32 nMaterial); 00416 00417 /** 00418 * @brief 00419 * Returns the number of geometries using this material 00420 * 00421 * @param[in] nMaterial 00422 * Number of the material to check 00423 * 00424 * @return 00425 * Number of geometries using this material 00426 * 00427 * @note 00428 * - Use this function for instance to find unused materials in order to 00429 * delete them 00430 */ 00431 PLMESH_API PLCore::uint32 GetMaterialUsage(PLCore::uint32 nMaterial) const; 00432 00433 /** 00434 * @brief 00435 * Gets one of the mesh's materials 00436 * 00437 * @param[in] nMaterial 00438 * Number of the material to get 00439 * 00440 * @return 00441 * Pointer to the material, or a null pointer 00442 */ 00443 PLMESH_API PLRenderer::Material *GetMaterial(PLCore::uint32 nMaterial = 0) const; 00444 00445 /** 00446 * @brief 00447 * Sets one of the mesh's materials 00448 * 00449 * @param[in] nMaterial 00450 * Number of the material to set 00451 * @param[in] pMaterial 00452 * Pointer to the material to set, can be a null pointer 00453 * 00454 * @return 00455 * 'true' if all went fine, else 'false' 00456 */ 00457 PLMESH_API bool SetMaterial(PLCore::uint32 nMaterial, PLRenderer::Material *pMaterial); 00458 00459 //[-------------------------------------------------------] 00460 //[ Skeleton functions ] 00461 //[-------------------------------------------------------] 00462 /** 00463 * @brief 00464 * Clears the list of skeleton handlers 00465 * 00466 * @note 00467 * - The skeletons are managed by the global skeleton manager, the meshes only 00468 * can have a list of skeletons 'assigned' to them. This skeletons for instance 00469 * are saved/loaded directly within the mesh file. 00470 * - By default the mesh has no skeleton assigned to it 00471 * - The first skeleton is the base skeleton, all other are for instance 00472 * additional animations assigned with this mesh 00473 * - See MeshLODLevel::GetVertexWeights() 00474 */ 00475 PLMESH_API void ClearSkeletonHandlers(); 00476 00477 /** 00478 * @brief 00479 * Returns the list of skeleton handlers 00480 * 00481 * @return 00482 * The list of skeleton handlers 00483 * 00484 * @see 00485 * - ClearSkeletonHandlers() 00486 */ 00487 PLMESH_API PLCore::Array<SkeletonHandler*> &GetSkeletonHandlers(); 00488 00489 /** 00490 * @brief 00491 * Returns the weights array 00492 * 00493 * @return 00494 * Weights array 00495 * 00496 * @note 00497 * - The weights are optional, but required for mesh skinning 00498 */ 00499 PLMESH_API PLCore::Array<Weight> &GetWeights(); 00500 00501 /** 00502 * @brief 00503 * Returns the vertex weights array 00504 * 00505 * @return 00506 * Vertex weights array 00507 * 00508 * @note 00509 * - The number of vertices in this array should always be the same number 00510 * as the number of vertices within the vertex buffer of this LOD level! 00511 * (see MeshMorphTarget::GetVertexBuffer()) 00512 * - The vertex weights are optional, but required for mesh skinning 00513 */ 00514 PLMESH_API PLCore::Array<VertexWeights> &GetVertexWeights(); 00515 00516 //[-------------------------------------------------------] 00517 //[ Tool functions ] 00518 //[-------------------------------------------------------] 00519 /** 00520 * @brief 00521 * Builds the connectivity information of all LOD levels 00522 * 00523 * @note 00524 * - For more information have a look at MeshLODLevel::BuildConnectivity() 00525 */ 00526 PLMESH_API void BuildConnectivity(); 00527 00528 /** 00529 * @brief 00530 * Builds the current triangle planes of all morph targets 00531 * 00532 * @note 00533 * - For more information have a look at MeshMorphTarget::BuildTrianglePlaneList() 00534 */ 00535 PLMESH_API void BuildTrianglePlaneList(); 00536 00537 /** 00538 * @brief 00539 * Builds the LOD levels automatically 00540 * 00541 * @param[in] nNumLODLevels 00542 * Number of LOD levels to create (including the original) 00543 * 00544 * @return 00545 * 'true' if all went fine, else 'false' 00546 * 00547 * @note 00548 * - The first LOD level and morph target must exist already 00549 */ 00550 PLMESH_API bool BuildLOD(PLCore::uint32 nNumLODLevels); 00551 00552 /** 00553 * @brief 00554 * Calculate the vertex normals of all morph targets of the mesh 00555 * 00556 * @return 00557 * 'true' if all went fine, else 'false' 00558 * 00559 * @note 00560 * - This function will add normals to the vertex buffer if there are no one 00561 * allocated yet 00562 */ 00563 PLMESH_API bool CalculateNormals(); 00564 00565 /** 00566 * @brief 00567 * Calculates all tangent space vectors of all morph targets of the mesh 00568 * 00569 * @param[in] bTangent 00570 * Create tangent vectors? 00571 * @param[in] bBinormal 00572 * Create binormal vectors? 00573 * 00574 * @return 00575 * 'true' if all went fine, else 'false' 00576 * 00577 * @note 00578 * - This function will add tangents and binormals to the 00579 * vertex buffer if there are no one allocated yet 00580 * - If there are no normals available they will be computed (see CalculateNormals()) 00581 * - To save memory one can only hold tangent vectors and compute the binormal for 00582 * instance within a vertex shader using a cross product of the normal and 00583 * tangent vector 00584 */ 00585 PLMESH_API bool CalculateTangentSpaceVectors(bool bTangent = true, bool bBinormal = true); 00586 00587 /** 00588 * @brief 00589 * Returns the mesh bounding box 00590 * 00591 * @param[out] vMin 00592 * Will receive the minimum bounding box position 00593 * @param[out] vMax 00594 * Will receive the maximum bounding box position 00595 * 00596 * @remarks 00597 * This bounding box should enclose the whole mesh. If it is a 0-bounding box 00598 * you can use CalculateBoundingBox() to calculate a valid bounding box. 00599 */ 00600 PLMESH_API void GetBoundingBox(PLMath::Vector3 &vMin, PLMath::Vector3 &vMax) const; 00601 00602 /** 00603 * @brief 00604 * Set's the mesh bounding box 00605 * 00606 * @param[in] vMin 00607 * The minimum bounding box position 00608 * @param[in] vMax 00609 * The maximum bounding box position 00610 * 00611 * @see 00612 * - SetBoundingBox() 00613 */ 00614 PLMESH_API void SetBoundingBox(const PLMath::Vector3 &vMin, const PLMath::Vector3 &vMax); 00615 00616 /** 00617 * @brief 00618 * Calculates the mesh bounding box 00619 * 00620 * @param[out] vMin 00621 * Will receive the minimum bounding box position 00622 * @param[out] vMax 00623 * Will receive the maximum bounding box position 00624 * 00625 * @return 00626 * 'true' if all went fine, else 'false' 00627 * 00628 * @note 00629 * - This function will take all morph targets into account 00630 * - The internal mesh bounding box is NOT manipulated! 00631 */ 00632 PLMESH_API bool CalculateBoundingBox(PLMath::Vector3 &vMin, PLMath::Vector3 &vMax); 00633 00634 /** 00635 * @brief 00636 * Calculates the mesh bounding sphere 00637 * 00638 * @param[out] vPos 00639 * Will receive the bounding sphere position 00640 * @param[out] fRadius 00641 * Will receive the bounding sphere radius 00642 * 00643 * @return 00644 * 'true' if all went fine, else 'false' 00645 * 00646 * @note 00647 * - This function will take all morph targets into account 00648 */ 00649 PLMESH_API bool CalculateBoundingSphere(PLMath::Vector3 &vPos, float &fRadius); 00650 00651 00652 //[-------------------------------------------------------] 00653 //[ Private functions ] 00654 //[-------------------------------------------------------] 00655 private: 00656 /** 00657 * @brief 00658 * Constructor 00659 * 00660 * @param[in] pRenderer 00661 * Pointer to the renderer to use can be a null pointer 00662 * @param[in] cManager 00663 * Mesh manager using this resource 00664 * @param[in] sName 00665 * Resource name to set 00666 * @param[in] bStatic 00667 * Static mesh? (better performance!) 00668 */ 00669 Mesh(PLRenderer::Renderer *pRenderer, PLCore::ResourceManager<Mesh> &cManager, const PLCore::String &sName, bool bStatic = true); 00670 00671 00672 //[-------------------------------------------------------] 00673 //[ Private data ] 00674 //[-------------------------------------------------------] 00675 private: 00676 // Data 00677 PLRenderer::Renderer *m_pRenderer; /**< Renderer the mesh is using, can be a null pointer */ 00678 bool m_bStatic; /**< Static mesh? (better performance!) */ 00679 PLMath::Vector3 m_vBBMin; /**< Minimum bounding box position */ 00680 PLMath::Vector3 m_vBBMax; /**< Maximum bounding box position */ 00681 00682 /** Anchor points */ 00683 AnchorPointManager m_cAnchorPointManager; 00684 00685 /** Morph targets */ 00686 PLCore::Array<MeshMorphTarget*> m_lstMorphTargets; 00687 MorphTargetAniManager m_cMorphTargetAnimation; 00688 PLCore::HashMap<PLCore::String, MeshMorphTarget*> m_mapMorphTargets; 00689 00690 /** LOD data */ 00691 PLCore::Array<MeshLODLevel*> m_lstLODLevels; 00692 00693 /** Materials */ 00694 PLCore::Array<PLRenderer::MaterialHandler*> m_lstMaterials; 00695 00696 /** Skeleton */ 00697 PLCore::Array<SkeletonHandler*> m_lstSkeletonHandler; /**< List of skeleton handlers */ 00698 PLCore::Array<Weight> m_lstWeights; /**< Optional weights */ 00699 PLCore::Array<VertexWeights> m_lstVertexWeights; /**< Optional vertex weights per vertex */ 00700 00701 00702 //[-------------------------------------------------------] 00703 //[ Public virtual PLCore::Loadable functions ] 00704 //[-------------------------------------------------------] 00705 public: 00706 PLMESH_API virtual bool Unload() override; 00707 PLMESH_API virtual PLCore::String GetLoadableTypeName() const override; 00708 00709 00710 }; 00711 00712 00713 //[-------------------------------------------------------] 00714 //[ Namespace ] 00715 //[-------------------------------------------------------] 00716 } // PLMesh 00717 00718 00719 #endif // __PLMESH_MESH_H__
|