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