#include <mesh.h>
Inheritance diagram for NL3D::CMeshGeom:
Nevrax France
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::CAABBoxExt & | getBoundingBox () 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 CPrimitiveBlock & | getRdrPassPrimitiveBlock (uint matrixBlockIndex, uint renderingPassIndex) const |
const CVertexBuffer & | getVertexBuffer () const |
get the vertex buffer used by the mesh | |
Private Types | |
typedef TBoneMap::iterator | ItBoneMap |
typedef TCornerSet::iterator | ItCornerSet |
typedef std::map< uint, CBoneTmp > | TBoneMap |
typedef std::set< CCornerTmp *, CCornerPred > | TCornerSet |
Private Member Functions | |
void | compileRunTime () |
void | findVBId (TCornerSet &corners, const CCornerTmp *corn, sint ¤tVBIndex, 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. |
|
Definition at line 606 of file mesh.h. Referenced by buildSkin(). |
|
Definition at line 730 of file mesh.h. Referenced by findVBId(). |
|
Just for build process. A map of Bone. Definition at line 605 of file mesh.h. Referenced by buildSkin(). |
|
Definition at line 729 of file mesh.h. Referenced by build(), and findVBId(). |
|
setuped at compileRunTime.
Definition at line 698 of file mesh.h.
00699 { 00700 MBROk= 1, 00701 MBRSortPerMaterial= 2, 00702 MBRCurrentUseVP= 4, 00703 }; |
|
Render Flags, used in render.
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 }; |
|
Definition at line 799 of file mesh.h. Referenced by applySkin().
00799 {SkinPosOnly=0, SkinWithNormal, SkinWithTgSpace}; |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
When the framework succes to allocate a VBHeap space, it call this method to fill this space and compute shifted 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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
Implemented in NLAIAGENT::CNumericIndex, NLAIC::IPointerGestion, NLAIC::CIdentType, and CAutomataDesc. Referenced by NLMISC::CClassRegistry::checkObject(), and NL3D::GetTextureSize(). |
|
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(); } |
|
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() ; } |
|
get the number of rendering pass for a given matrix block
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() ; } |
|
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 } |
|
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 } |
|
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 } |
|
get the material ID associated with a rendering pass of a 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 } |
|
get the primitive block associated with a rendering pass of a 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 } |
|
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;} |
|
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 } |
|
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 ; } |
|
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;} |
|
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 } |
|
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;} |
|
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;}
|
|
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 } |
|
clip this mesh
|
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
render the mesh geometry with a single material. Render is said "Simple" because no special features are used:
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
For clipping.
|
|
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(). |
|
true if the _BonesIdExt have been computed (for bone Usage).
Definition at line 671 of file mesh.h. Referenced by build(), CMeshGeom(), and computeBonesId(). |
|
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(). |
|
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(). |
|
This array give the name of the local bones used.
Definition at line 674 of file mesh.h. Referenced by build(), and computeBonesId(). |
|
This is the driver used to setup the vbuffer hard. error if a mesh has not the same driver in his life.
|
|
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(). |
|
Definition at line 712 of file mesh.h. Referenced by build(), CMeshGeom(), compileRunTime(), getNbBlendShapes(), render(), renderSkin(), setBlendShapes(), updateVertexBufferHard(), and ~CMeshGeom(). |
|
Definition at line 716 of file mesh.h. Referenced by activeInstance(), beginMesh(), bkupOriginalSkinVertices(), build(), compileRunTime(), endMesh(), getVBHeapInfo(), hasMeshVertexProgram(), initInstance(), render(), renderSkin(), and restoreOriginalSkinVertices(). |
|
Definition at line 652 of file mesh.h. Referenced by applySkin(), bkupOriginalSkinVertices(), render(), renderSkin(), and restoreOriginalSkinVertices(). |
|
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(). |
|
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(). |
|
Definition at line 653 of file mesh.h. Referenced by applySkin(), bkupOriginalSkinVertices(), render(), renderSkin(), and restoreOriginalSkinVertices(). |
|
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(). |
|
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(). |
|
setuped at compileRunTime.
Definition at line 705 of file mesh.h. Referenced by activeInstance(), beginMesh(), compileRunTime(), endMesh(), getVBHeapInfo(), renderPass(), sortPerMaterial(), and supportMeshBlockRendering(). |
|
VBuffer of the mesh (potentially modified by the mesh morpher and skinning).
|
|
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(). |
|
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(). |
|
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(). |