From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/a02878.html | 5263 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 5263 insertions(+) create mode 100644 docs/doxygen/nel/a02878.html (limited to 'docs/doxygen/nel/a02878.html') diff --git a/docs/doxygen/nel/a02878.html b/docs/doxygen/nel/a02878.html new file mode 100644 index 00000000..631f409c --- /dev/null +++ b/docs/doxygen/nel/a02878.html @@ -0,0 +1,5263 @@ + + +NeL: NL3D::CMeshGeom class Reference + + + +
+

NL3D::CMeshGeom Class Reference

#include <mesh.h> +

+

Inheritance diagram for NL3D::CMeshGeom: +

+ +NL3D::IMeshGeom +NLMISC::IStreamable +NLMISC::IClassable + +

Detailed Description

+A mesh geometry. Skinning support: support only palette skinning.
Author:
Lionel Berenguier

+Nevrax France

+
Date:
2000
+ +

+ +

+Definition at line 335 of file mesh.h. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Mesh Block Render Implementation

enum  TMBRSupport { MBROk = 1, +MBRSortPerMaterial = 2, +MBRCurrentUseVP = 4 + }
 setuped at compileRunTime. More...

uint8 _SupportMBRFlags
 setuped at compileRunTime.


Skinning

enum  TSkinType { SkinPosOnly = 0, +SkinWithNormal, +SkinWithTgSpace + }
void applySkin (CSkeletonModel *skeleton)
void bkupOriginalSkinVertices ()
void buildBoneUsageVer3 ()
void buildSkin (CMesh::CMeshBuild &m, std::vector< CFaceTmp > &tmpFaces)
void computeSkinMatrixes (CSkeletonModel *skeleton, CMatrix3x4 *matrixes, CMatrixBlock *prevBlock, CMatrixBlock &curBlock)
void computeSoftwarePointSkinning (CMatrix3x4 *matrixes, CVector *srcVector, CPaletteSkin *srcPal, float *srcWgt, CVector *dstVector)
void computeSoftwareVectorSkinning (CMatrix3x4 *matrixes, CVector *srcVector, CPaletteSkin *srcPal, float *srcWgt, CVector *dstVector)
void flagSkinVerticesForMatrixBlock (uint8 *skinFlags, CMatrixBlock &mb)
void restoreOriginalSkinVertices ()

VBufferHard mgt.

void updateVertexBufferHard (IDriver *drv)
 update the VertexBufferHard if NULL (ie not created or deleted by driver) or if VertexBufferDirty.

CRefPtr< IDriver_Driver
 This is the driver used to setup the vbuffer hard. error if a mesh has not the same driver in his life.

CRefPtr< IVertexBufferHard_VertexBufferHard
 The only one VBufferHard of the mesh. NULL by default.

bool _VertexBufferHardDirty
 This tells if the VBuffer has changed since the last time or not.


Public Types

enum  TRenderFlag {
+  RenderOpaqueMaterial = 1, +RenderTransparentMaterial = 2, +RenderPassOpaque = 4, +RenderGlobalAlpha = 8, +
+  RenderGADisableZWrite = 16 +
+ }
 Render Flags, used in render. More...


Public Member Functions

void applyMaterialRemap (const std::vector< sint > &remap)
 change materials Ids (called from CMesh::optimizeMaterialUsage())

void build (CMesh::CMeshBuild &mbuild, uint numMaxMaterial)
 Build a meshGeom.

 CMeshGeom ()
 Constructor.

virtual std::string getClassName ()=0
virtual bool hasMeshVertexProgram () const
 True if this mesh has a vertexProgram.

void renderSimpleWithMaterial (IDriver *drv, const CMatrix &worldMatrix, CMaterial &mat)
void setBlendShapes (std::vector< CBlendShape > &bs)
virtual ~CMeshGeom ()
Mesh Block Render Implementation
virtual void activeInstance (CMeshGeomRenderContext &rdrCtx, CMeshBaseInstance *inst, float polygonCount, void *vbDst)
virtual void beginMesh (CMeshGeomRenderContext &rdrCtx)
virtual void computeMeshVBHeap (void *dst, uint indexStart)
virtual void endMesh (CMeshGeomRenderContext &rdrCtx)
virtual uint getNumRdrPassesForInstance (CMeshBaseInstance *inst) const
virtual uint getNumRdrPassesForMesh () const
virtual bool getVBHeapInfo (uint &vertexFormat, uint &numVertices)
virtual void renderPass (CMeshGeomRenderContext &rdrCtx, CMeshBaseInstance *inst, float polygonCount, uint rdrPass)
virtual bool sortPerMaterial () const
virtual bool supportMeshBlockRendering () const
From IMeshGeom
virtual bool clip (const std::vector< CPlane > &pyramid, const CMatrix &worldMatrix)
 clip this mesh

virtual float getNumTriangles (float distance)
 clip this mesh

virtual void initInstance (CMeshBaseInstance *mbi)
 Init instance info.

 NLMISC_DECLARE_CLASS (CMeshGeom)
 clip this mesh

virtual void profileSceneRender (CRenderTrav *rdrTrav, CTransformShape *trans, float polygonCount, uint32 rdrFlags)
 clip this mesh

virtual void render (IDriver *drv, CTransformShape *trans, float polygonCount, uint32 rdrFlags, float globalAlpha)
 render() this mesh in a driver.

virtual void renderSkin (CTransformShape *trans, float alphaMRM)
 render() this mesh as a skin

virtual void serial (NLMISC::IStream &f) throw (NLMISC::EStream)
 serial this mesh.

Skinning Behavior
void computeBonesId (CSkeletonModel *skeleton)
 Compute skinning id.

const std::vector< sint32 > & getSkinBoneUsage () const
 return array of bones used by the skin. computeBonesId must has been called before.

bool isSkinned () const
 Return true if the mesh is skinned, else return false.

void updateSkeletonUsage (CSkeletonModel *sm, bool increment)
 update Skeleton Usage. increment or decrement. computeBonesId must has been called before.

Geometry accessors
const NLMISC::CAABBoxExtgetBoundingBox () const
 get the extended axis aligned bounding box of the mesh

uint getNbBlendShapes () const
 get the number of BlendShapes

uint getNbMatrixBlock () const
 get the number of matrix block

uint getNbRdrPass (uint matrixBlockIndex) const
uint32 getRdrPassMaterial (uint matrixBlockIndex, uint renderingPassIndex) const
const CPrimitiveBlockgetRdrPassPrimitiveBlock (uint matrixBlockIndex, uint renderingPassIndex) const
const CVertexBuffergetVertexBuffer () const
 get the vertex buffer used by the mesh


Private Types

typedef TBoneMap::iterator ItBoneMap
typedef TCornerSet::iterator ItCornerSet
typedef std::map< uint, CBoneTmpTBoneMap
typedef std::set< CCornerTmp *,
+ CCornerPred
TCornerSet

Private Member Functions

void compileRunTime ()
void findVBId (TCornerSet &corners, const CCornerTmp *corn, sint &currentVBIndex, const CVector &vert, const CMesh::CMeshBuild &mb)
void optimizeTriangleOrder ()

Private Attributes

NLMISC::CAABBoxExt _BBox
 For clipping.

bool _BoneIdComputed
 This boolean is true if the bones id have been passed in the skeleton.

bool _BoneIdExtended
 true if the _BonesIdExt have been computed (for bone Usage).

std::vector< sint32_BonesId
 This array give the index in the skeleton of the local bones used. computed at first computeBoneId().

std::vector< sint32_BonesIdExt
 Same as _BonesId but with parent of bones added. (used for bone usage).

std::vector< std::string > _BonesName
 This array give the name of the local bones used.

std::vector< CMatrixBlock_MatrixBlocks
 The matrix blocks.

CMeshMorpher_MeshMorpher
NLMISC::CSmartPtr< IMeshVertexProgram_MeshVertexProgram
std::vector< CVector_OriginalSkinNormals
bool _OriginalSkinRestored
 This tells if the mesh VBuffer has coorect BindPos vertices.

std::vector< CVector_OriginalSkinVertices
std::vector< CVector_OriginalTGSpace
bool _PreciseClipping
 Estimate if we must do a Precise clipping (ie with bboxes).

bool _Skinned
 This tells if the mesh is correctly skinned.

CVertexBuffer _VBuffer
 VBuffer of the mesh (potentially modified by the mesh morpher and skinning).

CVertexBuffer _VBufferOri
 The original VBuffer of the mesh used only if there are blend shapes.

+


Member Typedef Documentation

+

+ + + + +
+ + +
typedef TBoneMap::iterator NL3D::CMeshGeom::ItBoneMap [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 606 of file mesh.h. +

+Referenced by buildSkin().

+

+ + + + +
+ + +
typedef TCornerSet::iterator NL3D::CMeshGeom::ItCornerSet [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 730 of file mesh.h. +

+Referenced by findVBId().

+

+ + + + +
+ + +
typedef std::map<uint, CBoneTmp> NL3D::CMeshGeom::TBoneMap [private] +
+
+ + + + + +
+   + + +

+Just for build process. A map of Bone. +

+Definition at line 605 of file mesh.h. +

+Referenced by buildSkin().

+

+ + + + +
+ + +
typedef std::set<CCornerTmp*, CCornerPred> NL3D::CMeshGeom::TCornerSet [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 729 of file mesh.h. +

+Referenced by build(), and findVBId().

+


Member Enumeration Documentation

+

+ + + + +
+ + +
enum NL3D::CMeshGeom::TMBRSupport [private] +
+
+ + + + + +
+   + + +

+setuped at compileRunTime. +

+

Enumeration values:
+ + + + +
MBROk  +
MBRSortPerMaterial  +
MBRCurrentUseVP  +
+
+ +

+Definition at line 698 of file mesh.h. +

+

00699         {
+00700                 MBROk= 1,
+00701                 MBRSortPerMaterial= 2,
+00702                 MBRCurrentUseVP= 4,
+00703         };
+
+

+ + + + +
+ + +
enum NL3D::IMeshGeom::TRenderFlag [inherited] +
+
+ + + + + +
+   + + +

+Render Flags, used in render. +

+

Enumeration values:
+ + + + + + +
RenderOpaqueMaterial  +
RenderTransparentMaterial  +
RenderPassOpaque  +
RenderGlobalAlpha  +
RenderGADisableZWrite  +
+
+ +

+Definition at line 82 of file mesh_geom.h. +

+

00083         {
+00084                 RenderOpaqueMaterial= 1,                // set when the mesh geom must render opaque material
+00085                 RenderTransparentMaterial= 2,   // set when the mesh geom must render transparent material
+00086                 RenderPassOpaque=4,                             // set when the current traversal rdrPass is the opaque pass
+00087                 RenderGlobalAlpha= 8,                   // set when the caller wants to draw material with global alpha
+00088                 RenderGADisableZWrite= 16,              // only when globalAlpha is used. set if must disable ZWrite
+00089         };
+
+

+ + + + +
+ + +
enum NL3D::CMeshGeom::TSkinType [private] +
+
+ + + + + +
+   + + +

+

Enumeration values:
+ + + + +
SkinPosOnly  +
SkinWithNormal  +
SkinWithTgSpace  +
+
+ +

+Definition at line 799 of file mesh.h. +

+Referenced by applySkin(). +

+

+


Constructor & Destructor Documentation

+

+ + + + +
+ + + + + + + + + +
NL3D::CMeshGeom::CMeshGeom  ) 
+
+ + + + + +
+   + + +

+Constructor. +

+ +

+Definition at line 123 of file mesh.cpp. +

+References _BoneIdComputed, _BoneIdExtended, _MeshMorpher, _OriginalSkinRestored, _PreciseClipping, _Skinned, and _VertexBufferHardDirty. +

+

00124 {
+00125         _Skinned= false;
+00126         _OriginalSkinRestored= true;
+00127         _VertexBufferHardDirty= true;
+00128         _MeshMorpher = new CMeshMorpher;
+00129         _BoneIdComputed = false;
+00130         _BoneIdExtended= false;
+00131         _PreciseClipping= false;
+00132 }
+
+

+ + + + +
+ + + + + + + + + +
NL3D::CMeshGeom::~CMeshGeom  )  [virtual]
+
+ + + + + +
+   + + +

+ +

+Definition at line 136 of file mesh.cpp. +

+References _MeshMorpher, _VertexBufferHard, and nlassert. +

+

00137 {
+00138         // test (refptr) if the object still exist in memory.
+00139         if(_VertexBufferHard!=NULL)
+00140         {
+00141                 // A vbufferhard should still exist only if driver still exist.
+00142                 nlassert(_Driver!=NULL);
+00143 
+00144                 // delete it from driver.
+00145                 _Driver->deleteVertexBufferHard(_VertexBufferHard);
+00146                 _VertexBufferHard= NULL;
+00147         }
+00148         delete _MeshMorpher;
+00149 }
+
+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::activeInstance CMeshGeomRenderContext rdrCtx,
CMeshBaseInstance inst,
float  polygonCount,
void *  vbDst
[virtual]
+
+ + + + + +
+   + + +

+The framework call this method any time a change of instance occurs. +

+Implements NL3D::IMeshGeom. +

+Definition at line 2058 of file mesh.cpp. +

+References _MeshVertexProgram, _SupportMBRFlags, NL3D::CTransformShape::changeLightSetup(), NL3D::CMeshGeomRenderContext::Driver, NL3D::CTransform::getWorldMatrix(), NLMISC::CMatrix::inverted(), MBRCurrentUseVP, NL3D::CMeshGeomRenderContext::RenderTrav, NL3D::CMeshGeomRenderContext::Scene, and NL3D::IDriver::setupModelMatrix(). +

+

02059 {
+02060         // setup instance matrix
+02061         rdrCtx.Driver->setupModelMatrix(inst->getWorldMatrix());
+02062 
+02063         // setupLighting.
+02064         inst->changeLightSetup(rdrCtx.RenderTrav);
+02065 
+02066         // MeshVertexProgram ?
+02067         if( _SupportMBRFlags & MBRCurrentUseVP )
+02068         {
+02069                 CMatrix         invertedObjectMatrix;
+02070                 invertedObjectMatrix = inst->getWorldMatrix().inverted();
+02071                 _MeshVertexProgram->beginMBRInstance(rdrCtx.Driver, rdrCtx.Scene, inst, invertedObjectMatrix);
+02072         }
+02073 }
+
+

+ + + + +
+ + + + + + + + + + +
void NL3D::CMeshGeom::applyMaterialRemap const std::vector< sint > &  remap  ) 
+
+ + + + + +
+   + + +

+change materials Ids (called from CMesh::optimizeMaterialUsage()) +

+ +

+Definition at line 458 of file mesh.cpp. +

+References _MatrixBlocks, getNbMatrixBlock(), getNbRdrPass(), nlassert, uint, and uint32. +

+Referenced by NL3D::CMesh::optimizeMaterialUsage(). +

+

00459 {
+00460         for(uint mb=0;mb<getNbMatrixBlock();mb++)
+00461         {
+00462                 for(uint rp=0;rp<getNbRdrPass(mb);rp++)
+00463                 {
+00464                         // remap
+00465                         uint32  &matId= _MatrixBlocks[mb].RdrPass[rp].MaterialId;
+00466                         nlassert(remap[matId]>=0);
+00467                         matId= remap[matId];
+00468                 }
+00469         }
+00470 }
+
+

