# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

mesh_mrm.h

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #ifndef NL_MESH_MRM_H
00027 #define NL_MESH_MRM_H
00028 
00029 #include "nel/misc/types_nl.h"
00030 #include "3d/shape.h"
00031 #include "3d/driver.h"
00032 #include "nel/misc/aabbox.h"
00033 #include "nel/misc/uv.h"
00034 #include "3d/vertex_buffer.h"
00035 #include "3d/material.h"
00036 #include "3d/primitive_block.h"
00037 #include "3d/animated_material.h"
00038 #include "3d/mesh_base.h"
00039 #include "3d/mesh.h"
00040 #include "3d/mrm_mesh.h"
00041 #include "3d/mrm_parameters.h"
00042 #include "3d/bone.h"
00043 #include "3d/mesh_geom.h"
00044 #include "3d/mrm_level_detail.h"
00045 #include <set>
00046 #include <vector>
00047 
00048 
00049 namespace NL3D 
00050 {
00051 
00052 
00053 using   NLMISC::CVector;
00054 using   NLMISC::CPlane;
00055 using   NLMISC::CMatrix;
00056 class   CMRMBuilder;
00057 // Fast matrix in mesh_mrm_skin.cpp
00058 class   CMatrix3x4;
00059 class   CMatrix3x4SSE;
00060 class   CRawVertexNormalSkin1;
00061 class   CRawVertexNormalSkin2;
00062 class   CRawVertexNormalSkin4;
00063 class   CRawSkinNormalCache;
00064 class   CMeshMRMInstance;
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 
00128         // @}
00129 
00130 
00132         // @{
00133 
00136         uint                    getNbLodLoaded() const { return _NbLodLoaded ; }
00137 
00138 
00142         void                    loadFirstLod(NLMISC::IStream &f);
00143 
00144 
00150         void                    loadNextLod(NLMISC::IStream &f);
00151 
00152 
00156         void                    unloadNextLod(NLMISC::IStream &f);
00157 
00158 
00159         // @}
00160 
00161 
00163         // @{
00164 
00166         const NLMISC::CAABBoxExt& getBoundingBox() const
00167         {
00168                 return _BBox;
00169         }
00170 
00172         const CVertexBuffer &getVertexBuffer() const { return _VBufferFinal ; }
00173 
00175         const std::vector<CMesh::CSkinWeight>   &getSkinWeights() const {return _SkinWeights;}
00176 
00178         const std::vector<std::string>                  &getBonesName() const {return _BonesName;}
00179 
00182         uint getNbLod() const { return _Lods.size() ; }
00183 
00184 
00188         uint getNbRdrPass(uint lodId) const { return _Lods[lodId].RdrPass.size() ; }
00189 
00190 
00195         const CPrimitiveBlock &getRdrPassPrimitiveBlock(uint lodId, uint renderingPassIndex) const
00196         {
00197                 return _Lods[lodId].RdrPass[renderingPassIndex].PBlock ;
00198         }
00199 
00200 
00205         uint32 getRdrPassMaterial(uint lodId, uint renderingPassIndex) const
00206         {
00207                 return _Lods[lodId].RdrPass[renderingPassIndex].MaterialId ;
00208         }
00209 
00210 
00212         const std::vector<CMRMWedgeGeom>        &getGeomorphs(uint lodId) const
00213         {
00214                 return _Lods[lodId].Geomorphs;
00215         }
00216 
00217         // @}
00218 
00219 
00221         // @{
00222 
00224         bool isSkinned () const
00225         {
00226                 return _Skinned;
00227         }
00228 
00230         void                    computeBonesId (CSkeletonModel *skeleton);
00231 
00233         void                    updateSkeletonUsage(CSkeletonModel *sm, bool increment);
00234 
00236         const std::vector<sint32>       &getSkinBoneUsage() const {return _BonesId;}
00237 
00238         // @}
00239 
00240 
00242         // @{
00243 
00247         virtual bool    supportMeshBlockRendering () const;
00248 
00249         virtual bool    sortPerMaterial() const;
00250         virtual uint    getNumRdrPasses() const ;
00251         virtual void    beginMesh(CMeshGeomRenderContext &rdrCtx) ;
00252         virtual void    activeInstance(CMeshGeomRenderContext &rdrCtx, CMeshBaseInstance *inst, float polygonCount) ;
00253         virtual void    renderPass(CMeshGeomRenderContext &rdrCtx, CMeshBaseInstance *inst, float polygonCount, uint rdrPass) ;
00254         virtual void    endMesh(CMeshGeomRenderContext &rdrCtx) ;
00255 
00256         // @}
00257 
00258 
00260         const   CMRMLevelDetail         &getLevelDetail() const {return _LevelDetail;}
00261 
00262 
00264         // @{
00265         bool                    supportSkinGrouping() const;
00266         sint                    renderSkinGroupGeom(CMeshMRMInstance    *mi, float alphaMRM, uint remainingVertices, uint8 *vbDest);
00267         void                    renderSkinGroupPrimitives(CMeshMRMInstance      *mi, uint baseVertex);
00268         // @}
00269 
00270 
00271 // ************************
00272 private:
00273         friend class    CMRMBuilder;
00274 
00276 
00277 
00279         class   CRdrPass
00280         {
00281         public:
00282                 // The id of this material.
00283                 uint32                          MaterialId;
00284                 // The list of primitives.
00285                 CPrimitiveBlock         PBlock;
00286 
00287 
00288                 // Serialize a rdrpass.
00289                 void    serial(NLMISC::IStream &f)
00290                 {
00291                         (void)f.serialVersion(0);
00292 
00293                         f.serial(MaterialId);
00294                         f.serial(PBlock);
00295                 }
00296         };
00297 
00298 
00300         struct  CVertexBlock
00301         {
00302                 // The index of the start vertex.
00303                 uint32  VertexStart;
00304                 // Number of vertices.
00305                 uint32  NVertices;
00306 
00307                 void    serial(NLMISC::IStream &f)
00308                 {
00309                         f.serial(VertexStart, NVertices);
00310                 }
00311         };
00312 
00313 
00314 
00316         class   CLod
00317         {
00318         public:
00320                 uint32                                          NWedges;
00322                 std::vector<CMRMWedgeGeom>      Geomorphs;
00324                 std::vector<CRdrPass>           RdrPass;
00325 
00329                 std::vector<uint32>                             InfluencedVertices[NL3D_MESH_SKINNING_MAX_MATRIX];
00331                 std::vector<uint32>                             MatrixInfluences;
00333                 bool                                            OriginalSkinRestored;
00337                 std::vector<CVertexBlock>               SkinVertexBlocks;
00338 
00339 
00340 
00341                 CLod()
00342                 {
00343                         // By default, this is supposed false.
00344                         OriginalSkinRestored= false;
00345                 }
00346 
00347                 // Serialize a Lod.
00348                 void            serial(NLMISC::IStream &f);
00349 
00350                 // Used in CMeshMRMGeom::build().
00351                 void            buildSkinVertexBlocks();
00352                 void            optimizeTriangleOrder();
00353         };
00354 
00355         friend class    CLod;
00356 
00360         struct  CMeshBuildMRM
00361         {
00362                 // This tells if the mesh is correctly skinned.
00363                 bool                                                            Skinned;
00364 
00365                 // This is the array of SkinWeights, same size as the VB.
00366                 std::vector<CMesh::CSkinWeight>         SkinWeights;            
00367 
00368                 // This VB is computed with CMRMBuilder and is ready to used
00369                 CVertexBuffer                   VBuffer;
00370 
00371                 // Lod array, computed with CMRMBuilder and ready to used
00372                 std::vector<CLod>               Lods;
00373 
00374                 // The blend shapes
00375                 std::vector<CBlendShape>        BlendShapes;
00376 
00378                 // @{
00380                 float                                   DistanceFinest;
00382                 float                                   DistanceMiddle;
00384                 float                                   DistanceCoarsest;
00385                 // @}
00386 
00387         };
00389 
00390 
00392         class   CLodInfo
00393         {
00394         public:
00396                 uint32          StartAddWedge;
00398                 uint32          EndAddWedges;
00400                 sint32          LodOffset;
00401 
00402                 void    serial(NLMISC::IStream &f)
00403                 {
00404                         (void)f.serialVersion(0);
00405 
00406                         f.serial(StartAddWedge);
00407                         f.serial(EndAddWedges);
00408                         // do not serial LodOffset here.
00409                 }
00410         };
00411 
00412 
00413 
00414 private:
00415 
00417         bool                                            _Skinned;
00419         std::vector<CVector>            _OriginalSkinVertices;
00420         std::vector<CVector>            _OriginalSkinNormals;
00421         std::vector<CVector>            _OriginalTGSpace;
00422 
00424         CVertexBuffer                           _VBufferOriginal;
00426         CVertexBuffer                           _VBufferFinal;
00427         
00429         std::vector<CMesh::CSkinWeight>         _SkinWeights;
00430 
00432         bool                                            _BoneIdComputed;
00434         bool                                            _BoneIdExtended;
00435 
00437         bool                                            _SupportSkinGrouping;
00438 
00440         uint8                                           _LastLodComputed;
00441 
00443         std::vector<std::string>        _BonesName;
00445         std::vector<sint32>                     _BonesId;
00447         std::vector<sint32>                     _BonesIdExt;
00448 
00450         std::vector<CLod>                       _Lods;
00452         NLMISC::CAABBoxExt                      _BBox;
00453 
00454 
00456         std::vector<CLodInfo>           _LodInfos;
00457         uint                                            _NbLodLoaded;
00458 
00459 
00461         // @{
00462         CMRMLevelDetail                         _LevelDetail;
00463         // @}
00464 
00465 
00467         // @{
00468 
00469         CRefPtr<IVertexBufferHard>      _VBHard;
00470         // a refPtr on the driver, to delete VBuffer Hard at clear().
00471         CRefPtr<IDriver>                        _Driver;
00472         bool                                            _VertexBufferHardDirty;
00473 
00475         bool                                            _PreciseClipping;
00476 
00477         /* try to create a vertexBufferHard. NB: enlarge capacity of the VBHard as necessary.
00478                 After this call, the vertexBufferHard may be NULL.
00479         */
00480         void                            updateVertexBufferHard(IDriver *drv, uint32 numVertices);
00481         void                            deleteVertexBufferHard();
00482 
00483         // Fill skin in AGP, with a direct ptr onto AGP
00484         void                            fillAGPSkinPartWithVBHardPtr(CLod &lod, uint8 *vertexDst);
00485 
00486         // @}
00487 
00488         // The Mesh Morpher
00489         CMeshMorpher                            _MeshMorpher; 
00490 
00491         // Possible MeshVertexProgram to apply at render()
00492         NLMISC::CSmartPtr<IMeshVertexProgram>   _MeshVertexProgram;
00493 
00494 private:
00496         void    serialLodVertexData(NLMISC::IStream &f, uint startWedge, uint endWedge);
00497 
00499         sint    chooseLod(float alphaMRM, float &alphaLod);
00500 
00502         void    applyGeomorph(std::vector<CMRMWedgeGeom>  &geoms, float alphaLod, IVertexBufferHard *currentVBHard);
00503 
00505         void    applyGeomorphWithVBHardPtr(std::vector<CMRMWedgeGeom>  &geoms, float alphaLod, uint8 *vertexDestPtr);
00506 
00508         void    applyGeomorphPosNormalUV0(std::vector<CMRMWedgeGeom>  &geoms, uint8 *vertexPtr, uint8 *vertexDestPtr, sint32 vertexSize, float a, float a1);
00509 
00511         void    bkupOriginalSkinVertices();
00512         void    bkupOriginalSkinVerticesSubset(uint wedgeStart, uint wedgeEnd);
00514         void    restoreOriginalSkinVertices();
00515 
00517         void    applySkin(CLod &lod, const CSkeletonModel *skeleton);
00518 
00522         void    applySkinWithNormal(CLod &lod, const CSkeletonModel *skeleton);
00523         void    applySkinWithNormalSSE(CLod &lod, const CSkeletonModel *skeleton);
00524         void    applyRawSkinWithNormal(CLod &lod, CRawSkinNormalCache &rawSkinLod, const CSkeletonModel *skeleton);
00525         void    applyRawSkinWithNormalSSE(CLod &lod, CRawSkinNormalCache &rawSkinLod, const CSkeletonModel *skeleton);
00526 
00531         void    applySkinWithTangentSpace(CLod &lod, const CSkeletonModel *skeleton, uint tangentSpaceTexCoord);
00532         void    applySkinWithTangentSpaceSSE(CLod &lod, const CSkeletonModel *skeleton, uint tangentSpaceTexCoord);
00533 
00535         void    restoreOriginalSkinPart(CLod &lod, IVertexBufferHard *currentVBHard);
00536 
00537 
00539         sint            loadHeader(NLMISC::IStream &f) throw(NLMISC::EStream);
00541         void            load(NLMISC::IStream &f) throw(NLMISC::EStream);
00543         void            save(NLMISC::IStream &f) throw(NLMISC::EStream);
00544 
00545         // Build bone Usage information for serialized mesh <= version 2.
00546         void            buildBoneUsageVer2 ();
00547 
00548         // Some runtime not serialized compilation
00549         void            compileRunTime();
00550 
00551         // SkinGroup
00552         void            updateShiftedTriangleCache(CMeshMRMInstance *mi, sint curLodId, uint baseVertex);
00553 
00554 private:
00555 
00557         // @{
00558 
00560         uint            _MeshDataId;
00561 
00563         void            updateRawSkinNormal(bool enabled, CMeshMRMInstance *mi, sint curLodId);
00565         void            dirtMeshDataId();
00566 
00567         // ApplySkin method
00568         void            applyArrayRawSkinNormal1(CRawVertexNormalSkin1 *src, uint8 *destVertexPtr, 
00569                 CMatrix3x4 *boneMat3x4, uint vertexSize, uint nInf);
00570         void            applyArrayRawSkinNormal2(CRawVertexNormalSkin2 *src, uint8 *destVertexPtr, 
00571                 CMatrix3x4 *boneMat3x4, uint vertexSize, uint nInf);
00572         void            applyArrayRawSkinNormal3(CRawVertexNormalSkin4 *src, uint8 *destVertexPtr, 
00573                 CMatrix3x4 *boneMat3x4, uint vertexSize, uint nInf);
00574         void            applyArrayRawSkinNormal4(CRawVertexNormalSkin4 *src, uint8 *destVertexPtr, 
00575                 CMatrix3x4 *boneMat3x4, uint vertexSize, uint nInf);
00576         // Same for SSE
00577         void            applyArrayRawSkinNormal1(CRawVertexNormalSkin1 *src, uint8 *destVertexPtr, 
00578                 CMatrix3x4SSE *boneMat3x4, uint vertexSize, uint nInf);
00579         void            applyArrayRawSkinNormal2(CRawVertexNormalSkin2 *src, uint8 *destVertexPtr, 
00580                 CMatrix3x4SSE *boneMat3x4, uint vertexSize, uint nInf);
00581         void            applyArrayRawSkinNormal3(CRawVertexNormalSkin4 *src, uint8 *destVertexPtr, 
00582                 CMatrix3x4SSE *boneMat3x4, uint vertexSize, uint nInf);
00583         void            applyArrayRawSkinNormal4(CRawVertexNormalSkin4 *src, uint8 *destVertexPtr, 
00584                 CMatrix3x4SSE *boneMat3x4, uint vertexSize, uint nInf);
00585 
00586 
00587 public:
00588         static  uint    NumCacheVertexNormal1;
00589         static  uint    NumCacheVertexNormal2;
00590         static  uint    NumCacheVertexNormal4;
00591 
00592         // @}
00593 };
00594 
00595 
00596 
00597 // ***************************************************************************
00612 class CMeshMRM : public CMeshBase
00613 {
00614 public:
00616         CMeshMRM();
00617 
00622         void                    build ( CMeshBase::CMeshBaseBuild &mBase, CMesh::CMeshBuild &m,
00623                                                         std::vector<CMesh::CMeshBuild*> &listBS,
00624                                                         const CMRMParameters &params= CMRMParameters() );
00625 
00631         void                    build (CMeshBase::CMeshBaseBuild &m, const CMeshMRMGeom &mgeom);
00632 
00637         void                    optimizeMaterialUsage(std::vector<sint> &remap);
00638 
00639 
00641         void                    computeBonesId (CSkeletonModel *skeleton);
00642 
00644         void                    updateSkeletonUsage(CSkeletonModel *sm, bool increment);
00645 
00652         void                    changeMRMDistanceSetup(float distanceFinest, float distanceMiddle, float distanceCoarsest);
00653 
00655         // @{
00656 
00658         virtual CTransformShape         *createInstance(CScene &scene);
00659 
00661         virtual bool    clip(const std::vector<CPlane>  &pyramid, const CMatrix &worldMatrix) ;
00662 
00664         virtual void    render(IDriver *drv, CTransformShape *trans, bool passOpaque);
00665 
00667         virtual float   getNumTriangles (float distance);
00668 
00670         virtual void    serial(NLMISC::IStream &f) throw(NLMISC::EStream);
00671         NLMISC_DECLARE_CLASS(CMeshMRM);
00672 
00674         virtual void    getAABBox(NLMISC::CAABBox &bbox) const {bbox= getBoundingBox().getAABBox();}
00675 
00676         // @}
00677 
00678 
00680         // @{
00681 
00683         const NLMISC::CAABBoxExt& getBoundingBox() const
00684         {
00685                 return _MeshMRMGeom.getBoundingBox();
00686         }
00687 
00689         const CVertexBuffer &getVertexBuffer() const { return _MeshMRMGeom.getVertexBuffer(); }
00690 
00691 
00694         uint getNbLod() const { return _MeshMRMGeom.getNbLod()  ; }
00695 
00696 
00700         uint getNbRdrPass(uint lodId) const { return _MeshMRMGeom.getNbRdrPass(lodId) ; }
00701 
00702 
00707         const CPrimitiveBlock &getRdrPassPrimitiveBlock(uint lodId, uint renderingPassIndex) const
00708         {
00709                 return _MeshMRMGeom.getRdrPassPrimitiveBlock(lodId, renderingPassIndex) ;
00710         }
00711 
00712 
00717         uint32 getRdrPassMaterial(uint lodId, uint renderingPassIndex) const
00718         {
00719                 return _MeshMRMGeom.getRdrPassMaterial(lodId, renderingPassIndex) ;
00720         }
00721 
00723         const CMeshMRMGeom& getMeshGeom () const;
00724 
00725         // @}
00726 
00727 
00728 // ************************
00729 private:
00730 
00731         CMeshMRMGeom            _MeshMRMGeom;
00732 
00733 
00734 };
00735 
00736 
00737 } // NL3D
00738 
00739 
00740 #endif // NL_MESH_MRM_H
00741 
00742 /* End of mesh_mrm.h */