00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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 ¶ms= 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
00283 uint32 MaterialId;
00284
00285 CPrimitiveBlock PBlock;
00286
00287
00288
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
00303 uint32 VertexStart;
00304
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
00344 OriginalSkinRestored= false;
00345 }
00346
00347
00348 void serial(NLMISC::IStream &f);
00349
00350
00351 void buildSkinVertexBlocks();
00352 void optimizeTriangleOrder();
00353 };
00354
00355 friend class CLod;
00356
00360 struct CMeshBuildMRM
00361 {
00362
00363 bool Skinned;
00364
00365
00366 std::vector<CMesh::CSkinWeight> SkinWeights;
00367
00368
00369 CVertexBuffer VBuffer;
00370
00371
00372 std::vector<CLod> Lods;
00373
00374
00375 std::vector<CBlendShape> BlendShapes;
00376
00378
00380
00382
00384
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
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
00471 CRefPtr<IDriver> _Driver;
00472 bool _VertexBufferHardDirty;
00473
00475 bool _PreciseClipping;
00476
00477
00478
00479
00480 void updateVertexBufferHard(IDriver *drv, uint32 numVertices);
00481 void deleteVertexBufferHard();
00482
00483
00484 void fillAGPSkinPartWithVBHardPtr(CLod &lod, uint8 *vertexDst);
00485
00486
00487
00488
00489 CMeshMorpher _MeshMorpher;
00490
00491
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
00546 void buildBoneUsageVer2 ();
00547
00548
00549 void compileRunTime();
00550
00551
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
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
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 ¶ms= 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 }
00738
00739
00740 #endif // NL_MESH_MRM_H
00741
00742