+ + + + +
+ + + + + + + + + + +
void NL3D::CMeshGeom::applySkin CSkeletonModel skeleton  )  [private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1715 of file mesh.cpp. +

+References _MatrixBlocks, _OriginalSkinNormals, _OriginalSkinRestored, _OriginalSkinVertices, _OriginalTGSpace, computeSkinMatrixes(), computeSoftwarePointSkinning(), computeSoftwareVectorSkinning(), flagSkinVerticesForMatrixBlock(), NL3D::CVertexBuffer::getNormalCoordPointer(), NL3D::CVertexBuffer::getNumTexCoordUsed(), NL3D::CVertexBuffer::getPaletteSkinPointer(), NL3D::CVertexBuffer::getTexCoordPointer(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexSize(), NL3D::CVertexBuffer::getWeightPointer(), NL3D::CPaletteSkin::MatrixId, NL3D_SOFTSKIN_VCOMPUTED, NL3D_SOFTSKIN_VMUSTCOMPUTE, NL3D_SOFTSKIN_VNEEDCOMPUTE, nlassert, size, SkinPosOnly, SkinWithNormal, SkinWithTgSpace, TSkinType, uint, and uint8. +

+Referenced by renderSkin(). +

+

01716 {
+01717         // init.
+01718         //===================
+01719         if(_OriginalSkinVertices.empty())
+01720                 return;
+01721 
+01722         // Use correct skinning
+01723         TSkinType       skinType;
+01724         if( _OriginalSkinNormals.empty() )
+01725                 skinType= SkinPosOnly;
+01726         else if( _OriginalTGSpace.empty() )
+01727                 skinType= SkinWithNormal;
+01728         else
+01729                 skinType= SkinWithTgSpace;
+01730 
+01731         // Get VB src/dst info/ptrs.
+01732         uint    numVertices= _OriginalSkinVertices.size();
+01733         uint    dstStride= _VBuffer.getVertexSize();
+01734         // Get dst TgSpace.
+01735         uint    tgSpaceStage = 0;
+01736         if( skinType>= SkinWithTgSpace)
+01737         {
+01738                 nlassert(_VBuffer.getNumTexCoordUsed() > 0);
+01739                 tgSpaceStage= _VBuffer.getNumTexCoordUsed() - 1;
+01740         }
+01741 
+01742         // Mark all vertices flag to not computed.
+01743         static  vector<uint8>   skinFlags;
+01744         skinFlags.resize(numVertices);
+01745         // reset all flags
+01746         memset(&skinFlags[0], NL3D_SOFTSKIN_VNEEDCOMPUTE, numVertices );
+01747 
+01748 
+01749         // For all MatrixBlocks
+01750         //===================
+01751         for(uint mb= 0; mb<_MatrixBlocks.size();mb++)
+01752         {
+01753                 // compute matrixes for this block.
+01754                 static  CMatrix3x4      matrixes[IDriver::MaxModelMatrix];
+01755                 computeSkinMatrixes(skeleton, matrixes, mb==0?NULL:&_MatrixBlocks[mb-1], _MatrixBlocks[mb]);
+01756 
+01757                 // check what vertex to skin for this PB.
+01758                 flagSkinVerticesForMatrixBlock(&skinFlags[0], _MatrixBlocks[mb]);
+01759 
+01760                 // Get VB src/dst ptrs.
+01761                 uint8           *pFlag= &skinFlags[0];
+01762                 CVector         *srcVector= &_OriginalSkinVertices[0];
+01763                 uint8           *srcPal= (uint8*)_VBuffer.getPaletteSkinPointer(0);
+01764                 uint8           *srcWgt= (uint8*)_VBuffer.getWeightPointer(0);
+01765                 uint8           *dstVector= (uint8*)_VBuffer.getVertexCoordPointer(0);
+01766                 // Normal.
+01767                 CVector         *srcNormal= NULL;
+01768                 uint8           *dstNormal= NULL;
+01769                 if(skinType>=SkinWithNormal)
+01770                 {
+01771                         srcNormal= &_OriginalSkinNormals[0];
+01772                         dstNormal= (uint8*)_VBuffer.getNormalCoordPointer(0);
+01773                 }
+01774                 // TgSpace.
+01775                 CVector         *srcTgSpace= NULL;
+01776                 uint8           *dstTgSpace= NULL;
+01777                 if(skinType>=SkinWithTgSpace)
+01778                 {
+01779                         srcTgSpace= &_OriginalTGSpace[0];
+01780                         dstTgSpace= (uint8*)_VBuffer.getTexCoordPointer(0, tgSpaceStage);
+01781                 }
+01782 
+01783 
+01784                 // For all vertices that need to be computed.
+01785                 uint            size= numVertices;
+01786                 for(;size>0;size--)
+01787                 {
+01788                         // If we must compute this vertex.
+01789                         if(*pFlag==NL3D_SOFTSKIN_VMUSTCOMPUTE)
+01790                         {
+01791                                 // Flag this vertex as computed.
+01792                                 *pFlag=NL3D_SOFTSKIN_VCOMPUTED;
+01793 
+01794                                 CPaletteSkin    *psPal= (CPaletteSkin*)srcPal;
+01795 
+01796                                 // checks indices.
+01797                                 nlassert(psPal->MatrixId[0]<IDriver::MaxModelMatrix);
+01798                                 nlassert(psPal->MatrixId[1]<IDriver::MaxModelMatrix);
+01799                                 nlassert(psPal->MatrixId[2]<IDriver::MaxModelMatrix);
+01800                                 nlassert(psPal->MatrixId[3]<IDriver::MaxModelMatrix);
+01801 
+01802                                 // compute vertex part.
+01803                                 computeSoftwarePointSkinning(matrixes, srcVector, psPal, (float*)srcWgt, (CVector*)dstVector);
+01804 
+01805                                 // compute normal part.
+01806                                 if(skinType>=SkinWithNormal)
+01807                                         computeSoftwareVectorSkinning(matrixes, srcNormal, psPal, (float*)srcWgt, (CVector*)dstNormal);
+01808 
+01809                                 // compute tg part.
+01810                                 if(skinType>=SkinWithTgSpace)
+01811                                         computeSoftwareVectorSkinning(matrixes, srcTgSpace, psPal, (float*)srcWgt, (CVector*)dstTgSpace);
+01812                         }
+01813 
+01814                         // inc flags.
+01815                         pFlag++;
+01816                         // inc src (all whatever skin type used...)
+01817                         srcVector++;
+01818                         srcNormal++;
+01819                         srcTgSpace++;
+01820                         // inc paletteSkin and dst  (all whatever skin type used...)
+01821                         srcPal+= dstStride;
+01822                         srcWgt+= dstStride;
+01823                         dstVector+= dstStride;
+01824                         dstNormal+= dstStride;
+01825                         dstTgSpace+= dstStride;
+01826                 }
+01827         }
+01828 
+01829 
+01830         // dirt
+01831         _OriginalSkinRestored= false;
+01832 }
+
+

+ + + + +
+ + + + + + + + + + +
void NL3D::CMeshGeom::beginMesh CMeshGeomRenderContext rdrCtx  )  [virtual]
+
+ + + + + +
+   + + +

+The framework call this method when he will render instances of this meshGeom soon. +

+Implements NL3D::IMeshGeom. +

+Definition at line 2021 of file mesh.cpp. +

+References _MeshVertexProgram, _SupportMBRFlags, _VertexBufferHard, NL3D::IDriver::activeVertexBuffer(), NL3D::IDriver::activeVertexBufferHard(), NL3D::CMeshGeomRenderContext::Driver, MBRCurrentUseVP, nlassert, NL3D::CMeshGeomRenderContext::RenderThroughVBHeap, NL3D::CMeshGeomRenderContext::Scene, and updateVertexBufferHard(). +

+

02022 {
+02023         if(rdrCtx.RenderThroughVBHeap)
+02024         {
+02025                 // Don't setup VB in this case, since use the VBHeap setuped one.
+02026                 // NB: no VertexProgram test since VBHeap not possible with it...
+02027                 nlassert( (_SupportMBRFlags & MBRCurrentUseVP)==0 );
+02028         }
+02029         else
+02030         {
+02031                 // update the VBufferHard (create/delete), to maybe render in AGP memory.
+02032                 updateVertexBufferHard ( rdrCtx.Driver );
+02033 
+02034                 // use MeshVertexProgram effect?
+02035                 if( _MeshVertexProgram != NULL && _MeshVertexProgram->isMBRVpOk(rdrCtx.Driver) )
+02036                 {
+02037                         // Ok will use it.
+02038                         _SupportMBRFlags|= MBRCurrentUseVP;
+02039                         // Before VB activation
+02040                         _MeshVertexProgram->beginMBRMesh(rdrCtx.Driver, rdrCtx.Scene );
+02041                 }
+02042 
+02043 
+02044                 // if VB Hard is here, use it.
+02045                 if(_VertexBufferHard != NULL)
+02046                 {
+02047                         // active VB Hard.
+02048                         rdrCtx.Driver->activeVertexBufferHard(_VertexBufferHard);
+02049                 }
+02050                 else
+02051                 {
+02052                         // active VB. SoftwareSkinning: reset flags for skinning.
+02053                         rdrCtx.Driver->activeVertexBuffer(_VBuffer);
+02054                 }
+02055         }
+02056 }
+
+

+ + + + +
+ + + + + + + + + +
void NL3D::CMeshGeom::bkupOriginalSkinVertices  )  [private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1615 of file mesh.cpp. +

+References _MeshVertexProgram, _OriginalSkinNormals, _OriginalSkinVertices, _OriginalTGSpace, _Skinned, NL3D::CVertexBuffer::getNormalCoordPointer(), NL3D::CVertexBuffer::getNumTexCoordUsed(), NL3D::CVertexBuffer::getNumVertices(), NL3D::CVertexBuffer::getTexCoordPointer(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexFormat(), nlassert, and uint. +

+Referenced by compileRunTime(). +

+

01616 {
+01617         nlassert(_Skinned);
+01618 
+01619         // reset
+01620         contReset(_OriginalSkinVertices);
+01621         contReset(_OriginalSkinNormals);
+01622         contReset(_OriginalTGSpace);
+01623 
+01624         // get num of vertices
+01625         uint    numVertices= _VBuffer.getNumVertices();
+01626 
+01627         // Copy VBuffer content into Original vertices normals.
+01628         if(_VBuffer.getVertexFormat() & CVertexBuffer::PositionFlag)
+01629         {
+01630                 // copy vertices from VBuffer. (NB: unusefull geomorphed vertices are still copied, but doesn't matter).
+01631                 _OriginalSkinVertices.resize(numVertices);
+01632                 for(uint i=0; i<numVertices;i++)
+01633                 {
+01634                         _OriginalSkinVertices[i]= *(CVector*)_VBuffer.getVertexCoordPointer(i);
+01635                 }
+01636         }
+01637         if(_VBuffer.getVertexFormat() & CVertexBuffer::NormalFlag)
+01638         {
+01639                 // copy normals from VBuffer. (NB: unusefull geomorphed normals are still copied, but doesn't matter).
+01640                 _OriginalSkinNormals.resize(numVertices);
+01641                 for(uint i=0; i<numVertices;i++)
+01642                 {
+01643                         _OriginalSkinNormals[i]= *(CVector*)_VBuffer.getNormalCoordPointer(i);
+01644                 }
+01645         }
+01646 
+01647         // is there tangent space added ?
+01648         if (_MeshVertexProgram && _MeshVertexProgram->needTangentSpace())
+01649         {
+01650                 // yes, backup it
+01651                 nlassert(_VBuffer.getNumTexCoordUsed() > 0);
+01652                 uint tgSpaceStage = _VBuffer.getNumTexCoordUsed() - 1;
+01653                 _OriginalTGSpace.resize(numVertices);
+01654                 for(uint i=0; i<numVertices;i++)
+01655                 {
+01656                         _OriginalTGSpace[i]= *(CVector*)_VBuffer.getTexCoordPointer(i, tgSpaceStage);
+01657                 }
+01658         }
+01659 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::build CMesh::CMeshBuild m,
uint  numMaxMaterial
+
+ + + + + +
+   + + +

+Build a meshGeom. +

+0. First, make bbox.

+1. If skinning, group by matrix Block the vertices.

+2. Then, for all faces, resolve continuities, building VBuffer.

+3. build the RdrPass material.

+4. Then, for all faces, build the RdrPass PBlock.

+5. Remove empty RdrPasses.

+6. Misc.

+7. Compact bones id and build bones name array. +

+If all texture coordinates are of dimension 2, we can setup the flags as before. If this isn't the case, we must setup a custom format

+

Todo:
yoyo: TODO_OPTIMIZE: it should be interesting to sort the materials, depending on their attributes. But must change next loop too...
+ +

+Definition at line 172 of file mesh.cpp. +

+References _BoneIdComputed, _BoneIdExtended, _BonesName, _MatrixBlocks, _MeshMorpher, _MeshVertexProgram, _Skinned, _VertexBufferHardDirty, NL3D::CVertexBuffer::addValueEx(), NL3D::CMesh::CMeshBuild::BlendShapes, NL3D::CMeshMorpher::BlendShapes, NL3D::CMesh::CMeshBuild::BonesNames, buildSkin(), NL3D::CVertexBuffer::clearValueEx(), compileRunTime(), NL3D::CMeshGeom::CFaceTmp::Corner, NL3D::CMesh::CMeshBuild::Faces, findVBId(), NL3D::CVertexBuffer::initEx(), NL3D::makeBBox(), NL3D::CMeshGeom::CFaceTmp::MaterialId, matrix, NL3D::CMeshGeom::CFaceTmp::MatrixBlockId, NL3D::CMeshGeom::CMatrixBlock::MatrixId, NL3D::CMesh::CMeshBuild::MeshVertexProgram, nlassert, NL3D::CMesh::CMeshBuild::NumCoords, NL3D::CMeshGeom::CMatrixBlock::NumMatrix, optimizeTriangleOrder(), NL3D::CVertexBuffer::reserve(), NLMISC::CAABBoxExt::setCenter(), NL3D::CVertexBuffer::setNumVertices(), NLMISC::CAABBoxExt::setSize(), NL3D::CVertexBuffer::setUVRouting(), NL3D::CVertexBuffer::setVertexFormat(), sint, NL3D::CMesh::CMeshBuild::SkinWeights, TCornerSet, uint, uint32, NL3D::CMesh::CMeshBuild::UVRouting, NL3D::CMeshGeom::CCornerTmp::VBId, NL3D::CMesh::CCorner::Vertex, NL3D::CMesh::CMeshBuild::VertexFlags, NL3D::CMesh::CMeshBuild::Vertices, and NL3D::CMesh::CMeshBuild::VertLink. +

+Referenced by NL3D::CMesh::build(). +

+

00173 {
+00174         sint    i;
+00175 
+00176         // Dirt the VBuffer.
+00177         _VertexBufferHardDirty= true;
+00178 
+00179         // Empty geometry?
+00180         if(m.Vertices.size()==0 || m.Faces.size()==0)
+00181         {
+00182                 _VBuffer.setNumVertices(0);
+00183                 _VBuffer.reserve(0);
+00184                 _MatrixBlocks.clear();
+00185                 _BBox.setCenter(CVector::Null);
+00186                 _BBox.setSize(CVector::Null);
+00187                 return;
+00188         }
+00189         nlassert(numMaxMaterial>0);
+00190 
+00191         // Copy the UV routing table
+00192         for (i=0; i<CVertexBuffer::MaxStage; i++)
+00193                 _VBuffer.setUVRouting (i, m.UVRouting[i]);
+00194 
+00196         //======================
+00197         _BBox= makeBBox(m.Vertices);
+00198 
+00199 
+00201         //================================================
+00202 
+00203         // First, copy Face array.
+00204         vector<CFaceTmp>        tmpFaces;
+00205         tmpFaces.resize(m.Faces.size());
+00206         for(i=0;i<(sint)tmpFaces.size();i++)
+00207                 tmpFaces[i]= m.Faces[i];
+00208 
+00209         _Skinned= ((m.VertexFlags & CVertexBuffer::PaletteSkinFlag)==CVertexBuffer::PaletteSkinFlag);
+00210         // Skinning is OK only if SkinWeights are of same size as vertices.
+00211         _Skinned= _Skinned && (m.Vertices.size()==m.SkinWeights.size());
+00212 
+00213         // If skinning is KO, remove the Skin option.
+00214         uint    vbFlags= m.VertexFlags;
+00215         if(!_Skinned)
+00216                 vbFlags&= ~CVertexBuffer::PaletteSkinFlag;
+00217         // Force presence of vertex.
+00218         vbFlags|= CVertexBuffer::PositionFlag;
+00219 
+00220 
+00221         // If the mesh is not skinned, we have just 1 _MatrixBlocks.
+00222         if(!_Skinned)
+00223         {
+00224                 _MatrixBlocks.resize(1);
+00225                 // For each faces, assign it to the matrix block 0.
+00226                 for(i=0;i<(sint)tmpFaces.size();i++)
+00227                         tmpFaces[i].MatrixBlockId= 0;
+00228         }
+00229         // Else We must group/compute the matrixs blocks.
+00230         else
+00231         {
+00232                 // reset matrix blocks.
+00233                 _MatrixBlocks.clear();
+00234                 // build matrix blocks, and link faces to good matrix blocks.
+00235                 buildSkin(m, tmpFaces);
+00236         }
+00237 
+00238 
+00240         //================================================
+00241         // Setup VB.
+00242         _VBuffer.setNumVertices(0);
+00243         _VBuffer.reserve(0);
+00244 
+00245         bool useFormatExt = false;
+00249         for (uint k = 0; k < CVertexBuffer::MaxStage; ++k)
+00250         {
+00251                 if (
+00252                         (vbFlags & (CVertexBuffer::TexCoord0Flag << k))
+00253                         && m.NumCoords[k] != 2)
+00254                 {
+00255                         useFormatExt = true;
+00256                         break;
+00257                 }
+00258         }
+00259 
+00260         if (!useFormatExt)
+00261         {
+00262                 // setup standard format
+00263                 _VBuffer.setVertexFormat(vbFlags);
+00264         }
+00265         else // setup extended format
+00266         {
+00267                 _VBuffer.clearValueEx();                
+00268                 if (vbFlags & CVertexBuffer::PositionFlag) _VBuffer.addValueEx(CVertexBuffer::Position, CVertexBuffer::Float3);
+00269                 if (vbFlags & CVertexBuffer::NormalFlag) _VBuffer.addValueEx(CVertexBuffer::Normal, CVertexBuffer::Float3);
+00270                 if (vbFlags & CVertexBuffer::PrimaryColorFlag) _VBuffer.addValueEx(CVertexBuffer::PrimaryColor, CVertexBuffer::UChar4);
+00271                 if (vbFlags & CVertexBuffer::SecondaryColorFlag) _VBuffer.addValueEx(CVertexBuffer::SecondaryColor, CVertexBuffer::UChar4);
+00272                 if (vbFlags & CVertexBuffer::WeightFlag) _VBuffer.addValueEx(CVertexBuffer::Weight, CVertexBuffer::Float4);
+00273                 if (vbFlags & CVertexBuffer::PaletteSkinFlag) _VBuffer.addValueEx(CVertexBuffer::PaletteSkin, CVertexBuffer::UChar4);
+00274                 if (vbFlags & CVertexBuffer::FogFlag) _VBuffer.addValueEx(CVertexBuffer::Fog, CVertexBuffer::Float1);
+00275 
+00276                 for (uint k = 0; k < CVertexBuffer::MaxStage; ++k)
+00277                 {
+00278                         if (vbFlags & (CVertexBuffer::TexCoord0Flag << k))
+00279                         {
+00280                                 switch(m.NumCoords[k])
+00281                                 {       
+00282                                         case 2:
+00283                                                 _VBuffer.addValueEx((CVertexBuffer::TValue) (CVertexBuffer::TexCoord0 + k), CVertexBuffer::Float2);
+00284                                         break;
+00285                                         case 3:
+00286                                                 _VBuffer.addValueEx((CVertexBuffer::TValue) (CVertexBuffer::TexCoord0 + k), CVertexBuffer::Float3);
+00287                                         break;
+00288                                         default:
+00289                                                 nlassert(0);
+00290                                         break;
+00291                                 }
+00292                         }
+00293                 }
+00294                 _VBuffer.initEx();
+00295         }
+00296 
+00297         // Set local flags for corner comparison.
+00298         CCornerTmp::Flags= vbFlags;
+00299         // Setup locals.
+00300         TCornerSet      corners;
+00301         const CFaceTmp          *pFace= &(*tmpFaces.begin());
+00302         uint32          nFaceMB = 0;
+00303         sint            N= tmpFaces.size();
+00304         sint            currentVBIndex=0;
+00305 
+00306         m.VertLink.clear ();
+00307 
+00308         // process each face, building up the VB.
+00309         for(;N>0;N--, pFace++)
+00310         {
+00311                 sint    v0= pFace->Corner[0].Vertex;
+00312                 sint    v1= pFace->Corner[1].Vertex;
+00313                 sint    v2= pFace->Corner[2].Vertex;
+00314                 findVBId(corners, &pFace->Corner[0], currentVBIndex, m.Vertices[v0], m);
+00315                 findVBId(corners, &pFace->Corner[1], currentVBIndex, m.Vertices[v1], m);
+00316                 findVBId(corners, &pFace->Corner[2], currentVBIndex, m.Vertices[v2], m);
+00317                 CMesh::CVertLink vl1(nFaceMB, 0, pFace->Corner[0].VBId);
+00318                 CMesh::CVertLink vl2(nFaceMB, 1, pFace->Corner[1].VBId);
+00319                 CMesh::CVertLink vl3(nFaceMB, 2, pFace->Corner[2].VBId);
+00320                 m.VertLink.push_back(vl1);
+00321                 m.VertLink.push_back(vl2);
+00322                 m.VertLink.push_back(vl3);
+00323                 ++nFaceMB;
+00324         }
+00325 
+00326 
+00328         //================================
+00329         uint    mb;
+00330 
+00331         // For each _MatrixBlocks, point on those materials.
+00332         for(mb= 0;mb<_MatrixBlocks.size();mb++)
+00333         {
+00334                 // Build RdrPass ids.
+00335                 _MatrixBlocks[mb].RdrPass.resize (numMaxMaterial);
+00336 
+00338                 for(i=0;i<(sint)_MatrixBlocks[mb].RdrPass.size(); i++)
+00339                 {
+00340                         _MatrixBlocks[mb].RdrPass[i].MaterialId= i;
+00341                 }
+00342         }
+00343 
+00344         
+00346         //===================================================
+00347         pFace= &(*tmpFaces.begin());
+00348         N= tmpFaces.size();
+00349         for(;N>0;N--, pFace++)
+00350         {
+00351                 sint    mbId= pFace->MatrixBlockId;
+00352                 nlassert(mbId>=0 && mbId<(sint)_MatrixBlocks.size());
+00353                 // Insert the face in good MatrixBlock/RdrPass.
+00354                 _MatrixBlocks[mbId].RdrPass[pFace->MaterialId].PBlock.addTri(pFace->Corner[0].VBId, pFace->Corner[1].VBId, pFace->Corner[2].VBId);
+00355         }
+00356 
+00357 
+00359         //============================
+00360         for(mb= 0;mb<_MatrixBlocks.size();mb++)
+00361         {
+00362                 // NB: slow process (erase from a vector). Doens't matter since made at build.
+00363                 vector<CRdrPass>::iterator      itPass;
+00364                 for( itPass=_MatrixBlocks[mb].RdrPass.begin(); itPass!=_MatrixBlocks[mb].RdrPass.end(); )
+00365                 {
+00366                         // If this pass is empty, remove it.
+00367                         if( itPass->PBlock.getNumTri()==0 )
+00368                                 itPass= _MatrixBlocks[mb].RdrPass.erase(itPass);
+00369                         else
+00370                                 itPass++;
+00371                 }
+00372         }
+00373 
+00375         //============================
+00376         // BShapes
+00377         this->_MeshMorpher->BlendShapes = m.BlendShapes;
+00378 
+00379         // sort triangles for better cache use.
+00380         optimizeTriangleOrder();
+00381 
+00382         // SmartPtr Copy VertexProgram effect.
+00383         this->_MeshVertexProgram= m.MeshVertexProgram;
+00384 
+00386         //=================================================     
+00387 
+00388         // If skinned
+00389         if(_Skinned)
+00390         {
+00391                 // Reserve some space
+00392                 _BonesName.reserve (m.BonesNames.size ());
+00393 
+00394                 // Current local bone
+00395                 uint currentBone = 0;
+00396 
+00397                 // For each matrix block
+00398                 uint matrixBlock;
+00399                 for (matrixBlock=0; matrixBlock<_MatrixBlocks.size(); matrixBlock++)
+00400                 {
+00401                         // Ref on the matrix block
+00402                         CMatrixBlock &mb = _MatrixBlocks[matrixBlock];
+00403 
+00404                         // Remap the skeleton index in model index
+00405                         std::map<uint, uint> remap;
+00406 
+00407                         // For each matrix
+00408                         uint matrix;
+00409                         for (matrix=0; matrix<mb.NumMatrix; matrix++)
+00410                         {
+00411                                 // Get bone id in the skeleton
+00412                                 std::map<uint, uint>::iterator ite = remap.find (mb.MatrixId[matrix]);
+00413 
+00414                                 // Not found
+00415                                 if (ite == remap.end())
+00416                                 {
+00417                                         // Insert it
+00418                                         remap.insert (std::map<uint, uint>::value_type (mb.MatrixId[matrix], currentBone));
+00419 
+00420                                         // Check the matrix id
+00421                                         nlassert (mb.MatrixId[matrix] < m.BonesNames.size());
+00422 
+00423                                         // Set the bone name
+00424                                         _BonesName.push_back (m.BonesNames[mb.MatrixId[matrix]]);
+00425 
+00426                                         // Set the id in local
+00427                                         mb.MatrixId[matrix] = currentBone++;
+00428                                 }
+00429                                 else
+00430                                 {
+00431                                         // Set the id in local
+00432                                         mb.MatrixId[matrix] = ite->second;
+00433                                 }
+00434                         }
+00435                 }
+00436 
+00437                 // Bone id in local
+00438                 _BoneIdComputed = false;
+00439                 _BoneIdExtended = false;
+00440         }
+00441 
+00442 
+00443         // End!!
+00444         // Some runtime not serialized compilation
+00445         compileRunTime();
+00446 }
+
+

+ + + + +
+ + + + + + + + + +
void NL3D::CMeshGeom::buildBoneUsageVer3  )  [private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1549 of file mesh.cpp. +

+References _BonesId, _MatrixBlocks, _Skinned, matrix, NL3D::CMeshGeom::CMatrixBlock::MatrixId, NL3D::CMeshGeom::CMatrixBlock::NumMatrix, uint, and uint32. +

+

01550 {
+01551         if(_Skinned)
+01552         {
+01553                 // parse all matrixBlocks, couting MaxBoneId used.
+01554                 uint32  maxBoneId= 0;
+01555                 // For each matrix block
+01556                 uint matrixBlock;
+01557                 for (matrixBlock=0; matrixBlock<_MatrixBlocks.size(); matrixBlock++)
+01558                 {
+01559                         CMatrixBlock &mb = _MatrixBlocks[matrixBlock];
+01560                         // For each matrix
+01561                         for (uint matrix=0; matrix<mb.NumMatrix; matrix++)
+01562                         {
+01563                                 maxBoneId= max(mb.MatrixId[matrix], maxBoneId);
+01564                         }
+01565                 }
+01566 
+01567                 // alloc an array of maxBoneId+1, reset to 0.
+01568                 std::vector<uint8>              boneUsage;
+01569                 boneUsage.resize(maxBoneId+1, 0);
+01570 
+01571                 // reparse all matrixBlocks, counting usage for each bone.
+01572                 for (matrixBlock=0; matrixBlock<_MatrixBlocks.size(); matrixBlock++)
+01573                 {
+01574                         CMatrixBlock &mb = _MatrixBlocks[matrixBlock];
+01575                         // For each matrix
+01576                         for (uint matrix=0; matrix<mb.NumMatrix; matrix++)
+01577                         {
+01578                                 // mark this bone as used.
+01579                                 boneUsage[mb.MatrixId[matrix]]= 1;
+01580                         }
+01581                 }
+01582 
+01583                 // For each bone used
+01584                 _BonesId.clear();
+01585                 for(uint i=0; i<boneUsage.size();i++)
+01586                 {
+01587                         // if the bone is used by the mesh, add it to BoneId.
+01588                         if(boneUsage[i])
+01589                                 _BonesId.push_back(i);
+01590                 }
+01591         }
+01592 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::buildSkin CMesh::CMeshBuild m,
std::vector< CFaceTmp > &  tmpFaces
[private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1105 of file mesh.cpp. +

+References _MatrixBlocks, NL3D::CMeshGeom::CFaceTmp::Corner, NL3D::CMeshGeom::CMatrixBlock::getMatrixIdLocation(), NL3D::CMeshGeom::CBoneTmp::Inserted, ItBoneMap, NL3D::CMeshGeom::CFaceTmp::MatrixBlockId, NL3D::CPaletteSkin::MatrixId, NL3D::CMeshGeom::CMatrixBlock::MatrixId, NL3D::CMesh::CSkinWeight::MatrixId, NL3D::CMeshGeom::CBoneTmp::MatrixIdInMB, NL3D_MESH_SKINNING_MAX_MATRIX, nlassert, NL3D::CMeshGeom::CMatrixBlock::NumMatrix, NL3D::CMeshGeom::CCornerTmp::Palette, NL3D::CMeshGeom::CBoneTmp::RefCount, NL3D::CMeshGeom::CMatrixBlockRemap::Remap, sint, NL3D::CMesh::CMeshBuild::SkinWeights, TBoneMap, uint, uint8, NL3D::CMesh::CCorner::Vertex, NL3D::CMeshGeom::CCornerTmp::Weights, and NL3D::CMesh::CSkinWeight::Weights. +

+Referenced by build(). +

+

01106 {
+01107         sint    i,j,k;
+01108         TBoneMap                remainingBones;
+01109         list<uint>              remainingFaces;
+01110 
+01111 
+01112         // 0. normalize SkinWeights: for all weights at 0, copy the matrixId from 0th matrix => no random/bad use of matrix.
+01113         //================================
+01114         for(i=0;i<(sint)m.SkinWeights.size();i++)
+01115         {
+01116                 CMesh::CSkinWeight      &sw= m.SkinWeights[i];
+01117 
+01118                 // 0th weight must not be 0.
+01119                 nlassert(sw.Weights[0]!=0);
+01120 
+01121                 // Begin at 1, tests all other weights.
+01122                 for(j=1;j<NL3D_MESH_SKINNING_MAX_MATRIX;j++)
+01123                 {
+01124                         // We don't use this entry??
+01125                         if(sw.Weights[j]==0)
+01126                         {
+01127                                 // Setup MatrixId so that this vertex do no use more matrix than it really wants.
+01128                                 sw.MatrixId[j]= sw.MatrixId[0];
+01129                         }
+01130                 }
+01131         }
+01132 
+01133 
+01134         // 1. build the list of used/remaining bones, in ascending order. (so we use the depth-first topolgy of hierarchy).
+01135         //================================
+01136         for(i=0;i<(sint)tmpFaces.size();i++)
+01137         {
+01138                 CFaceTmp        &face= tmpFaces[i];
+01139 
+01140                 for(j=0;j<3;j++)
+01141                 {
+01142                         CMesh::CSkinWeight      &sw= m.SkinWeights[face.Corner[j].Vertex];
+01143                         for(k=0;k<NL3D_MESH_SKINNING_MAX_MATRIX;k++)
+01144                         {
+01145                                 // insert (if not already here) the used bone in the set.
+01146                                 // and insert his refcount. (NB: ctor() init it to 0 :) ).
+01147                                 remainingBones[sw.MatrixId[k]].RefCount++;
+01148                         }
+01149                 }
+01150         }
+01151 
+01152 
+01153         // 2. Create the list of un-inserted faces.
+01154         //================================
+01155         for(i=0;i<(sint)tmpFaces.size();i++)
+01156         {
+01157                 remainingFaces.push_back(i);
+01158         }
+01159 
+01160 
+01161 
+01162         // 3. Create as many Blocks as necessary.
+01163         //================================
+01164         // Which bones a face use (up to 12).
+01165         vector<uint>    boneUse;
+01166         boneUse.reserve(NL3D_MESH_SKINNING_MAX_MATRIX*3);
+01167 
+01168         // While still exist faces.
+01169         while(!remainingFaces.empty())
+01170         {
+01171                 // create a new matrix block.
+01172                 _MatrixBlocks.push_back(CMatrixBlock());
+01173                 CMatrixBlock    &matrixBlock= _MatrixBlocks[_MatrixBlocks.size()-1];
+01174                 matrixBlock.NumMatrix=0;
+01175 
+01176                 // a. reset remainingBones as not inserted in the current matrixBlock.
+01177                 //============================
+01178                 ItBoneMap       itBone;
+01179                 for(itBone= remainingBones.begin();itBone!=remainingBones.end();itBone++)
+01180                 {
+01181                         itBone->second.Inserted= false;
+01182                 }
+01183 
+01184 
+01185                 // b. while still exist bones, try to insert faces which use them in matrixBlock.
+01186                 //============================
+01187                 while(!remainingBones.empty())
+01188                 {
+01189                         // get the first bone from the map. (remind: depth-first order).
+01190                         uint            currentBoneId= remainingBones.begin()->first;
+01191 
+01192                         // If no more faces in the remainingFace list use this bone, remove it, and continue.
+01193                         if(remainingBones.begin()->second.RefCount==0)
+01194                         {
+01195                                 remainingBones.erase(remainingBones.begin());
+01196                                 continue;
+01197                         }
+01198 
+01199                         // this is a marker, to know if a face insertion will occurs.
+01200                         bool            faceAdded= false;
+01201 
+01202                         // traverse all faces, trying to insert them in current MatrixBlock processed.
+01203                         list<uint>::iterator    itFace;
+01204                         for(itFace= remainingFaces.begin(); itFace!=remainingFaces.end();)
+01205                         {
+01206                                 bool    useCurrentBoneId;
+01207                                 uint    newBoneAdded;
+01208 
+01209                                 // i/ Get info on current face.
+01210                                 //-----------------------------
+01211 
+01212                                 // build which bones this face use.
+01213                                 tmpFaces[*itFace].buildBoneUse(boneUse, m.SkinWeights);
+01214 
+01215                                 // test if this face use the currentBoneId.
+01216                                 useCurrentBoneId= false;
+01217                                 for(i=0;i<(sint)boneUse.size();i++)
+01218                                 {
+01219                                         // if this face use the currentBoneId
+01220                                         if(boneUse[i]==currentBoneId)
+01221                                         {
+01222                                                 useCurrentBoneId= true;
+01223                                                 break;
+01224                                         }
+01225                                 }
+01226                                 // compute how many bones that are not in the current matrixblock this face use.
+01227                                 newBoneAdded=0;
+01228                                 for(i=0;i<(sint)boneUse.size();i++)
+01229                                 {
+01230                                         // if this bone is not inserted in the current matrix block, inform it.
+01231                                         if(!remainingBones[boneUse[i]].Inserted)
+01232                                                 newBoneAdded++;
+01233                                 }
+01234                                 
+01235                                 
+01236                                 // ii/ insert/reject face.
+01237                                 //------------------------
+01238 
+01239                                 // If this face do not add any more bone, we can insert it into the current matrixblock.
+01240                                 // If it use the currentBoneId, and do not explode max count, we allow insert it too in the current matrixblock.
+01241                                 if( newBoneAdded==0 || 
+01242                                         (useCurrentBoneId && newBoneAdded+matrixBlock.NumMatrix < IDriver::MaxModelMatrix) )
+01243                                 {
+01244                                         // Insert this face in the current matrix block
+01245 
+01246                                         CFaceTmp        &face= tmpFaces[*itFace];
+01247 
+01248                                         // for all vertices of this face.
+01249                                         for(j=0;j<3;j++)
+01250                                         {
+01251                                                 CMesh::CSkinWeight      &sw= m.SkinWeights[face.Corner[j].Vertex];
+01252 
+01253                                                 // for each corner weight (4)
+01254                                                 for(k=0;k<NL3D_MESH_SKINNING_MAX_MATRIX;k++)
+01255                                                 {
+01256                                                         // get the global boneId this corner weight use.
+01257                                                         uint            boneId= sw.MatrixId[k];
+01258                                                         // get the CBoneTmp this corner weight use.
+01259                                                         CBoneTmp        &bone= remainingBones[boneId];
+01260 
+01261                                                         // decRef the bone .
+01262                                                         bone.RefCount--;
+01263 
+01264                                                         // Is this bone already inserted in the MatrixBlock ?
+01265                                                         if( !bone.Inserted )
+01266                                                         {
+01267                                                                 // No, insert it.
+01268                                                                 bone.Inserted= true;
+01269                                                                 // link it to the MatrixId in the current matrixBlock.
+01270                                                                 bone.MatrixIdInMB= matrixBlock.NumMatrix;
+01271 
+01272                                                                 // modify the matrixBlock
+01273                                                                 matrixBlock.MatrixId[matrixBlock.NumMatrix]= boneId;
+01274                                                                 // increment the number of matrix in the matrixBlock.
+01275                                                                 matrixBlock.NumMatrix++;
+01276                                                         }
+01277 
+01278                                                         // Copy Weight info for this Corner.
+01279                                                         // Set what matrix in the current matrix block this corner use.
+01280                                                         face.Corner[j].Palette.MatrixId[k]= bone.MatrixIdInMB;
+01281                                                         // Set weight.
+01282                                                         face.Corner[j].Weights[k]= sw.Weights[k];
+01283                                                 }
+01284                                         }
+01285 
+01286                                         // to Which matrixblock this face is inserted.
+01287                                         face.MatrixBlockId= _MatrixBlocks.size()-1;
+01288                                         
+01289                                         // remove the face from remain face list.
+01290                                         itFace= remainingFaces.erase(itFace);
+01291 
+01292                                         // inform the algorithm that a face has been added.
+01293                                         faceAdded= true;
+01294                                 }
+01295                                 else
+01296                                 {
+01297                                         // do not append this face to the current matrix block, skip to the next
+01298                                         itFace++;
+01299                                 }
+01300                         }
+01301 
+01302                         // If no faces have been added during this pass, we are blocked, and either the MatrixBlock may be full,
+01303                         // or there is no more face. So quit this block and process a new one.
+01304                         if(!faceAdded)
+01305                                 break;
+01306                 }
+01307 
+01308         }
+01309         // NB: at the end of this loop, remainingBones may not be empty(), but all remainingBones should have RefCount==0.
+01310 
+01311 
+01312 
+01313         // 4. Re-order matrix use in MatrixBlocks, for minimum matrix change between MatrixBlocks.
+01314         //================================
+01315         vector<CMatrixBlockRemap>       blockRemaps;
+01316         blockRemaps.resize(_MatrixBlocks.size());
+01317 
+01318 
+01319         // For all MatrixBlocks > first, try to "mirror" bones from previous.
+01320         for(i=1;i<(sint)_MatrixBlocks.size();i++)
+01321         {
+01322                 CMatrixBlock            &mBlock= _MatrixBlocks[i];
+01323                 CMatrixBlock            &mPrevBlock= _MatrixBlocks[i-1];
+01324                 CMatrixBlockRemap       &remap= blockRemaps[i];
+01325 
+01326                 // First bkup the bone ids in remap table.
+01327                 for(j=0;j<(sint)mBlock.NumMatrix;j++)
+01328                 {
+01329                         remap.Remap[j]= mBlock.MatrixId[j];
+01330                 }
+01331 
+01332                 // For all ids of this blocks, try to mirror them.
+01333                 for(j=0;j<(sint)mBlock.NumMatrix;j++)
+01334                 {
+01335                         // get the location of this bone in the prev bone.
+01336                         sint    idLoc= mPrevBlock.getMatrixIdLocation(mBlock.MatrixId[j]);
+01337                         // If not found, or if bigger than current array, fails (cant be mirrored).
+01338                         // Or if already mirrored.
+01339                         if(idLoc==-1 || idLoc>=(sint)mBlock.NumMatrix || idLoc==j)
+01340                         {
+01341                                 // next id.
+01342                                 j++;
+01343                         }
+01344                         else
+01345                         {
+01346                                 // puts me on my mirrored location. and swap with the current one at this mirrored location.
+01347                                 swap(mBlock.MatrixId[j], mBlock.MatrixId[idLoc]);
+01348                                 // mBlock.MatrixId[j] is now a candidate for mirror.
+01349                         }
+01350                 }
+01351 
+01352                 // Then build the Remap table, to re-order faces matrixId which use this matrix block.
+01353                 for(j=0;j<(sint)mBlock.NumMatrix;j++)
+01354                 {
+01355                         // get the boneid which was at this position j before.
+01356                         uint    boneId= remap.Remap[j];
+01357                         // search his new position, and store the result in the remap table.
+01358                         remap.Remap[j]= mBlock.getMatrixIdLocation(boneId);
+01359                 }
+01360 
+01361                 // NB: this matrixBlock is re-ordered. next matrixBlock use this state.
+01362         }
+01363 
+01364 
+01365         // For all faces/corners/weights, remap MatrixIds.
+01366         for(i=0;i<(sint)tmpFaces.size();i++)
+01367         {
+01368                 CFaceTmp        &face= tmpFaces[i];
+01369                 // do it but for matrixblock0.
+01370                 if(face.MatrixBlockId!=0)
+01371                 {
+01372                         CMatrixBlockRemap       &remap= blockRemaps[face.MatrixBlockId];
+01373                         // For all corners.
+01374                         for(j=0;j<3;j++)
+01375                         {
+01376                                 for(k=0;k<NL3D_MESH_SKINNING_MAX_MATRIX;k++)
+01377                                 {
+01378                                         uint    oldId= face.Corner[j].Palette.MatrixId[k];
+01379                                         face.Corner[j].Palette.MatrixId[k]= (uint8)remap.Remap[oldId];
+01380                                 }
+01381                         }
+01382                 }
+01383         }
+01384 
+01385 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool NL3D::CMeshGeom::clip const std::vector< CPlane > &  pyramid,
const CMatrix worldMatrix
[virtual]
+
+ + + + + +
+   + + +

+clip this mesh +

+ +

+Reimplemented from NL3D::IMeshGeom. +

+Definition at line 482 of file mesh.cpp. +

+References _PreciseClipping, NLMISC::CBSphere::applyTransform(), NLMISC::CBSphere::Center, NLMISC::CAABBoxExt::clipBack(), NLMISC::CAABBoxExt::getCenter(), NLMISC::CAABBoxExt::getRadius(), NLMISC::CPlane::normalize(), NLMISC::CBSphere::Radius, and sint. +

+Referenced by NL3D::CMesh::clip(). +

+

00483 {
+00484         // Speed Clip: clip just the sphere.
+00485         CBSphere        localSphere(_BBox.getCenter(), _BBox.getRadius());
+00486         CBSphere        worldSphere;
+00487 
+00488         // transform the sphere in WorldMatrix (with nearly good scale info).
+00489         localSphere.applyTransform(worldMatrix, worldSphere);
+00490 
+00491         // if out of only plane, entirely out.
+00492         for(sint i=0;i<(sint)pyramid.size();i++)
+00493         {
+00494                 // We are sure that pyramid has normalized plane normals.
+00495                 // if SpherMax OUT return false.
+00496                 float   d= pyramid[i]*worldSphere.Center;
+00497                 if(d>worldSphere.Radius)
+00498                         return false;
+00499         }
+00500 
+00501         // test if must do a precise clip, according to mesh size.
+00502         if( _PreciseClipping )
+00503         {
+00504                 CPlane  localPlane;
+00505 
+00506                 // if out of only plane, entirely out.
+00507                 for(sint i=0;i<(sint)pyramid.size();i++)
+00508                 {
+00509                         // Transform the pyramid in Object space.
+00510                         localPlane= pyramid[i]*worldMatrix;
+00511                         // localPlane must be normalized, because worldMatrix mya have a scale.
+00512                         localPlane.normalize();
+00513                         // if the box is not partially inside the plane, quit
+00514                         if( !_BBox.clipBack(localPlane) )
+00515                                 return false;
+00516                 }
+00517         }
+00518 
+00519         return true;
+00520 }
+
+

+ + + + +
+ + + + + + + + + +
void NL3D::CMeshGeom::compileRunTime  )  [private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1062 of file mesh.cpp. +

+References _MatrixBlocks, _MeshMorpher, _MeshVertexProgram, _PreciseClipping, _Skinned, _SupportMBRFlags, bkupOriginalSkinVertices(), NL3D::CMeshMorpher::BlendShapes, NLMISC::CAABBoxExt::getRadius(), MBROk, MBRSortPerMaterial, and NL3D_MESH_PRECISE_CLIP_THRESHOLD. +

+Referenced by build(), and setBlendShapes(). +

+

01063 {
+01064         // if skinned, prepare skinning
+01065         if(_Skinned)
+01066                 bkupOriginalSkinVertices();
+01067 
+01068         // Do precise clipping for big object??
+01069         _PreciseClipping= _BBox.getRadius() >= NL3D_MESH_PRECISE_CLIP_THRESHOLD;
+01070 
+01071         // Support MeshBlockRendering only if not skinned/meshMorphed.
+01072         bool    supportMeshBlockRendering= !_Skinned && _MeshMorpher->BlendShapes.size()==0;
+01073         
+01074         // true only if one matrix block, and at least one rdrPass.
+01075         supportMeshBlockRendering= supportMeshBlockRendering && _MatrixBlocks.size()==1 && _MatrixBlocks[0].RdrPass.size()>0;
+01076         if (supportMeshBlockRendering && _MeshVertexProgram) 
+01077         {
+01078                 supportMeshBlockRendering = supportMeshBlockRendering && _MeshVertexProgram->supportMeshBlockRendering();
+01079         }
+01080 
+01081         // TestYoyo
+01082         //supportMeshBlockRendering= false;
+01083 
+01084         // support MeshVertexProgram, but no material sorting...
+01085         bool    supportMBRPerMaterial= supportMeshBlockRendering && _MeshVertexProgram==NULL;
+01086 
+01087 
+01088         // setup flags
+01089         _SupportMBRFlags= 0;
+01090         if(supportMeshBlockRendering)
+01091                 _SupportMBRFlags|= MBROk;
+01092         if(supportMBRPerMaterial)
+01093                 _SupportMBRFlags|= MBRSortPerMaterial;
+01094 }
+
+

+ + + + +
+ + + + + + + + + + +
void NL3D::CMeshGeom::computeBonesId CSkeletonModel skeleton  ) 
+
+ + + + + +
+   + + +

+Compute skinning id. +

+ +

+Definition at line 1456 of file mesh.cpp. +

+References _BoneIdComputed, _BoneIdExtended, _BonesId, _BonesIdExt, _BonesName, _MatrixBlocks, NL3D::CSkeletonModel::Bones, NL3D::CSkeletonModel::flagBoneAndParents(), NL3D::CSkeletonModel::getBoneIdByName(), matrix, NL3D::CMeshGeom::CMatrixBlock::MatrixId, nlassert, nlwarning, NL3D::CMeshGeom::CMatrixBlock::NumMatrix, sint32, uint, and uint32. +

+Referenced by NL3D::CMesh::computeBonesId(). +

+

01457 {
+01458         // Already computed ?
+01459         if (!_BoneIdComputed)
+01460         {
+01461                 // Get a pointer on the skeleton
+01462                 nlassert (skeleton);
+01463                 if (skeleton)
+01464                 {
+01465                         // Resize boneId to the good size.
+01466                         _BonesId.resize(_BonesName.size());
+01467 
+01468                         // For each matrix block
+01469                         uint matrixBlock;
+01470                         for (matrixBlock=0; matrixBlock<_MatrixBlocks.size(); matrixBlock++)
+01471                         {
+01472                                 // Ref on the matrix block
+01473                                 CMatrixBlock &mb = _MatrixBlocks[matrixBlock];
+01474 
+01475                                 // For each matrix
+01476                                 uint matrix;
+01477                                 for (matrix=0; matrix<mb.NumMatrix; matrix++)
+01478                                 {
+01479                                         // Get bone id in the skeleton
+01480                                         nlassert (mb.MatrixId[matrix]<_BonesName.size());
+01481                                         sint32 boneId = skeleton->getBoneIdByName (_BonesName[mb.MatrixId[matrix]]);
+01482 
+01483                                         // Setup the _BoneId.
+01484                                         _BonesId[mb.MatrixId[matrix]]= boneId;
+01485 
+01486                                         // Bones found ?
+01487                                         if (boneId != -1)
+01488                                         {
+01489                                                 // Set the bone id
+01490                                                 mb.MatrixId[matrix] = (uint32)boneId;
+01491                                         }
+01492                                         else
+01493                                         {
+01494                                                 // Put id 0
+01495                                                 mb.MatrixId[matrix] = 0;
+01496 
+01497                                                 // Error
+01498                                                 nlwarning ("Bone %s not found in the skeleton.", _BonesName[mb.MatrixId[matrix]].c_str());
+01499                                         }
+01500                                 }
+01501                         }
+01502 
+01503                         // Computed
+01504                         _BoneIdComputed = true;
+01505                 }
+01506         }
+01507 
+01508         // Already extended ?
+01509         if (!_BoneIdExtended)
+01510         {
+01511                 nlassert (skeleton);
+01512                 if (skeleton)
+01513                 {
+01514                         // the total bone Usage of the mesh.
+01515                         vector<bool>    boneUsage;
+01516                         boneUsage.resize(skeleton->Bones.size(), false);
+01517 
+01518                         // for all Bones marked as valid.
+01519                         uint    i;
+01520                         for(i=0; i<_BonesId.size(); i++)
+01521                         {
+01522                                 // if not a valid boneId, skip it.
+01523                                 if(_BonesId[i]<0)
+01524                                         continue;
+01525 
+01526                                 // mark him and his father in boneUsage.
+01527                                 skeleton->flagBoneAndParents(_BonesId[i], boneUsage);
+01528                         }
+01529 
+01530                         // fill _BonesIdExt with bones of _BonesId and their parents.
+01531                         _BonesIdExt.clear();
+01532                         for(i=0; i<boneUsage.size();i++)
+01533                         {
+01534                                 // if the bone is used by the mesh, add it to BoneIdExt.
+01535                                 if(boneUsage[i])
+01536                                         _BonesIdExt.push_back(i);
+01537                         }
+01538 
+01539                 }
+01540 
+01541                 // Extended
+01542                 _BoneIdExtended= true;
+01543         }
+01544 
+01545 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::computeMeshVBHeap void *  dst,
uint  indexStart
[virtual]
+
+ + + + + +
+   + + +

+When the framework succes to allocate a VBHeap space, it call this method to fill this space and compute shifted Primitive block.

Parameters:
+ + + +
the dest VertexBuffer. NB: start to fill at dst[0]
indexStart used to shift primitive block.
+
+ +

+Reimplemented from NL3D::IMeshGeom. +

+Definition at line 2133 of file mesh.cpp. +

+References _MatrixBlocks, NL3D::CPrimitiveBlock::getLinePointer(), NL3D::CPrimitiveBlock::getNumLine(), NL3D::CPrimitiveBlock::getNumQuad(), NL3D::CPrimitiveBlock::getNumTri(), NL3D::CVertexBuffer::getNumVertices(), NL3D::CPrimitiveBlock::getQuadPointer(), NL3D::CPrimitiveBlock::getTriPointer(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexSize(), nlassert, NL3D::CMeshGeom::CMatrixBlock::RdrPass, NL3D::CPrimitiveBlock::setNumLine(), NL3D::CPrimitiveBlock::setNumQuad(), NL3D::CPrimitiveBlock::setNumTri(), uint, and uint32. +

+

02134 {
+02135         // Fill dst with Buffer content.
+02136         memcpy(dst, _VBuffer.getVertexCoordPointer(), _VBuffer.getNumVertices()*_VBuffer.getVertexSize() );
+02137 
+02138         // NB: only 1 MB is possible ...
+02139         nlassert(_MatrixBlocks.size()==1);
+02140         CMatrixBlock    &mBlock= _MatrixBlocks[0];
+02141         // For all rdrPass.
+02142         for(uint i=0;i<mBlock.RdrPass.size();i++)
+02143         {
+02144                 // shift the PB
+02145                 CPrimitiveBlock &srcPb= mBlock.RdrPass[i].PBlock;
+02146                 CPrimitiveBlock &dstPb= mBlock.RdrPass[i].VBHeapPBlock;
+02147                 uint j;
+02148 
+02149                 // Lines.
+02150                 dstPb.setNumLine(srcPb.getNumLine());
+02151                 uint32                  *srcLinePtr= srcPb.getLinePointer();
+02152                 uint32                  *dstLinePtr= dstPb.getLinePointer();
+02153                 for(j=0; j<dstPb.getNumLine()*2;j++)
+02154                 {
+02155                         dstLinePtr[j]= srcLinePtr[j]+indexStart;
+02156                 }
+02157                 // Tris.
+02158                 dstPb.setNumTri(srcPb.getNumTri());
+02159                 uint32                  *srcTriPtr= srcPb.getTriPointer();
+02160                 uint32                  *dstTriPtr= dstPb.getTriPointer();
+02161                 for(j=0; j<dstPb.getNumTri()*3;j++)
+02162                 {
+02163                         dstTriPtr[j]= srcTriPtr[j]+indexStart;
+02164                 }
+02165                 // Quads.
+02166                 dstPb.setNumQuad(srcPb.getNumQuad());
+02167                 uint32                  *srcQuadPtr= srcPb.getQuadPointer();
+02168                 uint32                  *dstQuadPtr= dstPb.getQuadPointer();
+02169                 for(j=0; j<dstPb.getNumQuad()*4;j++)
+02170                 {
+02171                         dstQuadPtr[j]= srcQuadPtr[j]+indexStart;
+02172                 }
+02173         }
+02174 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::computeSkinMatrixes CSkeletonModel skeleton,
CMatrix3x4 matrixes,
CMatrixBlock prevBlock,
CMatrixBlock curBlock
[private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1914 of file mesh.cpp. +

+References NL3D::CSkeletonModel::getActiveBoneSkinMatrix(), NL3D::CMeshGeom::CMatrixBlock::MatrixId, NL3D::CMeshGeom::CMatrixBlock::NumMatrix, NL3D::CMatrix3x4::set(), and uint. +

+Referenced by applySkin(). +

+

01915 {
+01916         // For all matrix of this mBlock.
+01917         for(uint idMat=0;idMat<mBlock.NumMatrix;idMat++)
+01918         {
+01919                 uint    curBoneId= mBlock.MatrixId[idMat];
+01920 
+01921                 // If same matrix binded as previous block, no need to bind!!
+01922                 if(prevBlock && idMat<prevBlock->NumMatrix && prevBlock->MatrixId[idMat]== curBoneId)
+01923                         continue;
+01924 
+01925                 // Else, we must setup the matrix 
+01926                 matrixes[idMat].set(skeleton->getActiveBoneSkinMatrix(curBoneId));
+01927         }
+01928 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::computeSoftwarePointSkinning CMatrix3x4 matrixes,
CVector srcVector,
CPaletteSkin srcPal,
float *  srcWgt,
CVector dstVector
[private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1870 of file mesh.cpp. +

+References NL3D::CPaletteSkin::MatrixId, NL3D::CMatrix3x4::mulAddPoint(), and NL3D::CMatrix3x4::mulSetPoint(). +

+Referenced by applySkin(). +

+

01871 {
+01872         CMatrix3x4              *pMat;
+01873 
+01874         // \todo yoyo: TODO_OPTIMIZE: SSE verion...
+01875 
+01876         // 0th matrix influence.
+01877         pMat= matrixes + srcPal->MatrixId[0];
+01878         pMat->mulSetPoint(*srcVec, srcWgt[0], *pDst);
+01879         // 1th matrix influence.
+01880         pMat= matrixes + srcPal->MatrixId[1];
+01881         pMat->mulAddPoint(*srcVec, srcWgt[1], *pDst);
+01882         // 2th matrix influence.
+01883         pMat= matrixes + srcPal->MatrixId[2];
+01884         pMat->mulAddPoint(*srcVec, srcWgt[2], *pDst);
+01885         // 3th matrix influence.
+01886         pMat= matrixes + srcPal->MatrixId[3];
+01887         pMat->mulAddPoint(*srcVec, srcWgt[3], *pDst);
+01888 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::computeSoftwareVectorSkinning CMatrix3x4 matrixes,
CVector srcVector,
CPaletteSkin srcPal,
float *  srcWgt,
CVector dstVector
[private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1892 of file mesh.cpp. +

+References NL3D::CPaletteSkin::MatrixId, NL3D::CMatrix3x4::mulAddVector(), and NL3D::CMatrix3x4::mulSetVector(). +

+Referenced by applySkin(). +

+

01893 {
+01894         CMatrix3x4              *pMat;
+01895 
+01896         // \todo yoyo: TODO_OPTIMIZE: SSE verion...
+01897 
+01898         // 0th matrix influence.
+01899         pMat= matrixes + srcPal->MatrixId[0];
+01900         pMat->mulSetVector(*srcVec, srcWgt[0], *pDst);
+01901         // 1th matrix influence.
+01902         pMat= matrixes + srcPal->MatrixId[1];
+01903         pMat->mulAddVector(*srcVec, srcWgt[1], *pDst);
+01904         // 2th matrix influence.
+01905         pMat= matrixes + srcPal->MatrixId[2];
+01906         pMat->mulAddVector(*srcVec, srcWgt[2], *pDst);
+01907         // 3th matrix influence.
+01908         pMat= matrixes + srcPal->MatrixId[3];
+01909         pMat->mulAddVector(*srcVec, srcWgt[3], *pDst);
+01910 }
+
+

+ + + + +
+ + + + + + + + + + +
void NL3D::CMeshGeom::endMesh CMeshGeomRenderContext rdrCtx  )  [virtual]
+
+ + + + + +
+   + + +

+The framework call this method when it has done with this meshGeom +

+Implements NL3D::IMeshGeom. +

+Definition at line 2100 of file mesh.cpp. +

+References _MeshVertexProgram, _SupportMBRFlags, NL3D::CMeshGeomRenderContext::Driver, and MBRCurrentUseVP. +

+

02101 {
+02102         // MeshVertexProgram ?
+02103         if( _SupportMBRFlags & MBRCurrentUseVP )
+02104         {
+02105                 // End Mesh
+02106                 _MeshVertexProgram->endMBRMesh( rdrCtx.Driver );
+02107 
+02108                 // and remove Current Flag.
+02109                 _SupportMBRFlags&= ~MBRCurrentUseVP;
+02110         }
+02111 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::findVBId TCornerSet corners,
const CCornerTmp corn,
sint currentVBIndex,
const CVector vert,
const CMesh::CMeshBuild mb
[inline, private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 733 of file mesh.h. +

+References ItCornerSet, NL3D_MESH_SKINNING_MAX_MATRIX, nlassert, NL3D::CMesh::CMeshBuild::NumCoords, NL3D::CVertexBuffer::setColor(), NL3D::CVertexBuffer::setNormalCoord(), NL3D::CVertexBuffer::setNumVertices(), NL3D::CVertexBuffer::setPaletteSkin(), NL3D::CVertexBuffer::setSpecular(), NL3D::CVertexBuffer::setTexCoord(), NL3D::CVertexBuffer::setValueFloat3Ex(), NL3D::CVertexBuffer::setVertexCoord(), NL3D::CVertexBuffer::setWeight(), sint, and TCornerSet. +

+Referenced by build(). +

+

00734         {
+00735                 ItCornerSet  it= corners.find(const_cast<CCornerTmp *>(corn));
+00736                 if(it!=corners.end())
+00737                         corn->VBId= (*it)->VBId;
+00738                 else
+00739                 {
+00740                         // Add corner to the set to not insert same corner two times.
+00741                         corners.insert (const_cast<CCornerTmp *>(corn));
+00742                         sint    i;
+00743                         corn->VBId= currentVBIndex++;
+00744                         // Fill the VBuffer.
+00745                         _VBuffer.setNumVertices(currentVBIndex);
+00746                         sint    id= currentVBIndex-1;
+00747                         // XYZ.
+00748                         _VBuffer.setVertexCoord(id, vert);
+00749                         // Normal
+00750                         if(CCornerTmp::Flags & CVertexBuffer::NormalFlag)
+00751                                 _VBuffer.setNormalCoord(id, corn->Normal);
+00752                         // Uvws.
+00753                         for(i=0;i<CVertexBuffer::MaxStage;i++)
+00754                         {
+00755                                 if(CCornerTmp::Flags & (CVertexBuffer::TexCoord0Flag<<i))
+00756                                 {
+00757                                         switch(mb.NumCoords[i])
+00758                                         {
+00759                                                 case 2:
+00760                                                         _VBuffer.setTexCoord(id, i, corn->Uvws[i].U, corn->Uvws[i].V);
+00761                                                 break;
+00762                                                 case 3:
+00763                                                         _VBuffer.setValueFloat3Ex((CVertexBuffer::TValue) (CVertexBuffer::TexCoord0 + i), id, corn->Uvws[i].U, corn->Uvws[i].V, corn->Uvws[i].W);
+00764                                                 break;
+00765                                                 default: // not supported
+00766                                                         nlassert(0);
+00767                                                 break;
+00768                                         }                                       
+00769                                 }
+00770                         }
+00771                         // Color.
+00772                         if(CCornerTmp::Flags & CVertexBuffer::PrimaryColorFlag)
+00773                                 _VBuffer.setColor(id, corn->Color);
+00774                         // Specular.
+00775                         if(CCornerTmp::Flags & CVertexBuffer::SecondaryColorFlag)
+00776                                 _VBuffer.setSpecular(id, corn->Specular);
+00777 
+00778                         // setup palette skinning.
+00779                         if ((CCornerTmp::Flags & CVertexBuffer::PaletteSkinFlag)==CVertexBuffer::PaletteSkinFlag)
+00780                         {
+00781                                 _VBuffer.setPaletteSkin(id, corn->Palette);
+00782                                 for(i=0;i<NL3D_MESH_SKINNING_MAX_MATRIX;i++)
+00783                                         _VBuffer.setWeight(id, i, corn->Weights[i]);
+00784                         }
+00785                 }
+00786         }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::flagSkinVerticesForMatrixBlock uint8 skinFlags,
CMatrixBlock mb
[private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1836 of file mesh.cpp. +

+References NL3D::CPrimitiveBlock::getLinePointer(), NL3D::CPrimitiveBlock::getNumLine(), NL3D::CPrimitiveBlock::getNumQuad(), NL3D::CPrimitiveBlock::getNumTri(), NL3D::CPrimitiveBlock::getQuadPointer(), NL3D::CPrimitiveBlock::getTriPointer(), NL3D_SOFTSKIN_VMUSTCOMPUTE, NL3D::CMeshGeom::CMatrixBlock::RdrPass, uint, uint32, and uint8. +

+Referenced by applySkin(). +

+

01837 {
+01838         for(uint i=0; i<mb.RdrPass.size(); i++)
+01839         {
+01840                 CPrimitiveBlock &PB= mb.RdrPass[i].PBlock;
+01841 
+01842                 uint32  *pIndex;
+01843                 uint    nIndex;
+01844 
+01845                 // This may be better to flags in 2 pass (first traverse primitives, then test vertices).
+01846                 // Better sol for BTB..., because number of tests are divided by 6 (for triangles).
+01847 
+01848                 // for all prims, indicate which vertex we must compute.
+01849                 // nothing if not already computed (ie 0), because 0&1==0.
+01850                 // Lines.
+01851                 pIndex= (uint32*)PB.getLinePointer();
+01852                 nIndex= PB.getNumLine()*2;
+01853                 for(;nIndex>0;nIndex--, pIndex++)
+01854                         skinFlags[*pIndex]&= NL3D_SOFTSKIN_VMUSTCOMPUTE;
+01855                 // Tris.
+01856                 pIndex= (uint32*)PB.getTriPointer();
+01857                 nIndex= PB.getNumTri()*3;
+01858                 for(;nIndex>0;nIndex--, pIndex++)
+01859                         skinFlags[*pIndex]&= NL3D_SOFTSKIN_VMUSTCOMPUTE;
+01860                 // Quads.
+01861                 pIndex= (uint32*)PB.getQuadPointer();
+01862                 nIndex= PB.getNumQuad()*4;
+01863                 for(;nIndex>0;nIndex--, pIndex++)
+01864                         skinFlags[*pIndex]&= NL3D_SOFTSKIN_VMUSTCOMPUTE;
+01865         }
+01866 }
+
+

+ + + + +
+ + + + + + + + + +
const NLMISC::CAABBoxExt& NL3D::CMeshGeom::getBoundingBox  )  const [inline, virtual]
+
+ + + + + +
+   + + +

+get the extended axis aligned bounding box of the mesh +

+ +

+Implements NL3D::IMeshGeom. +

+Definition at line 384 of file mesh.h. +

+Referenced by NL3D::CMesh::getBoundingBox(). +

+

00385         {
+00386                 return _BBox;
+00387         }
+
+

+ + + + +
+ + + + + + + + + +
virtual std::string NLMISC::IClassable::getClassName  )  [pure virtual, inherited]
+
+ + + + + +
+   + + +

+ +

+Implemented in NLAIAGENT::CNumericIndex, NLAIC::IPointerGestion, NLAIC::CIdentType, and CAutomataDesc. +

+Referenced by NLMISC::CClassRegistry::checkObject(), and NL3D::GetTextureSize().

+

+ + + + +
+ + + + + + + + + +
uint NL3D::CMeshGeom::getNbBlendShapes  )  const [inline]
+
+ + + + + +
+   + + +

+get the number of BlendShapes +

+ +

+Definition at line 419 of file mesh.h. +

+References _MeshMorpher, NL3D::CMeshMorpher::BlendShapes, and uint. +

+

00419 { if(_MeshMorpher) return _MeshMorpher->BlendShapes.size(); }
+
+

+ + + + +
+ + + + + + + + + +
uint NL3D::CMeshGeom::getNbMatrixBlock  )  const [inline]
+
+ + + + + +
+   + + +

+get the number of matrix block +

+ +

+Definition at line 393 of file mesh.h. +

+References _MatrixBlocks, and uint. +

+Referenced by NL3D::CZoneLighter::addTriangles(), NL3D::CInstanceLighter::addTriangles(), applyMaterialRemap(), NL3D::CCoarseMeshBuild::buildBitmap(), NL3D::CMeshMultiLod::compileCoarseMeshes(), NL3D::UShape::getMeshTriangles(), NL3D::CMesh::getNbMatrixBlock(), and NL3D::CCoarseMeshBuild::remapCoordinates(). +

+

00393 { return _MatrixBlocks.size() ; }
+
+

+ + + + +
+ + + + + + + + + + +
uint NL3D::CMeshGeom::getNbRdrPass uint  matrixBlockIndex  )  const [inline]
+
+ + + + + +
+   + + +

+get the number of rendering pass for a given matrix block

Parameters:
+ + +
matrixBlockIndex the index of the matrix block the rendering passes belong to
+
+ +

+Definition at line 398 of file mesh.h. +

+References _MatrixBlocks, and uint. +

+Referenced by NL3D::CZoneLighter::addTriangles(), NL3D::CInstanceLighter::addTriangles(), applyMaterialRemap(), NL3D::CCoarseMeshBuild::buildBitmap(), NL3D::CMeshMultiLod::compileCoarseMeshes(), NL3D::UShape::getMeshTriangles(), NL3D::CMesh::getNbRdrPass(), and NL3D::CCoarseMeshBuild::remapCoordinates(). +

+

00398 { return _MatrixBlocks[matrixBlockIndex].RdrPass.size() ; }
+
+

+ + + + +
+ + + + + + + + + + +
uint NL3D::CMeshGeom::getNumRdrPassesForInstance CMeshBaseInstance inst  )  const [virtual]
+
+ + + + + +
+   + + +

+return the number of renderPasses for this instance. Called after activateInstance() Used only if sortPerMaterial()) is false +

+Implements NL3D::IMeshGeom. +

+Definition at line 2016 of file mesh.cpp. +

+References _MatrixBlocks, and uint. +

+

02017 {
+02018         return _MatrixBlocks[0].RdrPass.size();
+02019 }
+
+

+ + + + +
+ + + + + + + + + +
uint NL3D::CMeshGeom::getNumRdrPassesForMesh  )  const [virtual]
+
+ + + + + +
+   + + +

+return the number of renderPasses for this mesh. Used only if sortPerMaterial()) is true +

+Implements NL3D::IMeshGeom. +

+Definition at line 2011 of file mesh.cpp. +

+References _MatrixBlocks, and uint. +

+

02012 {
+02013         return _MatrixBlocks[0].RdrPass.size();
+02014 }
+
+

+ + + + +
+ + + + + + + + + + +
float NL3D::CMeshGeom::getNumTriangles float  distance  )  [virtual]
+
+ + + + + +
+   + + +

+clip this mesh +

+ +

+Implements NL3D::IMeshGeom. +

+Definition at line 1429 of file mesh.cpp. +

+References _MatrixBlocks, NL3D::CPrimitiveBlock::getNumTriangles(), NL3D::CMeshGeom::CRdrPass::PBlock, NL3D::CMeshGeom::CMatrixBlock::RdrPass, uint, and uint32. +

+

01430 {
+01431         // Sum of triangles
+01432         uint32 triCount=0;
+01433 
+01434         // For each matrix block
+01435         uint mbCount=_MatrixBlocks.size();
+01436         for (uint mb=0; mb<mbCount; mb++)
+01437         {
+01438                 CMatrixBlock &block=_MatrixBlocks[mb];
+01439 
+01440                 // Count of primitive block
+01441                 uint pCount=block.RdrPass.size();
+01442                 for (uint pb=0; pb<pCount; pb++)
+01443                 {
+01444                         // Ref on the primitive block
+01445                         CRdrPass &pass=block.RdrPass[pb];
+01446 
+01447                         // Sum tri
+01448                         triCount+=pass.PBlock.getNumTriangles ();
+01449                 }
+01450         }
+01451         return (float)triCount;
+01452 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
uint32 NL3D::CMeshGeom::getRdrPassMaterial uint  matrixBlockIndex,
uint  renderingPassIndex
const [inline]
+
+ + + + + +
+   + + +

+get the material ID associated with a rendering pass of a matrix block

Parameters:
+ + + +
matrixBlockIndex the index of the matrix block the renderin pass belong to
renderingPassIndex the index of the rendering pass in the matrix block
+
+ +

+Definition at line 413 of file mesh.h. +

+References _MatrixBlocks, uint, and uint32. +

+Referenced by NL3D::CZoneLighter::addTriangles(), NL3D::CCoarseMeshBuild::buildBitmap(), NL3D::CMesh::getRdrPassMaterial(), and NL3D::CCoarseMeshBuild::remapCoordinates(). +

+

00414         {
+00415                 return _MatrixBlocks[matrixBlockIndex].RdrPass[renderingPassIndex].MaterialId ;
+00416         }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
const CPrimitiveBlock& NL3D::CMeshGeom::getRdrPassPrimitiveBlock uint  matrixBlockIndex,
uint  renderingPassIndex
const [inline]
+
+ + + + + +
+   + + +

+get the primitive block associated with a rendering pass of a matrix block

Parameters:
+ + + +
matrixBlockIndex the index of the matrix block the renderin pass belong to
renderingPassIndex the index of the rendering pass in the matrix block
+
+ +

+Definition at line 404 of file mesh.h. +

+References _MatrixBlocks, and uint. +

+Referenced by NL3D::CZoneLighter::addTriangles(), NL3D::CInstanceLighter::addTriangles(), NL3D::CMeshMultiLod::compileCoarseMeshes(), NL3D::UShape::getMeshTriangles(), NL3D::CMesh::getRdrPassPrimitiveBlock(), and NL3D::CCoarseMeshBuild::remapCoordinates(). +

+

00405         {
+00406                 return _MatrixBlocks[matrixBlockIndex].RdrPass[renderingPassIndex].PBlock ;
+00407         }
+
+

+ + + + +
+ + + + + + + + + +
const std::vector<sint32>& NL3D::CMeshGeom::getSkinBoneUsage  )  const [inline]
+
+ + + + + +
+   + + +

+return array of bones used by the skin. computeBonesId must has been called before. +

+ +

+Definition at line 440 of file mesh.h. +

+References _BonesId. +

+Referenced by NL3D::CMeshInstance::getSkinBoneUsage(). +

+

00440 {return _BonesId;}
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool NL3D::CMeshGeom::getVBHeapInfo uint vertexFormat,
uint numVertices
[virtual]
+
+ + + + + +
+   + + +

+The framework call this method to know if the mesh can fit in VBHeap. if yes, deriver must return mesh vertexFormat and num of vertices. +

+Reimplemented from NL3D::IMeshGeom. +

+Definition at line 2114 of file mesh.cpp. +

+References _MeshVertexProgram, _SupportMBRFlags, NL3D::CVertexBuffer::getNumVertices(), NL3D::CVertexBuffer::getVertexFormat(), and uint. +

+

02115 {
+02116         // CMeshGeom support VBHeap rendering, assuming supportMeshBlockRendering is true.
+02117         if( _SupportMBRFlags )
+02118         /* Yoyo: If VertexProgram, DON'T SUPPORT!! because VB need to be activated AFTER meshVP activation
+02119                 NB: still possible with complex code to do it (sort per VP type (with or not)...), but tests in Ryzom
+02120                 shows that VBHeap is not really important (not so much different shapes...)
+02121         */
+02122         if( _MeshVertexProgram==NULL )
+02123         {
+02124                 vertexFormat= _VBuffer.getVertexFormat();
+02125                 numVertices= _VBuffer.getNumVertices();
+02126                 return true;
+02127         }
+02128 
+02129         return false;
+02130 }
+
+

+ + + + +
+ + + + + + + + + +
const CVertexBuffer& NL3D::CMeshGeom::getVertexBuffer  )  const [inline]
+
+ + + + + +
+   + + +

+get the vertex buffer used by the mesh +

+ +

+Definition at line 390 of file mesh.h. +

+Referenced by NL3D::CZoneLighter::addTriangles(), NL3D::CInstanceLighter::addTriangles(), NL3D::UShape::getMeshTriangles(), NL3D::CMesh::getVertexBuffer(), NL3D::CMeshMultiLod::instanciateCoarseMeshSpace(), NL3D::CCoarseMeshBuild::remapCoordinates(), NL3D::CMeshMultiLod::renderCoarseMesh(), NL3D::CMeshMultiLodInstance::setPosCoarseMesh(), and NL3D::CMeshMultiLodInstance::setUVCoarseMesh(). +

+

00390 { return _VBuffer ; }
+
+

+ + + + +
+ + + + + + + + + +
virtual bool NL3D::CMeshGeom::hasMeshVertexProgram  )  const [inline, virtual]
+
+ + + + + +
+   + + +

+True if this mesh has a vertexProgram. +

+ +

+Reimplemented from NL3D::IMeshGeom. +

+Definition at line 478 of file mesh.h. +

+References _MeshVertexProgram. +

+Referenced by NL3D::CMeshInstance::initRenderFilterType(). +

+

00478 {return _MeshVertexProgram!=NULL;}
+
+

+ + + + +
+ + + + + + + + + + +
void NL3D::CMeshGeom::initInstance CMeshBaseInstance mbi  )  [virtual]
+
+ + + + + +
+   + + +

+Init instance info. +

+ +

+Implements NL3D::IMeshGeom. +

+Definition at line 474 of file mesh.cpp. +

+References _MeshVertexProgram. +

+Referenced by NL3D::CMesh::createInstance(). +

+

00475 {
+00476         // init the instance with _MeshVertexProgram infos
+00477         if(_MeshVertexProgram)
+00478                 _MeshVertexProgram->initInstance(mbi);
+00479 }
+
+

+ + + + +
+ + + + + + + + + +
virtual bool NL3D::IMeshGeom::isActiveInstanceNeedVBFill  )  const [inline, virtual, inherited]
+
+ + + + + +
+   + + +

+Return true if the meshGeom has to Fill some Vertices at activeInstance() time if VBHeap enabled at this time, then vbDst in activeInstance(,,,vbDst) will contains the vb to write to. +

+Reimplemented in NL3D::CMeshMRMGeom. +

+Definition at line 212 of file mesh_geom.h. +

+Referenced by NL3D::CMeshBlockManager::render(). +

+

00212 {return false;}
+
+

+ + + + +
+ + + + + + + + + +
bool NL3D::IMeshGeom::isMeshInVBHeap  )  const [inline, inherited]
+
+ + + + + +
+   + + +

