mesh_mrm_skinned.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_SKINNED_H
00027 #define NL_MESH_MRM_SKINNED_H
00028 
00029 #include "nel/misc/types_nl.h"
00030 #include "nel/3d/shape.h"
00031 #include "nel/3d/driver.h"
00032 #include "nel/misc/aabbox.h"
00033 #include "nel/misc/uv.h"
00034 #include "nel/3d/vertex_buffer.h"
00035 #include "nel/3d/material.h"
00036 #include "nel/3d/index_buffer.h"
00037 #include "nel/3d/animated_material.h"
00038 #include "nel/3d/mesh_base.h"
00039 #include "nel/3d/mesh.h"
00040 #include "nel/3d/mrm_mesh.h"
00041 #include "nel/3d/mrm_parameters.h"
00042 #include "nel/3d/bone.h"
00043 #include "nel/3d/mesh_geom.h"
00044 #include "nel/3d/mrm_level_detail.h"
00045 #include "nel/3d/shadow_skin.h"
00046 #include <set>
00047 #include <vector>
00048 
00049 
00050 namespace NL3D
00051 {
00052 
00053 
00054 using   NLMISC::CVector;
00055 using   NLMISC::CPlane;
00056 using   NLMISC::CMatrix;
00057 class   CMRMBuilder;
00058 // Fast matrix in mesh_mrm_skin.cpp
00059 class   CMatrix3x4;
00060 class   CRawVertexNormalSkinned1;
00061 class   CRawVertexNormalSkinned2;
00062 class   CRawVertexNormalSkinned3;
00063 class   CRawVertexNormalSkinned4;
00064 class   CRawSkinnedNormalCache;
00065 class   CMeshMRMSkinnedInstance;
00066 class   CSkinSpecularRdrPass;
00067 
00068 #define NL3D_MESH_MRM_SKINNED_WEIGHT_FACTOR     (255.f)
00069 #define NL3D_MESH_MRM_SKINNED_UV_FACTOR         (8192.f)
00070 #define NL3D_MESH_MRM_SKINNED_NORMAL_FACTOR     (32767.f)
00071 #define NL3D_MESH_MRM_SKINNED_DEFAULT_POS_SCALE (8.f/32767.f)
00072 #define NL3D_MESH_MRM_SKINNED_MAX_MATRIX        4
00073 #define NL3D_MESH_MRM_SKINNED_VERTEX_FORMAT     (CVertexBuffer::PositionFlag|CVertexBuffer::NormalFlag|CVertexBuffer::TexCoord0Flag|CVertexBuffer::PaletteSkinFlag)
00074 
00075 // ***************************************************************************
00089 class   CMeshMRMSkinnedGeom : public IMeshGeom
00090 {
00091 public:
00093     CMeshMRMSkinnedGeom();
00094     ~CMeshMRMSkinnedGeom();
00095 
00100     void            build(CMesh::CMeshBuild &m, uint numMaxMaterial, const CMRMParameters &params= CMRMParameters());
00101 
00103     void            applyMaterialRemap(const std::vector<sint> &remap);
00104 
00105 
00112     void            changeMRMDistanceSetup(float distanceFinest, float distanceMiddle, float distanceCoarsest);
00113 
00114 
00116     // @{
00117 
00119     virtual void    initInstance(CMeshBaseInstance *mbi);
00120 
00122     virtual bool    clip(const std::vector<CPlane>  &pyramid, const CMatrix &worldMatrix) ;
00123 
00125     virtual void    render(IDriver *drv, CTransformShape *trans, float polygonCount, uint32 rdrFlags, float globalAlpha);
00126 
00128     virtual void    renderSkin(CTransformShape *trans, float alphaMRM);
00129 
00131     virtual float   getNumTriangles (float distance);
00132 
00134     virtual void    serial(NLMISC::IStream &f);
00135     NLMISC_DECLARE_CLASS(CMeshMRMSkinnedGeom);
00136 
00138     void    profileSceneRender(CRenderTrav *rdrTrav, CTransformShape *trans, float polygonCount, uint32 rdrFlags);
00139 
00140     // @}
00141 
00142 
00144     // @{
00145 
00147     const NLMISC::CAABBoxExt& getBoundingBox() const
00148     {
00149         return _BBox;
00150     }
00151 
00153     void getVertexBuffer(CVertexBuffer &output) const;
00154 
00156     void getSkinWeights (std::vector<CMesh::CSkinWeight> &skinWeights) const;
00157 
00158 
00160     const std::vector<std::string>          &getBonesName() const {return _BonesName;}
00161 
00164     uint getNbLod() const { return _Lods.size() ; }
00165 
00166 
00170     uint getNbRdrPass(uint lodId) const { return _Lods[lodId].RdrPass.size() ; }
00171 
00172 
00177     void getRdrPassPrimitiveBlock(uint lodId, uint renderingPassIndex, CIndexBuffer &block) const
00178     {
00179         _Lods[lodId].getRdrPassPrimitiveBlock(renderingPassIndex, block);
00180     }
00181 
00182 
00187     uint32 getRdrPassMaterial(uint lodId, uint renderingPassIndex) const
00188     {
00189         return _Lods[lodId].RdrPass[renderingPassIndex].MaterialId ;
00190     }
00191 
00192 
00194     const std::vector<CMRMWedgeGeom>    &getGeomorphs(uint lodId) const
00195     {
00196         return _Lods[lodId].Geomorphs;
00197     }
00198 
00199     // @}
00200 
00201 
00203     // @{
00204 
00206     void            computeBonesId (CSkeletonModel *skeleton);
00207 
00209     void            updateSkeletonUsage(CSkeletonModel *sm, bool increment);
00210 
00212     const std::vector<sint32>           &getSkinBoneUsage() const {return _BonesId;}
00213 
00215     const std::vector<NLMISC::CBSphere> &getSkinBoneSphere() const {return _BonesSphere;}
00216 
00218     bool            getSkinBoneBBox(CSkeletonModel *skeleton, NLMISC::CAABBox &bbox, uint boneId) const;
00219 
00220     // @}
00221 
00222 
00224     // @{
00225 
00229     virtual bool    supportMeshBlockRendering () const;
00230 
00231     virtual bool    sortPerMaterial() const { return false; }
00232     virtual uint    getNumRdrPassesForMesh() const { return 0; }
00233     virtual uint    getNumRdrPassesForInstance(CMeshBaseInstance * /* inst */) const { return 0; }
00234     virtual void    beginMesh(CMeshGeomRenderContext &/* rdrCtx */) {}
00235     virtual void    activeInstance(CMeshGeomRenderContext &/* rdrCtx */, CMeshBaseInstance * /* inst */, float /* polygonCount */, void * /* vbDst */) {}
00236     virtual void    renderPass(CMeshGeomRenderContext &/* rdrCtx */, CMeshBaseInstance * /* inst */, float /* polygonCount */, uint /* rdrPass */) {}
00237     virtual void    endMesh(CMeshGeomRenderContext &/* rdrCtx */) {}
00238 
00239     // @}
00240 
00241 
00243     const   CMRMLevelDetail     &getLevelDetail() const {return _LevelDetail;}
00244 
00245 
00247     // @{
00248     bool            supportSkinGrouping() const;
00249     sint            renderSkinGroupGeom(CMeshMRMSkinnedInstance *mi, float alphaMRM, uint remainingVertices, uint8 *vbDest);
00250     void            renderSkinGroupPrimitives(CMeshMRMSkinnedInstance   *mi, uint baseVertex, std::vector<CSkinSpecularRdrPass> &specularRdrPasses, uint skinIndex);
00251     void            renderSkinGroupSpecularRdrPass(CMeshMRMSkinnedInstance  *mi, uint rdrPassId);
00252     // @}
00253 
00254     // Is this mesh Geom has a VertexProgram bound?
00255     virtual bool    hasMeshVertexProgram() const {return false;}
00256 
00258     // @{
00260     void            setShadowMesh(const std::vector<CShadowVertex> &shadowVertices, const std::vector<uint32> &triangles);
00261 
00263     uint            getNumShadowSkinVertices() const;
00264 
00266     bool            supportShadowSkinGrouping() const {return _SupportShadowSkinGrouping;}
00267     sint            renderShadowSkinGeom(CMeshMRMSkinnedInstance    *mi, uint remainingVertices, uint8 *vbDest);
00268     void            renderShadowSkinPrimitives(CMeshMRMSkinnedInstance  *mi, CMaterial &castMat, IDriver *drv, uint baseVertex);
00269 
00273     bool            supportIntersectSkin() const {return supportShadowSkinGrouping();}
00274     bool            intersectSkin(CMeshMRMSkinnedInstance   *mi, const CMatrix &toRaySpace, float &dist2D, float &distZ, bool computeDist2D);
00275 
00276     // @}
00277 
00278 // ************************
00279 private:
00280     friend class    CMRMBuilder;
00281 
00283 
00284 
00286     class   CRdrPass
00287     {
00288     public:
00289         // The id of this material.
00290         uint32              MaterialId;
00291         // The list of primitives.
00292         std::vector<uint16> PBlock;
00293 
00294         // Serialize a rdrpass.
00295         void    serial(NLMISC::IStream &f)
00296         {
00297             (void)f.serialVersion(0);
00298 
00299             f.serial(MaterialId);
00300             f.serialCont(PBlock);
00301         }
00302 
00303         // Get num triangle
00304         uint getNumTriangle () const
00305         {
00306             return PBlock.size()/3;
00307         }
00308     };
00309 
00310 
00312     struct  CVertexBlock
00313     {
00314         // The index of the start vertex.
00315         uint32  VertexStart;
00316         // Number of vertices.
00317         uint32  NVertices;
00318 
00319         void    serial(NLMISC::IStream &f)
00320         {
00321             f.serial(VertexStart, NVertices);
00322         }
00323     };
00324 
00325 
00326 
00328     class   CLod
00329     {
00330     public:
00332         uint32                      NWedges;
00334         std::vector<CMRMWedgeGeom>  Geomorphs;
00336         std::vector<CRdrPass>       RdrPass;
00337 
00341         std::vector<uint32>             InfluencedVertices[NL3D_MESH_SKINNING_MAX_MATRIX];
00343         std::vector<uint32>             MatrixInfluences;
00344 
00345 
00346 
00347         CLod()
00348         {
00349         }
00350 
00351         // Serialize a Lod.
00352         void        serial(NLMISC::IStream &f);
00353 
00354         // Used in CMeshMRMSkinnedGeom::build().
00355         void        optimizeTriangleOrder();
00356 
00357         // Get the primitive block
00358         void getRdrPassPrimitiveBlock (uint renderPass, CIndexBuffer &block) const;
00359 
00360         // Build the primitive block
00361         void buildPrimitiveBlock(uint renderPass, const CIndexBuffer &block);
00362     };
00363 
00364     friend class    CLod;
00365 
00369     struct  CMeshBuildMRM
00370     {
00371         // This tells if the mesh is correctly skinned.
00372         bool                                Skinned;
00373 
00374         // This is the array of SkinWeights, same size as the VB.
00375         std::vector<CMesh::CSkinWeight>     SkinWeights;
00376 
00377         // This VB is computed with CMRMBuilder and is ready to used
00378         CVertexBuffer           VBuffer;
00379 
00380         // Lod array, computed with CMRMBuilder and ready to used
00381         std::vector<CLod>       Lods;
00382 
00383         // The blend shapes
00384         std::vector<CBlendShape>    BlendShapes;
00385 
00387         // @{
00389         float                   DistanceFinest;
00391         float                   DistanceMiddle;
00393         float                   DistanceCoarsest;
00394         // @}
00395 
00396     };
00398 
00399 
00400 
00401 public:
00402 
00404     class CPackedVertexBuffer
00405     {
00406     public:
00408         struct CPackedVertex
00409         {
00410             sint16  X, Y, Z;
00411             sint16  Nx, Ny, Nz;
00412             sint16  U, V;
00413             uint8   Matrices[NL3D_MESH_MRM_SKINNED_MAX_MATRIX];
00414             uint8   Weights[NL3D_MESH_MRM_SKINNED_MAX_MATRIX];
00415 
00416             // Decompact it
00417             inline void getPos (CVector &dest, float factor) const
00418             {
00419                 dest.x = (float)X * factor;
00420                 dest.y = (float)Y * factor;
00421                 dest.z = (float)Z * factor;
00422             }
00423             inline void getNormal (CVector &dest) const
00424             {
00425                 dest.x = (float)Nx * (1.f/NL3D_MESH_MRM_SKINNED_NORMAL_FACTOR);
00426                 dest.y = (float)Ny * (1.f/NL3D_MESH_MRM_SKINNED_NORMAL_FACTOR);
00427                 dest.z = (float)Nz * (1.f/NL3D_MESH_MRM_SKINNED_NORMAL_FACTOR);
00428             }
00429             inline void getU (float &_u) const
00430             {
00431                 _u = (float)U * (1.f/NL3D_MESH_MRM_SKINNED_UV_FACTOR);
00432             }
00433             inline void getV (float &_v) const
00434             {
00435                 _v = (float)V * (1.f/NL3D_MESH_MRM_SKINNED_UV_FACTOR);
00436             }
00437             inline void getWeight (float &dest, uint index) const
00438             {
00439                 dest = (float)Weights[index] * (1.f/NL3D_MESH_MRM_SKINNED_WEIGHT_FACTOR);
00440             }
00441 
00442             // Compact it
00443             void setNormal (const CVector &pos);
00444             void setUV (float _u, float _v);
00445             void setWeight (uint weightId, float weight);
00446             void setPos (const CVector &pos, float scaleFactor);
00447 
00448             // Serial it
00449             void serial(NLMISC::IStream &f);
00450         };
00451 
00452         // Build it
00453         void build (const CVertexBuffer &buffer, const std::vector<CMesh::CSkinWeight> &skinWeight);
00454 
00455         // Clear it
00456         void clear ()
00457         {
00458             _PackedBuffer.clear();
00459         }
00460 
00461         // Reset
00462         void contReset()
00463         {
00464             NLMISC::contReset (_PackedBuffer);
00465         }
00466 
00467         // Access it
00468         const CPackedVertex *getPackedVertices() const
00469         {
00470             if (_PackedBuffer.empty())
00471                 return NULL;
00472             else
00473                 return &(_PackedBuffer[0]);
00474         }
00475 
00476         // Access it
00477         CPackedVertex   *getPackedVertices()
00478         {
00479             if (_PackedBuffer.empty())
00480                 return NULL;
00481             else
00482                 return &(_PackedBuffer[0]);
00483         }
00484 
00485         // Acces it
00486         uint getNumVertices() const
00487         {
00488             return _PackedBuffer.size();
00489         }
00490 
00491         // Decompact position
00492         inline void getPos (CVector &dest, const CPackedVertex &src) const
00493         {
00494             src.getPos (dest, _DecompactScale);
00495         }
00496 
00497         // Serialize it
00498         void serial(NLMISC::IStream &f);
00499 
00500     private:
00502         float                       _DecompactScale;
00503 
00504         //
00505         std::vector<CPackedVertex>  _PackedBuffer;
00506     };
00507 
00508 private:
00509 
00510     // The packed vertex buffer
00511     CPackedVertexBuffer         _VBufferFinal;
00512 
00514     bool                        _BoneIdComputed;
00516     bool                        _BoneIdExtended;
00517 
00519     uint8                       _LastLodComputed;
00520 
00522     std::vector<std::string>    _BonesName;
00524     std::vector<sint32>         _BonesId;
00526     std::vector<sint32>         _BonesIdExt;
00528     std::vector<NLMISC::CBSphere>   _BonesSphere;
00529 
00531     std::vector<CLod>           _Lods;
00533     NLMISC::CAABBoxExt          _BBox;
00534 
00535 
00537     // @{
00538     CMRMLevelDetail             _LevelDetail;
00539     // @}
00540 
00541 
00543     // @{
00544 
00546     bool                        _PreciseClipping;
00547 
00548     // @}
00549 
00551     // @{
00552     CShadowSkin                     _ShadowSkin;
00553     bool                            _SupportShadowSkinGrouping;
00554     // @}
00555 
00556 private:
00557 
00559     sint    chooseLod(float alphaMRM, float &alphaLod);
00560 
00562     void    applyGeomorph(std::vector<CMRMWedgeGeom>  &geoms, float alphaLod);
00563 
00565     void    applyGeomorphWithVBHardPtr(std::vector<CMRMWedgeGeom>  &geoms, float alphaLod);
00566 
00568     void    applyGeomorphPosNormalUV0Int(std::vector<CMRMWedgeGeom>  &geoms, uint8 *vertexPtr, uint8 *vertexDestPtr, sint32 vertexSize, sint a, sint a1);
00569 
00571     void    applyGeomorphPosNormalUV0(std::vector<CMRMWedgeGeom>  &geoms, uint8 *vertexPtr, uint8 *vertexDestPtr, sint32 vertexSize, float a, float a1);
00572 
00576     void    applyRawSkinWithNormal(CLod &lod, CRawSkinnedNormalCache &rawSkinLod, const CSkeletonModel *skeleton, uint8 *vbHard, float alphaLod);
00577 
00578     // Some runtime not serialized compilation
00579     void        compileRunTime();
00580 
00581     // SkinGroup
00582     void        updateShiftedTriangleCache(CMeshMRMSkinnedInstance *mi, sint curLodId, uint baseVertex);
00583 
00584 private:
00585 
00587     // @{
00588 
00590     uint        _MeshDataId;
00591 
00593     void        updateRawSkinNormal(bool enabled, CMeshMRMSkinnedInstance *mi, sint curLodId);
00595     void        dirtMeshDataId();
00596 
00597     // ApplySkin method
00598     void        applyArrayRawSkinNormal1(CRawVertexNormalSkinned1 *src, uint8 *destVertexPtr,
00599         CMatrix3x4 *boneMat3x4, uint nInf);
00600     void        applyArrayRawSkinNormal2(CRawVertexNormalSkinned2 *src, uint8 *destVertexPtr,
00601         CMatrix3x4 *boneMat3x4, uint nInf);
00602     void        applyArrayRawSkinNormal3(CRawVertexNormalSkinned3 *src, uint8 *destVertexPtr,
00603         CMatrix3x4 *boneMat3x4, uint nInf);
00604     void        applyArrayRawSkinNormal4(CRawVertexNormalSkinned4 *src, uint8 *destVertexPtr,
00605         CMatrix3x4 *boneMat3x4, uint nInf);
00606 
00607 
00608 public:
00609     static  uint    NumCacheVertexNormal1;
00610     static  uint    NumCacheVertexNormal2;
00611     static  uint    NumCacheVertexNormal3;
00612     static  uint    NumCacheVertexNormal4;
00613 
00614     // @}
00615 };
00616 
00617 
00618 
00619 // ***************************************************************************
00634 class CMeshMRMSkinned : public CMeshBase
00635 {
00636 public:
00638     CMeshMRMSkinned();
00639 
00643     static bool     isCompatible(const CMesh::CMeshBuild &m);
00644 
00650     void            build ( CMeshBase::CMeshBaseBuild &mBase, CMesh::CMeshBuild &m,
00651                             const CMRMParameters &params= CMRMParameters() );
00652 
00658     void            build (CMeshBase::CMeshBaseBuild &m, const CMeshMRMSkinnedGeom &mgeom);
00659 
00664     void            optimizeMaterialUsage(std::vector<sint> &remap);
00665 
00666 
00668     void            computeBonesId (CSkeletonModel *skeleton);
00669 
00671     void            updateSkeletonUsage(CSkeletonModel *sm, bool increment);
00672 
00679     void            changeMRMDistanceSetup(float distanceFinest, float distanceMiddle, float distanceCoarsest);
00680 
00682     // @{
00683 
00685     virtual CTransformShape     *createInstance(CScene &scene);
00686 
00688     virtual bool    clip(const std::vector<CPlane>  &pyramid, const CMatrix &worldMatrix) ;
00689 
00691     virtual void    render(IDriver *drv, CTransformShape *trans, bool passOpaque);
00692 
00694     virtual float   getNumTriangles (float distance);
00695 
00697     virtual void    serial(NLMISC::IStream &f);
00698     NLMISC_DECLARE_CLASS(CMeshMRMSkinned);
00699 
00701     virtual void    getAABBox(NLMISC::CAABBox &bbox) const {bbox= getBoundingBox().getAABBox();}
00702 
00704     virtual void    profileSceneRender(CRenderTrav *rdrTrav, CTransformShape *trans, bool opaquePass);
00705 
00706     // @}
00707 
00708 
00710     // @{
00711 
00713     const NLMISC::CAABBoxExt& getBoundingBox() const
00714     {
00715         return _MeshMRMGeom.getBoundingBox();
00716     }
00717 
00719     void getVertexBuffer(CVertexBuffer &output) const { _MeshMRMGeom.getVertexBuffer(output); }
00720 
00721 
00724     uint getNbLod() const { return _MeshMRMGeom.getNbLod()  ; }
00725 
00726 
00730     uint getNbRdrPass(uint lodId) const { return _MeshMRMGeom.getNbRdrPass(lodId) ; }
00731 
00732 
00737     void getRdrPassPrimitiveBlock(uint lodId, uint renderingPassIndex, CIndexBuffer &block) const
00738     {
00739         _MeshMRMGeom.getRdrPassPrimitiveBlock(lodId, renderingPassIndex, block);
00740     }
00741 
00742 
00747     uint32 getRdrPassMaterial(uint lodId, uint renderingPassIndex) const
00748     {
00749         return _MeshMRMGeom.getRdrPassMaterial(lodId, renderingPassIndex) ;
00750     }
00751 
00753     const CMeshMRMSkinnedGeom& getMeshGeom () const;
00754 
00755     // @}
00756 
00757 
00759     // @{
00760     virtual IMeshGeom   *supportMeshBlockRendering (CTransformShape *trans, float &polygonCount ) const;
00761     // @}
00762 
00763 
00764 // ************************
00765 private:
00766 
00767     CMeshMRMSkinnedGeom     _MeshMRMGeom;
00768 
00769 
00770 };
00771 
00772 
00773 } // NL3D
00774 
00775 
00776 #endif // NL_MESH_MRM_SKINNED_H
00777 
00778 /* End of mesh_mrm_skinned.h */

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