mesh_mrm.h

Go to the documentation of this file.
00001 
00005 /* Copyright, 2001 Nevrax Ltd.
00006  *
00007  * This file is part of NEVRAX NEL.
00008  * NEVRAX NEL is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2, or (at your option)
00011  * any later version.
00012 
00013  * NEVRAX NEL is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details.
00017 
00018  * You should have received a copy of the GNU General Public License
00019  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021  * MA 02111-1307, USA.
00022  */
00023 
00024 #ifndef NL_MESH_MRM_H
00025 #define NL_MESH_MRM_H
00026 
00027 #include "nel/misc/types_nl.h"
00028 #include "nel/3d/shape.h"
00029 #include "nel/3d/driver.h"
00030 #include "nel/misc/aabbox.h"
00031 #include "nel/misc/uv.h"
00032 #include "nel/3d/vertex_buffer.h"
00033 #include "nel/3d/material.h"
00034 #include "nel/3d/index_buffer.h"
00035 #include "nel/3d/animated_material.h"
00036 #include "nel/3d/mesh_base.h"
00037 #include "nel/3d/mesh.h"
00038 #include "nel/3d/mrm_mesh.h"
00039 #include "nel/3d/mrm_parameters.h"
00040 #include "nel/3d/bone.h"
00041 #include "nel/3d/mesh_geom.h"
00042 #include "nel/3d/mrm_level_detail.h"
00043 #include "nel/3d/shadow_skin.h"
00044 #include <set>
00045 #include <vector>
00046 
00047 
00048 namespace NL3D
00049 {
00050 
00051 
00052 using   NLMISC::CVector;
00053 using   NLMISC::CPlane;
00054 using   NLMISC::CMatrix;
00055 class   CMRMBuilder;
00056 // Fast matrix in mesh_mrm_skin.cpp
00057 class   CMatrix3x4;
00058 class   CRawVertexNormalSkin1;
00059 class   CRawVertexNormalSkin2;
00060 class   CRawVertexNormalSkin3;
00061 class   CRawVertexNormalSkin4;
00062 class   CRawSkinNormalCache;
00063 class   CMeshMRMInstance;
00064 class   CSkinSpecularRdrPass;
00065 
00066 // ***************************************************************************
00080 class   CMeshMRMGeom : public IMeshGeom
00081 {
00082 public:
00084     CMeshMRMGeom();
00085     ~CMeshMRMGeom();
00086 
00091     void            build(CMesh::CMeshBuild &m, std::vector<CMesh::CMeshBuild*> &bsList, uint numMaxMaterial, const CMRMParameters &params= CMRMParameters());
00092 
00094     void            applyMaterialRemap(const std::vector<sint> &remap);
00095 
00096 
00103     void            changeMRMDistanceSetup(float distanceFinest, float distanceMiddle, float distanceCoarsest);
00104 
00105 
00107     // @{
00108 
00110     virtual void    initInstance(CMeshBaseInstance *mbi);
00111 
00113     virtual bool    clip(const std::vector<CPlane>  &pyramid, const CMatrix &worldMatrix) ;
00114 
00116     virtual void    render(IDriver *drv, CTransformShape *trans, float polygonCount, uint32 rdrFlags, float globalAlpha);
00117 
00119     virtual void    renderSkin(CTransformShape *trans, float alphaMRM);
00120 
00122     virtual float   getNumTriangles (float distance);
00123 
00125     virtual void    serial(NLMISC::IStream &f) throw(NLMISC::EStream);
00126     NLMISC_DECLARE_CLASS(CMeshMRMGeom);
00127 
00129     void    profileSceneRender(CRenderTrav *rdrTrav, CTransformShape *trans, float polygonCount, uint32 rdrFlags);
00130 
00131     // @}
00132 
00133 
00135     // @{
00136 
00139     uint            getNbLodLoaded() const { return _NbLodLoaded ; }
00140 
00141 
00145     void            loadFirstLod(NLMISC::IStream &f);
00146 
00147 
00153     void            loadNextLod(NLMISC::IStream &f);
00154 
00155 
00159     void            unloadNextLod(NLMISC::IStream &f);
00160 
00161 
00162     // @}
00163 
00164 
00166     // @{
00167 
00169     const NLMISC::CAABBoxExt& getBoundingBox() const
00170     {
00171         return _BBox;
00172     }
00173 
00175     const CVertexBuffer &getVertexBuffer() const { return _VBufferFinal ; }
00176 
00178     const std::vector<CMesh::CSkinWeight>   &getSkinWeights() const {return _SkinWeights;}
00179 
00181     const std::vector<std::string>          &getBonesName() const {return _BonesName;}
00182 
00185     uint getNbLod() const { return _Lods.size() ; }
00186 
00187 
00191     uint getNbRdrPass(uint lodId) const { return _Lods[lodId].RdrPass.size() ; }
00192 
00193 
00198     const CIndexBuffer &getRdrPassPrimitiveBlock(uint lodId, uint renderingPassIndex) const
00199     {
00200         return _Lods[lodId].RdrPass[renderingPassIndex].PBlock ;
00201     }
00202 
00203 
00208     uint32 getRdrPassMaterial(uint lodId, uint renderingPassIndex) const
00209     {
00210         return _Lods[lodId].RdrPass[renderingPassIndex].MaterialId ;
00211     }
00212 
00213 
00215     const std::vector<CMRMWedgeGeom>    &getGeomorphs(uint lodId) const
00216     {
00217         return _Lods[lodId].Geomorphs;
00218     }
00219 
00221     uint getNbBlendShapes() const { return _MeshMorpher.BlendShapes.size(); }
00222 
00226     bool    buildGeometryForLod(uint lodId, std::vector<CVector> &vertices, std::vector<uint32> &triangles) const;
00227 
00228     // @}
00229 
00230 
00232     // @{
00233 
00235     bool isSkinned () const
00236     {
00237         return _Skinned;
00238     }
00239 
00241     void            computeBonesId (CSkeletonModel *skeleton);
00242 
00244     void            updateSkeletonUsage(CSkeletonModel *sm, bool increment);
00245 
00247     const std::vector<sint32>           &getSkinBoneUsage() const {return _BonesId;}
00248 
00250     const std::vector<NLMISC::CBSphere> &getSkinBoneSphere() const {return _BonesSphere;}
00251 
00253     bool            getSkinBoneBBox(CSkeletonModel *skeleton, NLMISC::CAABBox &bbox, uint boneId) const;
00254 
00255     // @}
00256 
00257 
00259     // @{
00260 
00264     virtual bool    supportMeshBlockRendering () const;
00265 
00266     virtual bool    sortPerMaterial() const;
00267     virtual uint    getNumRdrPassesForMesh() const ;
00268     virtual uint    getNumRdrPassesForInstance(CMeshBaseInstance *inst) const ;
00269     virtual void    beginMesh(CMeshGeomRenderContext &rdrCtx) ;
00270     virtual void    activeInstance(CMeshGeomRenderContext &rdrCtx, CMeshBaseInstance *inst, float polygonCount, void *vbDst) ;
00271     virtual void    renderPass(CMeshGeomRenderContext &rdrCtx, CMeshBaseInstance *inst, float polygonCount, uint rdrPass) ;
00272     virtual void    endMesh(CMeshGeomRenderContext &rdrCtx) ;
00273 
00274     virtual bool    getVBHeapInfo(uint &vertexFormat, uint &numVertices);
00275     virtual void    computeMeshVBHeap(void *dst, uint indexStart);
00276     virtual bool    isActiveInstanceNeedVBFill() const;
00277 
00278     // @}
00279 
00280 
00282     const   CMRMLevelDetail     &getLevelDetail() const {return _LevelDetail;}
00283 
00284 
00286     // @{
00287     bool            supportSkinGrouping() const;
00288     sint            renderSkinGroupGeom(CMeshMRMInstance    *mi, float alphaMRM, uint remainingVertices, uint8 *vbDest);
00289     void            renderSkinGroupPrimitives(CMeshMRMInstance  *mi, uint baseVertex, std::vector<CSkinSpecularRdrPass> &specularRdrPasses, uint skinIndex);
00290     void            renderSkinGroupSpecularRdrPass(CMeshMRMInstance *mi, uint rdrPassId);
00291     // @}
00292 
00293     // Is this mesh Geom has a VertexProgram bound?
00294     virtual bool    hasMeshVertexProgram() const {return _MeshVertexProgram!=NULL;}
00295 
00297     // @{
00299     void            setShadowMesh(const std::vector<CShadowVertex> &shadowVertices, const std::vector<uint32> &triangles);
00300 
00302     uint            getNumShadowSkinVertices() const;
00303 
00305     bool            supportShadowSkinGrouping() const {return _SupportShadowSkinGrouping;}
00306     sint            renderShadowSkinGeom(CMeshMRMInstance   *mi, uint remainingVertices, uint8 *vbDest);
00307     void            renderShadowSkinPrimitives(CMeshMRMInstance *mi, CMaterial &castMat, IDriver *drv, uint baseVertex);
00308 
00312     bool            supportIntersectSkin() const {return supportShadowSkinGrouping();}
00313     bool            intersectSkin(CMeshMRMInstance  *mi, const CMatrix &toRaySpace, float &dist2D, float &distZ, bool computeDist2D);
00314 
00315     // @}
00316 
00317 // ************************
00318 private:
00319     friend class    CMRMBuilder;
00320 
00322 
00323 
00325     class   CRdrPass
00326     {
00327     public:
00328         // The id of this material.
00329         uint32              MaterialId;
00330         // The list of primitives.
00331         CIndexBuffer        PBlock;
00332         // The same, precomputed for VBHeap Index Shifting
00333         CIndexBuffer        VBHeapPBlock;
00334 
00335         // Serialize a rdrpass.
00336         void    serial(NLMISC::IStream &f)
00337         {
00338             (void)f.serialVersion(0);
00339 
00340             f.serial(MaterialId);
00341             f.serial(PBlock);
00342         }
00343         CRdrPass()
00344         {
00345             NL_SET_IB_NAME(PBlock, "CMeshMRM::CRdrPass::PBlock");
00346             NL_SET_IB_NAME(VBHeapPBlock, "CMeshMRM::CRdrPass::VBHeapPBlock");
00347             PBlock.setFormat(NL_MESH_MRM_INDEX_FORMAT);
00348         }
00349     };
00350 
00351 
00353     struct  CVertexBlock
00354     {
00355         // The index of the start vertex.
00356         uint32  VertexStart;
00357         // Number of vertices.
00358         uint32  NVertices;
00359 
00360         void    serial(NLMISC::IStream &f)
00361         {
00362             f.serial(VertexStart, NVertices);
00363         }
00364     };
00365 
00366 
00367 
00369     class   CLod
00370     {
00371     public:
00373         uint32                      NWedges;
00375         std::vector<CMRMWedgeGeom>  Geomorphs;
00377         std::vector<CRdrPass>       RdrPass;
00378 
00382         std::vector<uint32>             InfluencedVertices[NL3D_MESH_SKINNING_MAX_MATRIX];
00384         std::vector<uint32>             MatrixInfluences;
00386         bool                        OriginalSkinRestored;
00390         std::vector<CVertexBlock>       SkinVertexBlocks;
00391 
00392 
00393 
00394         CLod()
00395         {
00396             // By default, this is supposed false.
00397             OriginalSkinRestored= false;
00398         }
00399 
00400         // Serialize a Lod.
00401         void        serial(NLMISC::IStream &f);
00402 
00403         // Used in CMeshMRMGeom::build().
00404         void        buildSkinVertexBlocks();
00405         void        optimizeTriangleOrder();
00406     };
00407 
00408     friend class    CLod;
00409 
00413     struct  CMeshBuildMRM
00414     {
00415         // This tells if the mesh is correctly skinned.
00416         bool                                Skinned;
00417 
00418         // This is the array of SkinWeights, same size as the VB.
00419         std::vector<CMesh::CSkinWeight>     SkinWeights;
00420 
00421         // This VB is computed with CMRMBuilder and is ready to used
00422         CVertexBuffer           VBuffer;
00423 
00424         // Lod array, computed with CMRMBuilder and ready to used
00425         std::vector<CLod>       Lods;
00426 
00427         // The blend shapes
00428         std::vector<CBlendShape>    BlendShapes;
00429 
00431         // @{
00433         float                   DistanceFinest;
00435         float                   DistanceMiddle;
00437         float                   DistanceCoarsest;
00438         // @}
00439 
00440     };
00442 
00443 
00445     class   CLodInfo
00446     {
00447     public:
00449         uint32      StartAddWedge;
00451         uint32      EndAddWedges;
00453         sint32      LodOffset;
00454 
00455         void    serial(NLMISC::IStream &f)
00456         {
00457             (void)f.serialVersion(0);
00458 
00459             f.serial(StartAddWedge);
00460             f.serial(EndAddWedges);
00461             // do not serial LodOffset here.
00462         }
00463     };
00464 
00465 
00466 
00467 private:
00468 
00470     bool                        _Skinned;
00472     std::vector<CVector>        _OriginalSkinVertices;
00473     std::vector<CVector>        _OriginalSkinNormals;
00474     std::vector<CVector>        _OriginalTGSpace;
00475 
00477     CVertexBuffer               _VBufferOriginal;
00479     CVertexBuffer               _VBufferFinal;
00480 
00482     std::vector<CMesh::CSkinWeight>     _SkinWeights;
00483 
00485     bool                        _BoneIdComputed;
00487     bool                        _BoneIdExtended;
00488 
00490     bool                        _SupportSkinGrouping;
00491 
00493     uint8                       _LastLodComputed;
00494 
00496     std::vector<std::string>    _BonesName;
00498     std::vector<sint32>         _BonesId;
00500     std::vector<sint32>         _BonesIdExt;
00502     std::vector<NLMISC::CBSphere>   _BonesSphere;
00503 
00505     std::vector<CLod>           _Lods;
00507     NLMISC::CAABBoxExt          _BBox;
00508 
00509 
00511     std::vector<CLodInfo>       _LodInfos;
00512     uint                        _NbLodLoaded;
00513 
00514 
00516     // @{
00517     CMRMLevelDetail             _LevelDetail;
00518     // @}
00519 
00520 
00522     bool                        _PreciseClipping;
00523 
00524     // The Mesh Morpher
00525     CMeshMorpher                _MeshMorpher;
00526 
00527     // Possible MeshVertexProgram to apply at render()
00528     NLMISC::CSmartPtr<IMeshVertexProgram>   _MeshVertexProgram;
00529 
00531     // @{
00533     bool                            _SupportMeshBlockRendering;
00535     bool                            _MBRBkupNormalize;
00537     sint                            _MBRCurrentLodId;
00538     // @}
00539 
00540 
00542     // @{
00543     CShadowSkin                     _ShadowSkin;
00544     bool                            _SupportShadowSkinGrouping;
00545     // @}
00546 
00547 private:
00549     void    serialLodVertexData(NLMISC::IStream &f, uint startWedge, uint endWedge);
00550 
00552     sint    chooseLod(float alphaMRM, float &alphaLod);
00553 
00555     void    applyGeomorph(std::vector<CMRMWedgeGeom>  &geoms, float alphaLod);
00556 
00558     void    applyGeomorphWithVBHardPtr(std::vector<CMRMWedgeGeom>  &geoms, float alphaLod, uint8 *vertexDestPtr);
00559 
00561     void    applyGeomorphPosNormalUV0(std::vector<CMRMWedgeGeom>  &geoms, uint8 *vertexPtr, uint8 *vertexDestPtr, sint32 vertexSize, float a, float a1);
00562 
00564     void    bkupOriginalSkinVertices();
00565     void    bkupOriginalSkinVerticesSubset(uint wedgeStart, uint wedgeEnd);
00567     void    restoreOriginalSkinVertices();
00568 
00570     void    applySkin(CLod &lod, const CSkeletonModel *skeleton);
00571 
00575     void    applySkinWithNormal(CLod &lod, const CSkeletonModel *skeleton);
00576     void    applyRawSkinWithNormal(CLod &lod, CRawSkinNormalCache &rawSkinLod, const CSkeletonModel *skeleton, uint8 *vbHard, float alphaLod);
00577 
00582     void    applySkinWithTangentSpace(CLod &lod, const CSkeletonModel *skeleton, uint tangentSpaceTexCoord);
00583 
00585     void    restoreOriginalSkinPart(CLod &lod);
00586 
00587 
00589     sint        loadHeader(NLMISC::IStream &f) throw(NLMISC::EStream);
00591     void        load(NLMISC::IStream &f) throw(NLMISC::EStream);
00593     void        save(NLMISC::IStream &f) throw(NLMISC::EStream);
00594 
00595     // Build bone Usage information for serialized mesh <= version 2.
00596     void        buildBoneUsageVer2 ();
00597 
00598     // Some runtime not serialized compilation
00599     void        compileRunTime();
00600 
00601     // SkinGroup
00602     void        updateShiftedTriangleCache(CMeshMRMInstance *mi, sint curLodId, uint baseVertex);
00603 
00604 private:
00605 
00607     // @{
00608 
00610     uint        _MeshDataId;
00611 
00613     void        updateRawSkinNormal(bool enabled, CMeshMRMInstance *mi, sint curLodId);
00615     void        dirtMeshDataId();
00616 
00617     // ApplySkin method
00618     void        applyArrayRawSkinNormal1(CRawVertexNormalSkin1 *src, uint8 *destVertexPtr,
00619         CMatrix3x4 *boneMat3x4, uint nInf);
00620     void        applyArrayRawSkinNormal2(CRawVertexNormalSkin2 *src, uint8 *destVertexPtr,
00621         CMatrix3x4 *boneMat3x4, uint nInf);
00622     void        applyArrayRawSkinNormal3(CRawVertexNormalSkin3 *src, uint8 *destVertexPtr,
00623         CMatrix3x4 *boneMat3x4, uint nInf);
00624     void        applyArrayRawSkinNormal4(CRawVertexNormalSkin4 *src, uint8 *destVertexPtr,
00625         CMatrix3x4 *boneMat3x4, uint nInf);
00626 
00627 
00628 public:
00629     static  uint    NumCacheVertexNormal1;
00630     static  uint    NumCacheVertexNormal2;
00631     static  uint    NumCacheVertexNormal3;
00632     static  uint    NumCacheVertexNormal4;
00633 
00634     // @}
00635 };
00636 
00637 
00638 
00639 // ***************************************************************************
00654 class CMeshMRM : public CMeshBase
00655 {
00656 public:
00658     CMeshMRM();
00659 
00664     void            build ( CMeshBase::CMeshBaseBuild &mBase, CMesh::CMeshBuild &m,
00665                             std::vector<CMesh::CMeshBuild*> &listBS,
00666                             const CMRMParameters &params= CMRMParameters() );
00667 
00673     void            build (CMeshBase::CMeshBaseBuild &m, const CMeshMRMGeom &mgeom);
00674 
00679     void            optimizeMaterialUsage(std::vector<sint> &remap);
00680 
00681 
00683     void            computeBonesId (CSkeletonModel *skeleton);
00684 
00686     void            updateSkeletonUsage(CSkeletonModel *sm, bool increment);
00687 
00694     void            changeMRMDistanceSetup(float distanceFinest, float distanceMiddle, float distanceCoarsest);
00695 
00697     // @{
00698 
00700     virtual CTransformShape     *createInstance(CScene &scene);
00701 
00703     virtual bool    clip(const std::vector<CPlane>  &pyramid, const CMatrix &worldMatrix) ;
00704 
00706     virtual void    render(IDriver *drv, CTransformShape *trans, bool passOpaque);
00707 
00709     virtual float   getNumTriangles (float distance);
00710 
00712     virtual void    serial(NLMISC::IStream &f) throw(NLMISC::EStream);
00713     NLMISC_DECLARE_CLASS(CMeshMRM);
00714 
00716     virtual void    getAABBox(NLMISC::CAABBox &bbox) const {bbox= getBoundingBox().getAABBox();}
00717 
00719     virtual void    profileSceneRender(CRenderTrav *rdrTrav, CTransformShape *trans, bool opaquePass);
00720 
00722     virtual void    buildSystemGeometry();
00723 
00724     // @}
00725 
00726 
00728     // @{
00729 
00731     const NLMISC::CAABBoxExt& getBoundingBox() const
00732     {
00733         return _MeshMRMGeom.getBoundingBox();
00734     }
00735 
00737     const CVertexBuffer &getVertexBuffer() const { return _MeshMRMGeom.getVertexBuffer(); }
00738 
00739 
00742     uint getNbLod() const { return _MeshMRMGeom.getNbLod()  ; }
00743 
00744 
00748     uint getNbRdrPass(uint lodId) const { return _MeshMRMGeom.getNbRdrPass(lodId) ; }
00749 
00750 
00755     const CIndexBuffer &getRdrPassPrimitiveBlock(uint lodId, uint renderingPassIndex) const
00756     {
00757         return _MeshMRMGeom.getRdrPassPrimitiveBlock(lodId, renderingPassIndex) ;
00758     }
00759 
00760 
00765     uint32 getRdrPassMaterial(uint lodId, uint renderingPassIndex) const
00766     {
00767         return _MeshMRMGeom.getRdrPassMaterial(lodId, renderingPassIndex) ;
00768     }
00769 
00771     const CMeshMRMGeom& getMeshGeom () const;
00772 
00773     // @}
00774 
00775 
00777     // @{
00778     virtual IMeshGeom   *supportMeshBlockRendering (CTransformShape *trans, float &polygonCount ) const;
00779     // @}
00780 
00781 
00782 // ************************
00783 private:
00784 
00785     CMeshMRMGeom        _MeshMRMGeom;
00786 
00787 
00788 };
00789 
00790 
00791 } // NL3D
00792 
00793 
00794 #endif // NL_MESH_MRM_H
00795 
00796 /* End of mesh_mrm.h */

Generated on Thu Jan 7 08:26:18 2010 for NeL by  doxygen 1.6.1