+Return true if the meshGeom has to Fill some Vertices at activeInstance() time if VBHeap enabled at this time, then vbDst in activeInstance(,,,vbDst) will contains the vb to write to. +

+Definition at line 215 of file mesh_geom.h. +

+References NL3D::IMeshGeom::_MeshVBHeapId. +

+Referenced by NL3D::CMeshMRMGeom::profileSceneRender(), and profileSceneRender(). +

+

00215 {return _MeshVBHeapId!=0;}
+
+

+ + + + +
+ + + + + + + + + +
bool NL3D::CMeshGeom::isSkinned  )  const [inline]
+
+ + + + + +
+   + + +

+Return true if the mesh is skinned, else return false. +

+ +

+Definition at line 428 of file mesh.h. +

+References _Skinned. +

+Referenced by NL3D::CMeshInstance::isSkinnable(). +

+

00429         {
+00430                 return _Skinned;
+00431         }
+
+

+ + + + +
+ + + + + + + + + + +
NL3D::CMeshGeom::NLMISC_DECLARE_CLASS CMeshGeom   ) 
+
+ + + + + +
+   + + +

+clip this mesh +

+

+

+ + + + +
+ + + + + + + + + +
void NL3D::CMeshGeom::optimizeTriangleOrder  )  [private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 153 of file mesh.cpp. +

+References _MatrixBlocks, NL3D::CStripifier::optimizeTriangles(), NL3D::CMeshGeom::CRdrPass::PBlock, and uint. +

+Referenced by build(). +

+

00154 {
+00155         CStripifier             stripifier;
+00156 
+00157         // for all rdrpass of all matrix blocks.
+00158         for(uint mb= 0;mb<_MatrixBlocks.size();mb++)
+00159         {
+00160                 for(uint  rp=0; rp<_MatrixBlocks[mb].RdrPass.size(); rp++ )
+00161                 {
+00162                         // stripify list of triangles of this pass.
+00163                         CRdrPass        &pass= _MatrixBlocks[mb].RdrPass[rp];
+00164                         stripifier.optimizeTriangles(pass.PBlock, pass.PBlock);
+00165                 }
+00166         }
+00167 
+00168 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::profileSceneRender CRenderTrav rdrTrav,
CTransformShape trans,
float  polygonCount,
uint32  rdrFlags
[virtual]
+
+ + + + + +
+   + + +

+clip this mesh +

+ +

+Implements NL3D::IMeshGeom. +

+Definition at line 1932 of file mesh.cpp. +

+References _MatrixBlocks, _VertexBufferHard, NL3D::CScene::BenchRes, NL3D::CPrimitiveBlock::getNumTri(), NL3D::CVertexBuffer::getVertexFormat(), NL3D::CScene::incrementProfileTriVBFormat(), NL3D::IMeshGeom::isMeshInVBHeap(), NL3D::CMeshGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, NL3D::UScene::CBenchResults::MeshProfileTriVBFormat, NL3D::UScene::CBenchResults::NumMeshRdrBlock, NL3D::UScene::CBenchResults::NumMeshRdrBlockWithVBHeap, NL3D::UScene::CBenchResults::NumMeshRdrNormal, NL3D::UScene::CBenchResults::NumMeshTriRdrBlock, NL3D::UScene::CBenchResults::NumMeshTriRdrBlockWithVBHeap, NL3D::UScene::CBenchResults::NumMeshTriRdrNormal, NL3D::UScene::CBenchResults::NumMeshVBufferHard, NL3D::UScene::CBenchResults::NumMeshVBufferStd, NL3D::CMeshGeom::CRdrPass::PBlock, NL3D::CMeshGeom::CMatrixBlock::RdrPass, NL3D::CTraversal::Scene, supportMeshBlockRendering(), uint, and uint32. +

+Referenced by NL3D::CMesh::profileSceneRender(). +

+

01933 {
+01934         // get the mesh instance.
+01935         CMeshBaseInstance       *mi= safe_cast<CMeshBaseInstance*>(trans);
+01936 
+01937         // For all _MatrixBlocks
+01938         uint    triCount= 0;
+01939         for(uint mb=0;mb<_MatrixBlocks.size();mb++)
+01940         {
+01941                 CMatrixBlock    &mBlock= _MatrixBlocks[mb];
+01942 
+01943                 // Profile all pass.
+01944                 for (uint i=0;i<mBlock.RdrPass.size();i++)
+01945                 {
+01946                         CRdrPass        &rdrPass= mBlock.RdrPass[i];
+01947                         // Profile with the Materials of the MeshInstance.
+01948                         if ( ( (mi->Materials[rdrPass.MaterialId].getBlend() == false) && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) ) ||
+01949                                  ( (mi->Materials[rdrPass.MaterialId].getBlend() == true) && (rdrFlags & IMeshGeom::RenderTransparentMaterial) ) )
+01950                         {
+01951                                 triCount+= rdrPass.PBlock.getNumTri();
+01952                         }
+01953                 }
+01954         }
+01955 
+01956         // Profile
+01957         if(triCount)
+01958         {
+01959                 // tri per VBFormat
+01960                 rdrTrav->Scene->incrementProfileTriVBFormat(rdrTrav->Scene->BenchRes.MeshProfileTriVBFormat, 
+01961                         _VBuffer.getVertexFormat(), triCount);
+01962 
+01963                 // VBHard
+01964                 if(_VertexBufferHard)
+01965                         rdrTrav->Scene->BenchRes.NumMeshVBufferHard++;
+01966                 else
+01967                         rdrTrav->Scene->BenchRes.NumMeshVBufferStd++;
+01968 
+01969                 // rendered in BlockRendering, only if not transparent pass (known it if RenderTransparentMaterial is set)
+01970                 if(supportMeshBlockRendering() && (rdrFlags & IMeshGeom::RenderTransparentMaterial)==0 )
+01971                 {
+01972                         if(isMeshInVBHeap())
+01973                         {
+01974                                 rdrTrav->Scene->BenchRes.NumMeshRdrBlockWithVBHeap++;
+01975                                 rdrTrav->Scene->BenchRes.NumMeshTriRdrBlockWithVBHeap+= triCount;
+01976                         }
+01977                         else
+01978                         {
+01979                                 rdrTrav->Scene->BenchRes.NumMeshRdrBlock++;
+01980                                 rdrTrav->Scene->BenchRes.NumMeshTriRdrBlock+= triCount;
+01981                         }
+01982                 }
+01983                 else
+01984                 {
+01985                         rdrTrav->Scene->BenchRes.NumMeshRdrNormal++;
+01986                         rdrTrav->Scene->BenchRes.NumMeshTriRdrNormal+= triCount;
+01987                 }
+01988         }
+01989 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::render IDriver drv,
CTransformShape trans,
float  polygonCount,
uint32  rdrFlags,
float  globalAlpha
[virtual]
+
+ + + + + +
+   + + +

+render() this mesh in a driver. +

+ +

+Implements NL3D::IMeshGeom. +

+Definition at line 598 of file mesh.cpp. +

+References _MatrixBlocks, _MeshMorpher, _MeshVertexProgram, _OriginalSkinNormals, _OriginalSkinRestored, _OriginalSkinVertices, _OriginalTGSpace, _Skinned, _VBufferOri, _VertexBufferHard, NL3D::IDriver::activeVertexBuffer(), NL3D::IDriver::activeVertexBufferHard(), NL3D::CMeshMorpher::BlendShapes, NL3D::CTravCameraScene::CamPos, NL3D::CMeshBaseInstance::getBlendShapeFactors(), NL3D::CTransform::getOwnerScene(), NL3D::CScene::getRenderTrav(), NL3D::CTransform::getSkeletonModel(), NL3D::CTransform::getWorldMatrix(), H_AUTO, NL3D::CMeshMorpher::init(), NL3D::CMeshMorpher::initSkinned(), NLMISC::CMatrix::inverted(), NL3D::CTransform::isSkinned(), NL3D::CMeshGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, nlassert, NLMISC::OptFastFloor(), NL3D::CMeshGeom::CRdrPass::PBlock, NL3D::CMeshBlender::prepareRenderForGlobalAlpha(), NL3D::CMeshGeom::CMatrixBlock::RdrPass, NL3D::IDriver::render(), restoreOriginalSkinVertices(), NL3D::CMeshBlender::restoreRender(), NL3D::IDriver::setupModelMatrix(), uint, uint32, uint8, NL3D::CMeshMorpher::update(), NL3D::CMeshMorpher::updateSkinned(), and updateVertexBufferHard(). +

+Referenced by NL3D::CMesh::render(). +

+

00599 {
+00600         nlassert(drv);
+00601         // get the mesh instance.
+00602         CMeshBaseInstance       *mi= safe_cast<CMeshBaseInstance*>(trans);
+00603         // get a ptr on scene
+00604         CScene                  *ownerScene= mi->getOwnerScene();
+00605         // get a ptr on renderTrav
+00606         CRenderTrav             *renderTrav= &ownerScene->getRenderTrav();
+00607 
+00608         // update the VBufferHard (create/delete), to maybe render in AGP memory.
+00609         updateVertexBufferHard (drv);
+00610         /* currentVBHard is NULL if must disable it temporarily
+00611                 For now, never disable it, but switch of VBHard may be VERY EXPENSIVE if NV_vertex_array_range2 is not
+00612                 supported (old drivers).
+00613         */
+00614         IVertexBufferHard               *currentVBHard= _VertexBufferHard;
+00615 
+00616 
+00617         // get the skeleton model to which I am binded (else NULL).
+00618         CSkeletonModel          *skeleton;
+00619         skeleton= mi->getSkeletonModel();
+00620         // The mesh must not be skinned for render()
+00621         nlassert(!(_Skinned && mi->isSkinned() && skeleton));
+00622         bool bMorphApplied = _MeshMorpher->BlendShapes.size() > 0;
+00623         bool useTangentSpace = _MeshVertexProgram && _MeshVertexProgram->needTangentSpace();
+00624 
+00625 
+00626         // Profiling
+00627         //===========
+00628         H_AUTO( NL3D_MeshGeom_RenderNormal );
+00629 
+00630 
+00631         // Morphing
+00632         // ========
+00633         if (bMorphApplied)
+00634         {
+00635                 // If _Skinned (NB: the skin is not applied) and if lod.OriginalSkinRestored, then restoreOriginalSkinPart is
+00636                 // not called but mush morpher write changed vertices into VBHard so its ok. The unchanged vertices
+00637                 // are written in the preceding call to restoreOriginalSkinPart.
+00638                 if (_Skinned)
+00639                 {
+00640                         _MeshMorpher->initSkinned(&_VBufferOri,
+00641                                                                  &_VBuffer,
+00642                                                                  currentVBHard,
+00643                                                                  useTangentSpace,
+00644                                                                  &_OriginalSkinVertices,
+00645                                                                  &_OriginalSkinNormals,
+00646                                                                  useTangentSpace ? &_OriginalTGSpace : NULL,
+00647                                                                  false );
+00648                         _MeshMorpher->updateSkinned (mi->getBlendShapeFactors());
+00649                 }
+00650                 else // Not even skinned so we have to do all the stuff
+00651                 {
+00652                         _MeshMorpher->init(&_VBufferOri,
+00653                                                                  &_VBuffer,
+00654                                                                  currentVBHard,
+00655                                                                  useTangentSpace);
+00656                         _MeshMorpher->update (mi->getBlendShapeFactors());
+00657                 }
+00658         }
+00659 
+00660 
+00661         // Skinning
+00662         // ========
+00663 
+00664         // else setup instance matrix
+00665         drv->setupModelMatrix(trans->getWorldMatrix());
+00666 
+00667 
+00668         // since instance skin is invalid but mesh is skinned , we must copy vertices/normals from original vertices.
+00669         if (_Skinned)
+00670         {
+00671                 // do it for this Lod only, and if cache say it is necessary.
+00672                 if (!_OriginalSkinRestored)
+00673                         restoreOriginalSkinVertices();
+00674         }
+00675 
+00676 
+00677         // Setup meshVertexProgram
+00678         //===========
+00679 
+00680         // use MeshVertexProgram effect?
+00681         bool    useMeshVP= _MeshVertexProgram != NULL;
+00682         if( useMeshVP )
+00683         {
+00684                 CMatrix         invertedObjectMatrix;
+00685                 invertedObjectMatrix = trans->getWorldMatrix().inverted();
+00686                 // really ok if success to begin VP
+00687                 useMeshVP= _MeshVertexProgram->begin(drv, ownerScene, mi, invertedObjectMatrix, renderTrav->CamPos);
+00688         }
+00689         
+00690 
+00691         // Render the mesh.
+00692         //===========
+00693         // active VB.
+00694         if(currentVBHard != NULL)
+00695                 drv->activeVertexBufferHard(currentVBHard);
+00696         else
+00697                 drv->activeVertexBuffer(_VBuffer);
+00698 
+00699 
+00700         // Global alpha used ?
+00701         uint32  globalAlphaUsed= rdrFlags & IMeshGeom::RenderGlobalAlpha;
+00702         uint8   globalAlphaInt=(uint8)NLMISC::OptFastFloor(globalAlpha*255);
+00703 
+00704 
+00705         // For all _MatrixBlocks
+00706         for(uint mb=0;mb<_MatrixBlocks.size();mb++)
+00707         {
+00708                 CMatrixBlock    &mBlock= _MatrixBlocks[mb];
+00709                 if(mBlock.RdrPass.size()==0)
+00710                         continue;
+00711 
+00712                 // Global alpha ?
+00713                 if (globalAlphaUsed)
+00714                 {
+00715                         bool    gaDisableZWrite= (rdrFlags & IMeshGeom::RenderGADisableZWrite)?true:false;
+00716 
+00717                         // Render all pass.
+00718                         for (uint i=0;i<mBlock.RdrPass.size();i++)
+00719                         {
+00720                                 CRdrPass        &rdrPass= mBlock.RdrPass[i];
+00721                                 // Render with the Materials of the MeshInstance.
+00722                                 if ( ( (mi->Materials[rdrPass.MaterialId].getBlend() == false) && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) ) ||
+00723                                          ( (mi->Materials[rdrPass.MaterialId].getBlend() == true) && (rdrFlags & IMeshGeom::RenderTransparentMaterial) ) )
+00724                                 {
+00725                                         // CMaterial Ref
+00726                                         CMaterial &material=mi->Materials[rdrPass.MaterialId];
+00727 
+00728                                         // Use a MeshBlender to modify material and driver.
+00729                                         CMeshBlender    blender;
+00730                                         blender.prepareRenderForGlobalAlpha(material, drv, globalAlpha, globalAlphaInt, gaDisableZWrite);
+00731 
+00732                                         // Setup VP material
+00733                                         if (useMeshVP)
+00734                                         {
+00735                                                 if(currentVBHard)
+00736                                                         _MeshVertexProgram->setupForMaterial(material, drv, ownerScene, currentVBHard);
+00737                                                 else
+00738                                                         _MeshVertexProgram->setupForMaterial(material, drv, ownerScene, &_VBuffer);
+00739                                         }
+00740 
+00741                                         // Render
+00742                                         drv->render(rdrPass.PBlock, material);
+00743 
+00744                                         // Resetup material/driver
+00745                                         blender.restoreRender(material, drv, gaDisableZWrite);
+00746                                 }
+00747                         }
+00748                 }
+00749                 else
+00750                 {
+00751                         // Render all pass.
+00752                         for(uint i=0;i<mBlock.RdrPass.size();i++)
+00753                         {
+00754                                 CRdrPass        &rdrPass= mBlock.RdrPass[i];
+00755                                 // Render with the Materials of the MeshInstance.
+00756                                 if( ( (mi->Materials[rdrPass.MaterialId].getBlend() == false) && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) ) ||
+00757                                         ( (mi->Materials[rdrPass.MaterialId].getBlend() == true) && (rdrFlags & IMeshGeom::RenderTransparentMaterial) )         )
+00758                                 {
+00759                                         // CMaterial Ref
+00760                                         CMaterial &material=mi->Materials[rdrPass.MaterialId];
+00761 
+00762                                         // Setup VP material
+00763                                         if (useMeshVP)
+00764                                         {
+00765                                                 if(currentVBHard)
+00766                                                         _MeshVertexProgram->setupForMaterial(material, drv, ownerScene, currentVBHard);
+00767                                                 else
+00768                                                         _MeshVertexProgram->setupForMaterial(material, drv, ownerScene, &_VBuffer);
+00769                                         }                                                                       
+00770 
+00771                                         // render primitives
+00772                                         drv->render(rdrPass.PBlock, material);
+00773                                 }
+00774                         }
+00775                 }
+00776         }
+00777 
+00778         // End VertexProgram effect
+00779         if(useMeshVP)
+00780         {
+00781                 // Apply it.
+00782                 _MeshVertexProgram->end(drv);
+00783         }
+00784 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::renderPass CMeshGeomRenderContext rdrCtx,
CMeshBaseInstance inst,
float  polygonCount,
uint  rdrPass
[virtual]
+
+ + + + + +
+   + + +

+The framework call this method to render the current renderPass, with the current instance NB: if the material is blended, DON'T render it!! +

+Implements NL3D::IMeshGeom. +

+Definition at line 2075 of file mesh.cpp. +

+References _MatrixBlocks, _SupportMBRFlags, NL3D::CRenderTrav::changeVPLightSetupMaterial(), NL3D::CMeshGeomRenderContext::Driver, NL3D::CMeshGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, MBRCurrentUseVP, NL3D::CMeshGeom::CRdrPass::PBlock, NL3D::CMeshGeom::CMatrixBlock::RdrPass, NL3D::IDriver::render(), NL3D::CMeshGeomRenderContext::RenderThroughVBHeap, NL3D::CMeshGeomRenderContext::RenderTrav, uint, and NL3D::CMeshGeom::CRdrPass::VBHeapPBlock. +

+

02076 {
+02077         CMatrixBlock    &mBlock= _MatrixBlocks[0];
+02078 
+02079         CRdrPass                &rdrPass= mBlock.RdrPass[rdrPassId];
+02080         // Render with the Materials of the MeshInstance, only if not blended.
+02081         if( ( (mi->Materials[rdrPass.MaterialId].getBlend() == false) ) )
+02082         {
+02083                 CMaterial       &material= mi->Materials[rdrPass.MaterialId];
+02084 
+02085                 // MeshVertexProgram ?
+02086                 if( _SupportMBRFlags & MBRCurrentUseVP )
+02087                 {
+02088                         rdrCtx.RenderTrav->changeVPLightSetupMaterial(material, false);
+02089                 }
+02090 
+02091                 if(rdrCtx.RenderThroughVBHeap)
+02092                         // render shifted primitives
+02093                         rdrCtx.Driver->render(rdrPass.VBHeapPBlock, material);
+02094                 else
+02095                         // render primitives
+02096                         rdrCtx.Driver->render(rdrPass.PBlock, material);
+02097         }
+02098 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::renderSimpleWithMaterial IDriver drv,
const CMatrix worldMatrix,
CMaterial mat
+
+ + + + + +
+   + + +

+render the mesh geometry with a single material. Render is said "Simple" because no special features are used:

    +
  • mesh is rendered without VertexProgram (if it has one).
  • mesh is rendered without Skinning.
  • mesh is rendered without use of VertexBufferHard.
  • mesh is rendered without MeshMorpher.
  • .....
+ +

+Definition at line 915 of file mesh.cpp. +

+References _MatrixBlocks, NL3D::IDriver::activeVertexBuffer(), H_AUTO, nlassert, NL3D::CMeshGeom::CRdrPass::PBlock, NL3D::CMeshGeom::CMatrixBlock::RdrPass, NL3D::IDriver::render(), NL3D::IDriver::setupModelMatrix(), and uint. +

+Referenced by NL3D::CMeshMultiLod::renderMeshGeom(). +

+

00916 {
+00917         H_AUTO( NL3D_MeshGeom_RenderSimpleWithMaterial );
+00918 
+00919         nlassert(drv);
+00920 
+00921         // setup matrix
+00922         drv->setupModelMatrix(worldMatrix);
+00923 
+00924         // Active simple VB.
+00925         drv->activeVertexBuffer(_VBuffer);
+00926 
+00927         // For all _MatrixBlocks
+00928         for(uint mb=0;mb<_MatrixBlocks.size();mb++)
+00929         {
+00930                 CMatrixBlock    &mBlock= _MatrixBlocks[mb];
+00931                 if(mBlock.RdrPass.size()==0)
+00932                         continue;
+00933 
+00934                 // Render all pass.
+00935                 for(uint i=0;i<mBlock.RdrPass.size();i++)
+00936                 {
+00937                         CRdrPass        &rdrPass= mBlock.RdrPass[i];
+00938 
+00939                         // render primitives
+00940                         drv->render(rdrPass.PBlock, mat);
+00941                 }
+00942         }
+00943 
+00944 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::renderSkin CTransformShape trans,
float  alphaMRM
[virtual]
+
+ + + + + +
+   + + +

+render() this mesh as a skin +

+ +

+Implements NL3D::IMeshGeom. +

+Definition at line 788 of file mesh.cpp. +

+References _MatrixBlocks, _MeshMorpher, _MeshVertexProgram, _OriginalSkinNormals, _OriginalSkinVertices, _OriginalTGSpace, _Skinned, _VBufferOri, _VertexBufferHard, NL3D::IDriver::activeVertexBuffer(), NL3D::IDriver::activeVertexBufferHard(), applySkin(), NL3D::CMeshMorpher::BlendShapes, NL3D::CTravCameraScene::CamPos, NL3D::CMeshBaseInstance::getBlendShapeFactors(), NL3D::CRenderTrav::getDriver(), NL3D::CTransform::getOwnerScene(), NL3D::CScene::getRenderTrav(), NL3D::CTransform::getSkeletonModel(), NL3D::CTransform::getWorldMatrix(), H_AUTO, NL3D::CMeshMorpher::initSkinned(), NLMISC::CMatrix::inverted(), NL3D::CTransform::isSkinned(), NL3D::CMeshGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, nlassert, NL3D::CMeshGeom::CRdrPass::PBlock, NL3D::CMeshGeom::CMatrixBlock::RdrPass, NL3D::IDriver::render(), uint, NL3D::CMeshMorpher::updateSkinned(), and updateVertexBufferHard(). +

+Referenced by NL3D::CMeshInstance::renderSkin(). +

+

00789 {
+00790         // get the mesh instance.
+00791         CMeshBaseInstance       *mi= safe_cast<CMeshBaseInstance*>(trans);
+00792         // get a ptr on scene
+00793         CScene                  *ownerScene= mi->getOwnerScene();
+00794         // get a ptr on renderTrav
+00795         CRenderTrav             *renderTrav= &ownerScene->getRenderTrav();
+00796         // get a ptr on the driver
+00797         IDriver                 *drv= renderTrav->getDriver();
+00798         nlassert(drv);
+00799 
+00800 
+00801         // update the VBufferHard (create/delete), to maybe render in AGP memory.
+00802         updateVertexBufferHard (drv);
+00803         /* currentVBHard is NULL if must disable it temporarily
+00804                 For now, never disable it, but switch of VBHard may be VERY EXPENSIVE if NV_vertex_array_range2 is not
+00805                 supported (old drivers).
+00806         */
+00807         IVertexBufferHard               *currentVBHard= _VertexBufferHard;
+00808 
+00809 
+00810         // get the skeleton model to which I am binded (else NULL).
+00811         CSkeletonModel          *skeleton;
+00812         skeleton= mi->getSkeletonModel();
+00813         // must be skinned for renderSkin()
+00814         nlassert(_Skinned && mi->isSkinned() && skeleton);
+00815         bool bMorphApplied = _MeshMorpher->BlendShapes.size() > 0;
+00816         bool useTangentSpace = _MeshVertexProgram && _MeshVertexProgram->needTangentSpace();
+00817 
+00818 
+00819         // Profiling
+00820         //===========
+00821         H_AUTO( NL3D_MeshGeom_RenderSkinned );
+00822 
+00823 
+00824         // Morphing
+00825         // ========
+00826         if (bMorphApplied)
+00827         {
+00828                 // Since Skinned we must update original skin vertices and normals because skinning use it
+00829                 _MeshMorpher->initSkinned(&_VBufferOri,
+00830                                                          &_VBuffer,
+00831                                                          currentVBHard,
+00832                                                          useTangentSpace,
+00833                                                          &_OriginalSkinVertices,
+00834                                                          &_OriginalSkinNormals,
+00835                                                          useTangentSpace ? &_OriginalTGSpace : NULL,
+00836                                                          true );
+00837                 _MeshMorpher->updateSkinned (mi->getBlendShapeFactors());
+00838         }
+00839 
+00840 
+00841         // Skinning
+00842         // ========
+00843 
+00844         // NB: the skeleton matrix has already been setuped by CSkeletonModel
+00845         // NB: the normalize flag has already been setuped by CSkeletonModel
+00846 
+00847 
+00848         // apply the skinning: _VBuffer is modified.
+00849         applySkin(skeleton);
+00850 
+00851 
+00852         // Setup meshVertexProgram
+00853         //===========
+00854 
+00855         // use MeshVertexProgram effect?
+00856         bool    useMeshVP= _MeshVertexProgram != NULL;
+00857         if( useMeshVP )
+00858         {
+00859                 CMatrix         invertedObjectMatrix;
+00860                 invertedObjectMatrix = skeleton->getWorldMatrix().inverted();
+00861                 // really ok if success to begin VP
+00862                 useMeshVP= _MeshVertexProgram->begin(drv, ownerScene, mi, invertedObjectMatrix, renderTrav->CamPos);
+00863         }
+00864         
+00865 
+00866         // Render the mesh.
+00867         //===========
+00868         // active VB.
+00869         if(currentVBHard != NULL)
+00870                 drv->activeVertexBufferHard(currentVBHard);
+00871         else
+00872                 drv->activeVertexBuffer(_VBuffer);
+00873 
+00874 
+00875         // For all _MatrixBlocks
+00876         for(uint mb=0;mb<_MatrixBlocks.size();mb++)
+00877         {
+00878                 CMatrixBlock    &mBlock= _MatrixBlocks[mb];
+00879                 if(mBlock.RdrPass.size()==0)
+00880                         continue;
+00881 
+00882                 // Render all pass.
+00883                 for(uint i=0;i<mBlock.RdrPass.size();i++)
+00884                 {
+00885                         CRdrPass        &rdrPass= mBlock.RdrPass[i];
+00886 
+00887                         // CMaterial Ref
+00888                         CMaterial &material=mi->Materials[rdrPass.MaterialId];
+00889 
+00890                         // Setup VP material
+00891                         if (useMeshVP)
+00892                         {
+00893                                 if(currentVBHard)
+00894                                         _MeshVertexProgram->setupForMaterial(material, drv, ownerScene, currentVBHard);
+00895                                 else
+00896                                         _MeshVertexProgram->setupForMaterial(material, drv, ownerScene, &_VBuffer);
+00897                         }                                                                       
+00898 
+00899                         // render primitives
+00900                         drv->render(rdrPass.PBlock, material);
+00901                 }
+00902         }
+00903 
+00904         // End VertexProgram effect
+00905         if(useMeshVP)
+00906         {
+00907                 // Apply it.
+00908                 _MeshVertexProgram->end(drv);
+00909         }
+00910 
+00911 }
+
+

+ + + + +
+ + + + + + + + + +
void NL3D::CMeshGeom::restoreOriginalSkinVertices  )  [private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 1663 of file mesh.cpp. +

+References _MeshVertexProgram, _OriginalSkinNormals, _OriginalSkinRestored, _OriginalSkinVertices, _OriginalTGSpace, _Skinned, NL3D::CVertexBuffer::getNormalCoordPointer(), NL3D::CVertexBuffer::getNumTexCoordUsed(), NL3D::CVertexBuffer::getNumVertices(), NL3D::CVertexBuffer::getTexCoordPointer(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexFormat(), nlassert, and uint. +

+Referenced by render(). +

+

01664 {
+01665         nlassert(_Skinned);
+01666 
+01667         // get num of vertices
+01668         uint    numVertices= _VBuffer.getNumVertices();
+01669 
+01670         // Copy VBuffer content into Original vertices normals.
+01671         if(_VBuffer.getVertexFormat() & CVertexBuffer::PositionFlag)
+01672         {
+01673                 // copy vertices from VBuffer. (NB: unusefull geomorphed vertices are still copied, but doesn't matter).
+01674                 for(uint i=0; i<numVertices;i++)
+01675                 {
+01676                         *(CVector*)_VBuffer.getVertexCoordPointer(i)= _OriginalSkinVertices[i];
+01677                 }
+01678         }
+01679         if(_VBuffer.getVertexFormat() & CVertexBuffer::NormalFlag)
+01680         {
+01681                 // copy normals from VBuffer. (NB: unusefull geomorphed normals are still copied, but doesn't matter).
+01682                 for(uint i=0; i<numVertices;i++)
+01683                 {
+01684                         *(CVector*)_VBuffer.getNormalCoordPointer(i)= _OriginalSkinNormals[i];
+01685                 }
+01686         }
+01687         if (_MeshVertexProgram && _MeshVertexProgram->needTangentSpace())
+01688         {
+01689                 uint numTexCoords = _VBuffer.getNumTexCoordUsed();
+01690                 nlassert(numTexCoords >= 2);
+01691                 nlassert(_OriginalTGSpace.size() == numVertices);
+01692                 // copy tangent space vectors
+01693                 for(uint i = 0; i < numVertices; ++i)
+01694                 {
+01695                         *(CVector*)_VBuffer.getTexCoordPointer(i, numTexCoords - 1)= _OriginalTGSpace[i];
+01696                 }
+01697         }
+01698 
+01699         // cleared
+01700         _OriginalSkinRestored= true;
+01701 }
+
+

+ + + + +
+ + + + + + + + + + +
void NL3D::CMeshGeom::serial NLMISC::IStream f  )  throw (NLMISC::EStream) [virtual]
+
+ + + + + +
+   + + +

+serial this mesh. +

+ +

+Implements NLMISC::IStreamable. +

+Definition at line 948 of file mesh.cpp. +

+References nlassert, and sint. +

+

00949 {
+00950         /*
+00951         Version 4:
+00952                 - BonesName.
+00953         Version 3:
+00954                 - MeshVertexProgram.
+00955         Version 2:
+00956                 - precompute of triangle order. (nothing more to load).
+00957         Version 1:
+00958                 - added blend shapes
+00959         Version 0:
+00960                 - separate serialisation CMesh / CMeshGeom.
+00961         */
+00962         sint ver = f.serialVersion (4);
+00963 
+00964 
+00965         // must have good original Skinned Vertex before writing.
+00966         if( !f.isReading() && _Skinned && !_OriginalSkinRestored )
+00967         {
+00968                 restoreOriginalSkinVertices();
+00969         }
+00970 
+00971 
+00972         // Version 4+: Array of bone name
+00973         if (ver >= 4)
+00974         {
+00975                 f.serialCont (_BonesName);
+00976         }
+00977 
+00978         if (f.isReading())
+00979         {
+00980                 // Version3-: Bones index are in skeleton model id list
+00981                 _BoneIdComputed = (ver < 4);
+00982                 // In all case, must recompute usage of parents.
+00983                 _BoneIdExtended= false;
+00984         }
+00985         else
+00986         {
+00987                 // Warning, if you have skinned this shape, you can't write it anymore because skinning id have been changed! 
+00988                 nlassert (_BoneIdComputed==false);
+00989         }
+00990 
+00991         // Version3+: MeshVertexProgram.
+00992         if (ver >= 3)
+00993         {
+00994                 IMeshVertexProgram      *mvp= NULL;
+00995                 if(f.isReading())
+00996                 {
+00997                         f.serialPolyPtr(mvp);
+00998                         _MeshVertexProgram= mvp;
+00999                 }
+01000                 else
+01001                 {
+01002                         mvp= _MeshVertexProgram;
+01003                         f.serialPolyPtr(mvp);
+01004                 }
+01005         }
+01006         else if(f.isReading())
+01007         {
+01008                 // release vp
+01009                 _MeshVertexProgram= NULL;
+01010         }
+01011 
+01012         // TestYoyo
+01013         //_MeshVertexProgram= NULL;
+01014 
+01015         // Version1+: _MeshMorpher.
+01016         if (ver >= 1)
+01017                 f.serial (*_MeshMorpher);
+01018 
+01019         // serial geometry.
+01020         f.serial (_VBuffer);
+01021         f.serialCont (_MatrixBlocks);
+01022         f.serial (_BBox);
+01023         f.serial (_Skinned);
+01024 
+01025 
+01026         // If _VertexBuffer changed, flag the VertexBufferHard.
+01027         if(f.isReading())
+01028         {
+01029                 _VertexBufferHardDirty = true;
+01030 
+01031                 // if >= version 2, reorder of triangles is precomputed, else compute it now.
+01032                 if(ver < 2 )
+01033                 {
+01034                         optimizeTriangleOrder();
+01035                 }
+01036         }
+01037 
+01038         // Skinning: If Version < 4, _BonesName are not present, must compute _BonesId from localId
+01039         // Else it is computed at first computeBonesId().
+01040         if(ver < 4)
+01041                 buildBoneUsageVer3();
+01042 
+01043         // TestYoyo
+01044         //_MeshVertexProgram= NULL;
+01045         /*{
+01046                 uint numTris= 0;
+01047                 for(uint i=0;i<_MatrixBlocks.size();i++)
+01048                 {
+01049                         for(uint j=0;j<_MatrixBlocks[i].RdrPass.size();j++)
+01050                                 numTris+= _MatrixBlocks[i].RdrPass[j].PBlock.getNumTri();
+01051                 }
+01052                 nlinfo("YOYO: %d Vertices. %d Triangles.", _VBuffer.getNumVertices(), numTris);
+01053         }*/
+01054 
+01055         // Some runtime not serialized compilation
+01056         if(f.isReading())
+01057                 compileRunTime();
+01058 }
+
+

+ + + + +
+ + + + + + + + + + +
void NL3D::CMeshGeom::setBlendShapes std::vector< CBlendShape > &  bs  ) 
+
+ + + + + +
+   + + +

+ +

+Definition at line 449 of file mesh.cpp. +

+References _MeshMorpher, NL3D::CMeshMorpher::BlendShapes, and compileRunTime(). +

+Referenced by NL3D::CMesh::setBlendShapes(). +

+

00450 {
+00451         _MeshMorpher->BlendShapes = bs;
+00452         // must update some RunTime parameters
+00453         compileRunTime();
+00454 }
+
+

+ + + + +
+ + + + + + + + + +
bool NL3D::CMeshGeom::sortPerMaterial  )  const [virtual]
+
+ + + + + +
+   + + +

+true if the sort criterion must be by material. Else, sort per instance. +

+Implements NL3D::IMeshGeom. +

+Definition at line 2006 of file mesh.cpp. +

+References _SupportMBRFlags, and MBRSortPerMaterial. +

+

02007 {
+02008         return (_SupportMBRFlags & MBRSortPerMaterial)!=0;
+02009 }
+
+

+ + + + +
+ + + + + + + + + +
bool NL3D::CMeshGeom::supportMeshBlockRendering  )  const [virtual]
+
+ + + + + +
+   + + +

