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