+true if this meshGeom support meshBlock rendering. return false if skinned/meshMorphed. +

+Implements NL3D::IMeshGeom. +

+Definition at line 2000 of file mesh.cpp. +

+References _SupportMBRFlags. +

+Referenced by profileSceneRender(), and NL3D::CMesh::supportMeshBlockRendering(). +

+

02001 {
+02002         return _SupportMBRFlags!=0;
+02003 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void NL3D::CMeshGeom::updateSkeletonUsage CSkeletonModel sm,
bool  increment
+
+ + + + + +
+   + + +

+update Skeleton Usage. increment or decrement. computeBonesId must has been called before. +

+ +

+Definition at line 1596 of file mesh.cpp. +

+References _BonesIdExt, NL3D::CSkeletonModel::Bones, NL3D::CSkeletonModel::decBoneUsage(), NL3D::CSkeletonModel::incBoneUsage(), nlerror, and uint. +

+Referenced by NL3D::CMesh::updateSkeletonUsage(). +

+

01597 {
+01598         // For all Bones used by this mesh.
+01599         for(uint i=0; i<_BonesIdExt.size();i++)
+01600         {
+01601                 uint    boneId= _BonesIdExt[i];
+01602                 // Some explicit Error.
+01603                 if(boneId>=sm->Bones.size())
+01604                         nlerror(" Skin is incompatible with Skeleton: tries to use bone %d", boneId);
+01605                 // increment or decrement not Forced, because CMeshGeom use getActiveBoneSkinMatrix().
+01606                 if(increment)
+01607                         sm->incBoneUsage(boneId, CSkeletonModel::UsageNormal);
+01608                 else
+01609                         sm->decBoneUsage(boneId, CSkeletonModel::UsageNormal);
+01610         }
+01611 }
+
+

+ + + + +
+ + + + + + + + + + +
void NL3D::CMeshGeom::updateVertexBufferHard IDriver drv  )  [private]
+
+ + + + + +
+   + + +

+update the VertexBufferHard if NULL (ie not created or deleted by driver) or if VertexBufferDirty. +

+ +

+Definition at line 523 of file mesh.cpp. +

+References _MeshMorpher, _Skinned, _VertexBufferHard, _VertexBufferHardDirty, NL3D::CMeshMorpher::BlendShapes, NL3D::CVertexBuffer::getNumVertices(), NL3D::CVertexBuffer::getUVRouting(), NL3D::CVertexBuffer::getValueTypePointer(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexFormat(), NL3D::CVertexBuffer::getVertexSize(), nlassert, NL3D::IDriver::slowUnlockVertexBufferHard(), and NL3D::IDriver::supportVertexBufferHard(). +

+Referenced by beginMesh(), render(), and renderSkin(). +

+

00524 {
+00525         if(!drv->supportVertexBufferHard())
+00526                 return;
+00527 
+00528 
+00529         /* If the mesh is skinned, still use normal CVertexBuffer.
+00530          * \todo yoyo: optimize. not done now because CMesh Skinned are not so used in game, 
+00531          *      and CMesh skinning is far not optimized (4 matrix mul all the time). Should use later the renderSkinGroupGeom()
+00532          *      scheme
+00533          *      Also, if the driver has slow VBhard unlock()  (ie ATI gl extension), avoid use of them if MeshMorpher 
+00534          *      is used.
+00535          */
+00536         bool    avoidVBHard;
+00537         avoidVBHard= _Skinned || ( _MeshMorpher && _MeshMorpher->BlendShapes.size()>0 && drv->slowUnlockVertexBufferHard() );
+00538         if( _VertexBufferHardDirty && avoidVBHard )
+00539         {
+00540                 // delete possible old VBHard.
+00541                 if(_VertexBufferHard!=NULL)
+00542                 {
+00543                         // VertexBufferHard lifetime < Driver lifetime.
+00544                         nlassert(_Driver!=NULL);
+00545                         _Driver->deleteVertexBufferHard(_VertexBufferHard);
+00546                 }
+00547                 return;
+00548         }
+00549 
+00550         // If the vbufferhard is not synced to the vbuffer.
+00551         if(_VertexBufferHardDirty || _VertexBufferHard==NULL)
+00552         {
+00553                 _VertexBufferHardDirty= false;
+00554 
+00555                 // delete possible old VBHard.
+00556                 if(_VertexBufferHard!=NULL)
+00557                 {
+00558                         // VertexBufferHard lifetime < Driver lifetime.
+00559                         nlassert(_Driver!=NULL);
+00560                         _Driver->deleteVertexBufferHard(_VertexBufferHard);
+00561                 }
+00562 
+00563                 // bkup drv in a refptr. (so we know if the vbuffer hard has to be deleted).
+00564                 _Driver= drv;
+00565                 // try to create new one, in AGP Ram
+00566                 _VertexBufferHard= _Driver->createVertexBufferHard(_VBuffer.getVertexFormat(), _VBuffer.getValueTypePointer (), _VBuffer.getNumVertices(), IDriver::VBHardAGP, _VBuffer.getUVRouting());
+00567 
+00568                 // If KO, use normal VertexBuffer.
+00569                 if(_VertexBufferHard==NULL)
+00570                         return;
+00571                 // else, setup and Fill it with VertexBuffer.
+00572                 else
+00573                 {
+00574                         // If the mesh is static: not skinned/no meshMorpher, then setup a static VBHard -> runs faster under NVidia
+00575                         if( !_Skinned && ( !_MeshMorpher || _MeshMorpher->BlendShapes.size()==0) )
+00576                                 _VertexBufferHard->lockHintStatic(true);
+00577 
+00578 
+00579                         // Fill VB
+00580                         void    *vertexPtr= _VertexBufferHard->lock();
+00581 
+00582                         nlassert(_VBuffer.getVertexFormat() == _VertexBufferHard->getVertexFormat());
+00583                         nlassert(_VBuffer.getNumVertices() == _VertexBufferHard->getNumVertices());
+00584                         nlassert(_VBuffer.getVertexSize() == _VertexBufferHard->getVertexSize());
+00585 
+00586                         // \todo yoyo: TODO_DX8 and DX8 ???
+00587                         // Because same internal format, just copy all block.
+00588                         memcpy(vertexPtr, _VBuffer.getVertexCoordPointer(), _VBuffer.getNumVertices() * _VBuffer.getVertexSize() );
+00589 
+00590                         _VertexBufferHard->unlock();
+00591                 }
+00592 
+00593         }
+00594 }
+
+


Field Documentation

+

+ + + + +
+ + +
NLMISC::CAABBoxExt NL3D::CMeshGeom::_BBox [private] +
+
+ + + + + +
+   + + +

+For clipping. +

+ +

+Definition at line 662 of file mesh.h.

+

+ + + + +
+ + +
bool NL3D::CMeshGeom::_BoneIdComputed [private] +
+
+ + + + + +
+   + + +

+This boolean is true if the bones id have been passed in the skeleton. +

+ +

+Definition at line 669 of file mesh.h. +

+Referenced by build(), CMeshGeom(), and computeBonesId().

+

+ + + + +
+ + +
bool NL3D::CMeshGeom::_BoneIdExtended [private] +
+
+ + + + + +
+   + + +

+true if the _BonesIdExt have been computed (for bone Usage). +

+ +

+Definition at line 671 of file mesh.h. +

+Referenced by build(), CMeshGeom(), and computeBonesId().

+

+ + + + +
+ + +
std::vector<sint32> NL3D::CMeshGeom::_BonesId [private] +
+
+ + + + + +
+   + + +

+This array give the index in the skeleton of the local bones used. computed at first computeBoneId(). +

+ +

+Definition at line 676 of file mesh.h. +

+Referenced by buildBoneUsageVer3(), computeBonesId(), and getSkinBoneUsage().

+

+ + + + +
+ + +
std::vector<sint32> NL3D::CMeshGeom::_BonesIdExt [private] +
+
+ + + + + +
+   + + +

+Same as _BonesId but with parent of bones added. (used for bone usage). +

+ +

+Definition at line 678 of file mesh.h. +

+Referenced by computeBonesId(), and updateSkeletonUsage().

+

+ + + + +
+ + +
std::vector<std::string> NL3D::CMeshGeom::_BonesName [private] +
+
+ + + + + +
+   + + +

+This array give the name of the local bones used. +

+ +

+Definition at line 674 of file mesh.h. +

+Referenced by build(), and computeBonesId().

+

+ + + + +
+ + +
CRefPtr<IDriver> NL3D::CMeshGeom::_Driver [private] +
+
+ + + + + +
+   + + +

+This is the driver used to setup the vbuffer hard. error if a mesh has not the same driver in his life. +

+ +

+Definition at line 686 of file mesh.h.

+

+ + + + +
+ + +
std::vector<CMatrixBlock> NL3D::CMeshGeom::_MatrixBlocks [private] +
+
+ + + + + +
+   + + +

+The matrix blocks. +

+ +

+Definition at line 660 of file mesh.h. +

+Referenced by applyMaterialRemap(), applySkin(), build(), buildBoneUsageVer3(), buildSkin(), compileRunTime(), computeBonesId(), computeMeshVBHeap(), getNbMatrixBlock(), getNbRdrPass(), getNumRdrPassesForInstance(), getNumRdrPassesForMesh(), getNumTriangles(), getRdrPassMaterial(), getRdrPassPrimitiveBlock(), optimizeTriangleOrder(), profileSceneRender(), render(), renderPass(), renderSimpleWithMaterial(), and renderSkin().

+

+ + + + +
+ + +
CMeshMorpher* NL3D::CMeshGeom::_MeshMorpher [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 712 of file mesh.h. +

+Referenced by build(), CMeshGeom(), compileRunTime(), getNbBlendShapes(), render(), renderSkin(), setBlendShapes(), updateVertexBufferHard(), and ~CMeshGeom().

+

+ + + + +
+ + +
NLMISC::CSmartPtr<IMeshVertexProgram> NL3D::CMeshGeom::_MeshVertexProgram [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 716 of file mesh.h. +

+Referenced by activeInstance(), beginMesh(), bkupOriginalSkinVertices(), build(), compileRunTime(), endMesh(), getVBHeapInfo(), hasMeshVertexProgram(), initInstance(), render(), renderSkin(), and restoreOriginalSkinVertices().

+

+ + + + +
+ + +
std::vector<CVector> NL3D::CMeshGeom::_OriginalSkinNormals [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 652 of file mesh.h. +

+Referenced by applySkin(), bkupOriginalSkinVertices(), render(), renderSkin(), and restoreOriginalSkinVertices().

+

+ + + + +
+ + +
bool NL3D::CMeshGeom::_OriginalSkinRestored [private] +
+
+ + + + + +
+   + + +

+This tells if the mesh VBuffer has coorect BindPos vertices. +

+ +

+Definition at line 666 of file mesh.h. +

+Referenced by applySkin(), CMeshGeom(), render(), and restoreOriginalSkinVertices().

+

+ + + + +
+ + +
std::vector<CVector> NL3D::CMeshGeom::_OriginalSkinVertices [private] +
+
+ + + + + +
+   + + +

+Skinning: this is the list of vertices (mirror of VBuffer), at the bind Pos. Potentially modified by the mesh morpher +

+Definition at line 651 of file mesh.h. +

+Referenced by applySkin(), bkupOriginalSkinVertices(), render(), renderSkin(), and restoreOriginalSkinVertices().

+

+ + + + +
+ + +
std::vector<CVector> NL3D::CMeshGeom::_OriginalTGSpace [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 653 of file mesh.h. +

+Referenced by applySkin(), bkupOriginalSkinVertices(), render(), renderSkin(), and restoreOriginalSkinVertices().

+

+ + + + +
+ + +
bool NL3D::CMeshGeom::_PreciseClipping [private] +
+
+ + + + + +
+   + + +

+Estimate if we must do a Precise clipping (ie with bboxes). +

+ +

+Definition at line 709 of file mesh.h. +

+Referenced by clip(), CMeshGeom(), and compileRunTime().

+

+ + + + +
+ + +
bool NL3D::CMeshGeom::_Skinned [private] +
+
+ + + + + +
+   + + +

+This tells if the mesh is correctly skinned. +

+ +

+Definition at line 664 of file mesh.h. +

+Referenced by bkupOriginalSkinVertices(), build(), buildBoneUsageVer3(), CMeshGeom(), compileRunTime(), isSkinned(), render(), renderSkin(), restoreOriginalSkinVertices(), and updateVertexBufferHard().

+

+ + + + +
+ + +
uint8 NL3D::CMeshGeom::_SupportMBRFlags [private] +
+
+ + + + + +
+   + + +

+setuped at compileRunTime. +

+ +

+Definition at line 705 of file mesh.h. +

+Referenced by activeInstance(), beginMesh(), compileRunTime(), endMesh(), getVBHeapInfo(), renderPass(), sortPerMaterial(), and supportMeshBlockRendering().

+

+ + + + +
+ + +
CVertexBuffer NL3D::CMeshGeom::_VBuffer [private] +
+
+ + + + + +
+   + + +

+VBuffer of the mesh (potentially modified by the mesh morpher and skinning). +

+ +

+Definition at line 656 of file mesh.h.

+

+ + + + +
+ + +
CVertexBuffer NL3D::CMeshGeom::_VBufferOri [private] +
+
+ + + + + +
+   + + +

+The original VBuffer of the mesh used only if there are blend shapes. +

+ +

+Definition at line 658 of file mesh.h. +

+Referenced by render(), and renderSkin().

+

+ + + + +
+ + +
CRefPtr<IVertexBufferHard> NL3D::CMeshGeom::_VertexBufferHard [private] +
+
+ + + + + +
+   + + +

+The only one VBufferHard of the mesh. NULL by default. +

+ +

+Definition at line 684 of file mesh.h. +

+Referenced by beginMesh(), profileSceneRender(), render(), renderSkin(), updateVertexBufferHard(), and ~CMeshGeom().

+

+ + + + +
+ + +
bool NL3D::CMeshGeom::_VertexBufferHardDirty [private] +
+
+ + + + + +
+   + + +

+This tells if the VBuffer has changed since the last time or not. +

+ +

+Definition at line 688 of file mesh.h. +

+Referenced by build(), CMeshGeom(), and updateVertexBufferHard().

+


The documentation for this class was generated from the following files: +
Generated on Tue Mar 16 06:52:03 2004 for NeL by + +doxygen +1.3.6
+ + -- cgit v1.2.1