#include <mesh_mrm.h>
Inheritance diagram for NL3D::CMeshMRMGeom:

To build a CMeshMRMGeom, you should:
NB: internally, build() use CMRMBuilder, a builder of MRM.
Nevrax France
Definition at line 81 of file mesh_mrm.h.
RawSkin optimisation. | |
| uint | NumCacheVertexNormal1 = NL_BlockByteL1 / sizeof(CRawVertexNormalSkin1) |
| uint | NumCacheVertexNormal2 = NL_BlockByteL1 / sizeof(CRawVertexNormalSkin2) |
| uint | NumCacheVertexNormal3 = NL_BlockByteL1 / sizeof(CRawVertexNormalSkin3) |
| uint | NumCacheVertexNormal4 = NL_BlockByteL1 / sizeof(CRawVertexNormalSkin4) |
| uint | NumCacheVertexShadow = NL_BlockByteL1 / sizeof(CMeshMRMGeom::CShadowVertex) |
| void | applyArrayRawSkinNormal1 (CRawVertexNormalSkin1 *src, uint8 *destVertexPtr, CMatrix3x4 *boneMat3x4, uint nInf) |
| void | applyArrayRawSkinNormal2 (CRawVertexNormalSkin2 *src, uint8 *destVertexPtr, CMatrix3x4 *boneMat3x4, uint nInf) |
| void | applyArrayRawSkinNormal3 (CRawVertexNormalSkin3 *src, uint8 *destVertexPtr, CMatrix3x4 *boneMat3x4, uint nInf) |
| void | applyArrayRawSkinNormal4 (CRawVertexNormalSkin4 *src, uint8 *destVertexPtr, CMatrix3x4 *boneMat3x4, uint nInf) |
| void | dirtMeshDataId () |
| Increment the refCount, so instances RawSkins are no longer valid. | |
| void | updateRawSkinNormal (bool enabled, CMeshMRMInstance *mi, sint curLodId) |
| compute RawSkin info in the MRMInstance according to current skin setup. | |
| uint | _MeshDataId |
| Each time the mesh is loaded/built, this increment. | |
ShadowMap Skin rendering | |
| void | applyArrayShadowSkin (CShadowVertex *src, CVector *dst, CSkeletonModel *skeleton, uint numVerts) |
| std::vector< uint32 > | _ShadowSkinTriangles |
| std::vector< CShadowVertex > | _ShadowSkinVertices |
| bool | _SupportShadowSkinGrouping |
Hard VB | |
| void | deleteVertexBufferHard () |
| void | fillAGPSkinPartWithVBHardPtr (CLod &lod, uint8 *vertexDst) |
| void | updateVertexBufferHard (IDriver *drv, uint32 numVertices) |
| CRefPtr< IDriver > | _Driver |
| bool | _PreciseClipping |
| NB: HERE FOR PACKING ONLY. For clipping. Estimate if we must do a Precise clipping (ie with bboxes). | |
| CRefPtr< IVertexBufferHard > | _VBHard |
| bool | _VertexBufferHardDirty |
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 &m, std::vector< CMesh::CMeshBuild * > &bsList, uint numMaxMaterial, const CMRMParameters ¶ms=CMRMParameters()) |
| void | changeMRMDistanceSetup (float distanceFinest, float distanceMiddle, float distanceCoarsest) |
| CMeshMRMGeom () | |
| Constructor. | |
| virtual std::string | getClassName ()=0 |
| const CMRMLevelDetail & | getLevelDetail () const |
| get the MRM level detail information | |
| virtual bool | hasMeshVertexProgram () const |
| True if this mesh has a vertexProgram. | |
| ~CMeshMRMGeom () | |
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 bool | isActiveInstanceNeedVBFill () const |
| 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 in a driver. true if visible. | |
| virtual float | getNumTriangles (float distance) |
| get an approximation of the number of triangles this instance will render for a fixed distance. | |
| virtual void | initInstance (CMeshBaseInstance *mbi) |
| Init instance info. | |
| NLMISC_DECLARE_CLASS (CMeshMRMGeom) | |
| clip this mesh in a driver. true if visible. | |
| void | profileSceneRender (CRenderTrav *rdrTrav, CTransformShape *trans, float polygonCount, uint32 rdrFlags) |
| Scene profile. | |
| virtual void | render (IDriver *drv, CTransformShape *trans, float polygonCount, uint32 rdrFlags, float globalAlpha) |
| render() this mesh in a driver, given an instance and his materials. | |
| virtual void | renderSkin (CTransformShape *trans, float alphaMRM) |
| render() this mesh as a skin | |
| virtual void | serial (NLMISC::IStream &f) throw (NLMISC::EStream) |
| serial this meshGeom. | |
Skinning Behavior | |
| void | computeBonesId (CSkeletonModel *skeleton) |
| Compute skinning id. | |
| const std::vector< NLMISC::CBSphere > & | getSkinBoneSphere () const |
| see CTransform::getSkinBoneSphere() doc for the meaning of this value. computeBonesId must has been called before. | |
| 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 std::vector< std::string > & | getBonesName () const |
| get the bone names of the meshMRM. | |
| const NLMISC::CAABBoxExt & | getBoundingBox () const |
| get the extended axis aligned bounding box of the mesh | |
| const std::vector< CMRMWedgeGeom > & | getGeomorphs (uint lodId) const |
| Advanced. get the geomorphs for a special lod. | |
| uint | getNbBlendShapes () const |
| get the number of BlendShapes | |
| uint | getNbLod () const |
| uint | getNbRdrPass (uint lodId) const |
| uint32 | getRdrPassMaterial (uint lodId, uint renderingPassIndex) const |
| const CPrimitiveBlock & | getRdrPassPrimitiveBlock (uint lodId, uint renderingPassIndex) const |
| const std::vector< CMesh::CSkinWeight > & | getSkinWeights () const |
| get the skinWeights used by the mrm mesh. NB: same size of the vertexBuffer. empty if !isSkinned() | |
| const CVertexBuffer & | getVertexBuffer () const |
| get the vertex buffer used by the mrm mesh. NB: this VB store all Vertices used by All LODs. | |
Lod management. | |
| uint | getNbLodLoaded () const |
| void | loadFirstLod (NLMISC::IStream &f) |
| void | loadNextLod (NLMISC::IStream &f) |
| void | unloadNextLod (NLMISC::IStream &f) |
ShadowMap Skin rendering | |
| uint | getNumShadowSkinVertices () const |
| Get the num of shadow skin vertices. | |
| sint | renderShadowSkinGeom (CMeshMRMInstance *mi, uint remainingVertices, uint8 *vbDest) |
| Get the num of shadow skin vertices. | |
| void | renderShadowSkinPrimitives (CMeshMRMInstance *mi, CMaterial &castMat, IDriver *drv, uint baseVertex) |
| Get the num of shadow skin vertices. | |
| void | setShadowMesh (const std::vector< CShadowVertex > &shadowVertices, const std::vector< uint32 > &triangles) |
| Setup the ShadowMesh. | |
| bool | supportShadowSkinGrouping () const |
| Render the ShadowSkin (SkinGroup like). | |
Special SkinGrouping Rendering | |
| sint | renderSkinGroupGeom (CMeshMRMInstance *mi, float alphaMRM, uint remainingVertices, uint8 *vbDest) |
| void | renderSkinGroupPrimitives (CMeshMRMInstance *mi, uint baseVertex, std::vector< CSkinSpecularRdrPass > &specularRdrPasses, uint skinIndex) |
| void | renderSkinGroupSpecularRdrPass (CMeshMRMInstance *mi, uint rdrPassId) |
| bool | supportSkinGrouping () const |
Private Member Functions | |
| void | applyGeomorph (std::vector< CMRMWedgeGeom > &geoms, float alphaLod, IVertexBufferHard *currentVBHard) |
| Apply the geomorph to the _VBuffer, or the VBhard, if exist/used. | |
| void | applyGeomorphPosNormalUV0 (std::vector< CMRMWedgeGeom > &geoms, uint8 *vertexPtr, uint8 *vertexDestPtr, sint32 vertexSize, float a, float a1) |
| Faster, but common geomorph apply. | |
| void | applyGeomorphWithVBHardPtr (std::vector< CMRMWedgeGeom > &geoms, float alphaLod, uint8 *vertexDestPtr) |
| Apply the geomorph to the VBhard ptr, if not NULL. | |
| void | applyRawSkinWithNormal (CLod &lod, CRawSkinNormalCache &rawSkinLod, const CSkeletonModel *skeleton, uint8 *vbHard, float alphaLod) |
| void | applySkin (CLod &lod, const CSkeletonModel *skeleton) |
| Skinning: Apply skinning to the _VBuffer (before geomorph). | |
| void | applySkinWithNormal (CLod &lod, const CSkeletonModel *skeleton) |
| void | applySkinWithTangentSpace (CLod &lod, const CSkeletonModel *skeleton, uint tangentSpaceTexCoord) |
| void | bkupOriginalSkinVertices () |
| Skinning: bkup Vertex/Normal into _OriginalSkin* from VBuffer. | |
| void | bkupOriginalSkinVerticesSubset (uint wedgeStart, uint wedgeEnd) |
| void | buildBoneUsageVer2 () |
| sint | chooseLod (float alphaMRM, float &alphaLod) |
| choose the lod according to the alphaMRM [0,1] given. | |
| void | compileRunTime () |
| void | load (NLMISC::IStream &f) throw (NLMISC::EStream) |
| load this mesh. | |
| sint | loadHeader (NLMISC::IStream &f) throw (NLMISC::EStream) |
| load the header of this mesh. return the version of the header. | |
| void | restoreOriginalSkinPart (CLod &lod, IVertexBufferHard *currentVBHard) |
| Skinning: same as restoreOriginalSkinVertices(), but for one Lod only. | |
| void | restoreOriginalSkinVertices () |
| Skinning: restore Vertex/Normal from _OriginalSkin* to VBuffer. | |
| void | save (NLMISC::IStream &f) throw (NLMISC::EStream) |
| save the entire mesh. | |
| void | serialLodVertexData (NLMISC::IStream &f, uint startWedge, uint endWedge) |
| serial a subset of the vertices. | |
| void | updateShiftedTriangleCache (CMeshMRMInstance *mi, sint curLodId, uint baseVertex) |
Private Attributes | |
| NLMISC::CAABBoxExt | _BBox |
| For clipping. this is the BB of all vertices of all Lods. | |
| 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. | |
| std::vector< NLMISC::CBSphere > | _BonesSphere |
| see CTransform::getSkinBoneSphere() doc for the meaning of this value | |
| uint8 | _LastLodComputed |
| Last lod rendered. used with renderSkinGroup*() only. | |
| std::vector< CLodInfo > | _LodInfos |
| Info for pre-loading Lods. | |
| std::vector< CLod > | _Lods |
| List of Lods. | |
| CMeshMorpher | _MeshMorpher |
| NLMISC::CSmartPtr< IMeshVertexProgram > | _MeshVertexProgram |
| uint | _NbLodLoaded |
| std::vector< CVector > | _OriginalSkinNormals |
| std::vector< CVector > | _OriginalSkinVertices |
| Skinning: this is the list of vertices (mirror of VBuffer), at the bind Pos. | |
| std::vector< CVector > | _OriginalTGSpace |
| bool | _Skinned |
| Skinning: This tells if the mesh is correctly skinned (suuport skinning). | |
| std::vector< CMesh::CSkinWeight > | _SkinWeights |
| This is the array of SkinWeights, same size as the VB. | |
| bool | _SupportSkinGrouping |
| if true, then maybe use faster render | |
| CVertexBuffer | _VBufferFinal |
| The Final VBuffer. | |
| CVertexBuffer | _VBufferOriginal |
| The Original VBuffer. | |
| CMRMLevelDetail | _LevelDetail |
Mesh Block Render Implementation | |
| bool | _MBRBkupNormalize |
| BeginMesh setup. | |
| sint | _MBRCurrentLodId |
| global setup at activateInstance() | |
| bool | _SupportMeshBlockRendering |
| setuped at compileRunTime. | |
Friends | |
| class | CMRMBuilder |
Structures for building a MRM mesh. | |
| class | CLod |
|
|
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 };
|
|
|
Constructor.
Definition at line 204 of file mesh_mrm.cpp. References _MBRCurrentLodId, _MeshDataId, _NbLodLoaded, _SupportMeshBlockRendering, _SupportShadowSkinGrouping, and _SupportSkinGrouping.
00205 {
00206 _VertexBufferHardDirty= true;
00207 _Skinned= false;
00208 _NbLodLoaded= 0;
00209 _BoneIdComputed = false;
00210 _BoneIdExtended = false;
00211 _PreciseClipping= false;
00212 _SupportSkinGrouping= false;
00213 _MeshDataId= 0;
00214 _SupportMeshBlockRendering= false;
00215 _MBRCurrentLodId= 0;
00216 _SupportShadowSkinGrouping= false;
00217 }
|
|
|
Definition at line 221 of file mesh_mrm.cpp. References deleteVertexBufferHard().
00222 {
00223 deleteVertexBufferHard();
00224 }
|
|
||||||||||||||||||||
|
The framework call this method any time a change of instance occurs. Implements NL3D::IMeshGeom. Definition at line 2738 of file mesh_mrm.cpp. References _LevelDetail, _Lods, _MBRCurrentLodId, applyGeomorph(), applyGeomorphWithVBHardPtr(), NL3D::CTransformShape::changeLightSetup(), chooseLod(), NL3D::CMeshGeomRenderContext::Driver, NL3D::CMRMLevelDetail::getLevelDetailFromPolyCount(), NL3D::CTransform::getWorldMatrix(), H_AUTO, NL3D::CMeshGeomRenderContext::RenderThroughVBHeap, NL3D::CMeshGeomRenderContext::RenderTrav, NL3D::IDriver::setupModelMatrix(), and uint8.
02739 {
02740 H_AUTO( NL3D_MeshMRMGeom_RenderNormal );
02741
02742 if(_Lods.empty())
02743 return;
02744
02745 // get the result of the Load Balancing.
02746 float alphaMRM= _LevelDetail.getLevelDetailFromPolyCount(polygonCount);
02747
02748 // choose the lod.
02749 float alphaLod;
02750 _MBRCurrentLodId= chooseLod(alphaMRM, alphaLod);
02751
02752 // Geomorph the choosen Lod (if not the coarser mesh).
02753 if(_MBRCurrentLodId>0)
02754 {
02755 if(rdrCtx.RenderThroughVBHeap)
02756 applyGeomorphWithVBHardPtr(_Lods[_MBRCurrentLodId].Geomorphs, alphaLod, (uint8*)vbDst);
02757 else
02758 applyGeomorph(_Lods[_MBRCurrentLodId].Geomorphs, alphaLod, _VBHard);
02759 }
02760
02761 // set the instance worldmatrix.
02762 rdrCtx.Driver->setupModelMatrix(inst->getWorldMatrix());
02763
02764 // setupLighting.
02765 inst->changeLightSetup(rdrCtx.RenderTrav);
02766 }
|
|
||||||||||||||||||||
|
Definition at line 895 of file mesh_mrm_skin.cpp. |
|
||||||||||||||||||||
|
Definition at line 1074 of file mesh_mrm_skin.cpp. |
|
||||||||||||||||||||
|
Definition at line 1377 of file mesh_mrm_skin.cpp. |
|
||||||||||||||||||||
|
Definition at line 1771 of file mesh_mrm_skin.cpp. |
|
||||||||||||||||||||
|
Definition at line 339 of file mesh_mrm_skin.cpp. References _Lods, NL3D::computeBoneMatrixes3x4(), NL3D::CMeshMRMGeom::CLod::MatrixInfluences, min, NumCacheVertexShadow, src, and uint. Referenced by renderShadowSkinGeom().
00340 {
00341 // For all matrix this Mesh use. (the shadow geometry cannot use other Matrix than the mesh use).
00342 // NB: take the best lod since the lower lods cannot use other Matrix than the higher one.
00343 static vector<CMatrix3x4> boneMat3x4;
00344 CLod &lod= _Lods[_Lods.size()-1];
00345 computeBoneMatrixes3x4(boneMat3x4, lod.MatrixInfluences, skeleton);
00346
00347 // Then do the skin
00348 for(;numVerts>0;)
00349 {
00350 // number of vertices to process for this block.
00351 uint nBlockInf= min(NumCacheVertexShadow, numVerts);
00352 // next block.
00353 numVerts-= nBlockInf;
00354
00355 // cache the data in L1 cache.
00356 CFastMem::precache(src, nBlockInf * sizeof(CShadowVertex));
00357
00358 // for all InfluencedVertices only.
00359 for(;nBlockInf>0;nBlockInf--, src++, dst++)
00360 {
00361 boneMat3x4[ src->MatrixId ].mulSetPoint( src->Vertex, *dst );
00362 }
00363 }
00364 }
|
|
||||||||||||||||
|
Apply the geomorph to the _VBuffer, or the VBhard, if exist/used.
Definition at line 477 of file mesh_mrm.cpp. References _VBufferFinal, applyGeomorphWithVBHardPtr(), NL3D::IVertexBufferHard::getVertexSize(), NL3D::CVertexBuffer::getVertexSize(), NL3D::IVertexBufferHard::lock(), nlassert, uint8, and NL3D::IVertexBufferHard::unlock(). Referenced by activeInstance(), render(), and renderSkin().
00478 {
00479 if(currentVBHard!=NULL)
00480 {
00481 // must write into it
00482 uint8 *vertexDestPtr= (uint8*)currentVBHard->lock();
00483 nlassert(_VBufferFinal.getVertexSize() == currentVBHard->getVertexSize());
00484
00485 // apply the geomorph
00486 applyGeomorphWithVBHardPtr(geoms, alphaLod, vertexDestPtr);
00487
00488 // unlock. ATI: copy only geomorphed vertices.
00489 currentVBHard->unlock(0, geoms.size());
00490 }
00491 else
00492 applyGeomorphWithVBHardPtr(geoms, alphaLod, NULL);
00493
00494 }
|
|
||||||||||||||||||||||||||||
|
Faster, but common geomorph apply.
Definition at line 817 of file mesh_mrm.cpp. References NL3D::CMRMWedgeGeom::End, nlassert, sint32, NL3D::CMRMWedgeGeom::Start, uint, and uint8. Referenced by applyGeomorphWithVBHardPtr().
00818 {
00819 nlassert(vertexSize==32);
00820
00821
00822 // For all geomorphs.
00823 uint nGeoms= geoms.size();
00824 CMRMWedgeGeom *ptrGeom= &(geoms[0]);
00825 uint8 *destPtr= vertexDestPtr;
00826 for(; nGeoms>0; nGeoms--, ptrGeom++, destPtr+= vertexSize )
00827 {
00828 // Consider the Pos/Normal/UV as an array of 8 float to interpolate.
00829 float *start= (float*)(vertexPtr + (ptrGeom->Start<<5));
00830 float *end= (float*)(vertexPtr + (ptrGeom->End<<5));
00831 float *dst= (float*)(destPtr);
00832
00833 // unrolled
00834 dst[0]= start[0] * a + end[0]* a1;
00835 dst[1]= start[1] * a + end[1]* a1;
00836 dst[2]= start[2] * a + end[2]* a1;
00837 dst[3]= start[3] * a + end[3]* a1;
00838 dst[4]= start[4] * a + end[4]* a1;
00839 dst[5]= start[5] * a + end[5]* a1;
00840 dst[6]= start[6] * a + end[6]* a1;
00841 dst[7]= start[7] * a + end[7]* a1;
00842 }
00843 }
|
|
||||||||||||||||
|
Apply the geomorph to the VBhard ptr, if not NULL.
Definition at line 498 of file mesh_mrm.cpp. References _VBufferFinal, applyGeomorphPosNormalUV0(), NLMISC::CRGBA::blendFromui(), NLMISC::clamp(), NL3D::CMRMWedgeGeom::End, NL3D::CVertexBuffer::getColorOff(), NL3D::CVertexBuffer::getNormalOff(), NL3D::CVertexBuffer::getSpecularOff(), NL3D::CVertexBuffer::getTexCoordOff(), NL3D::CVertexBuffer::getValueType(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexFormat(), NL3D::CVertexBuffer::getVertexSize(), nlassert, sint32, NL3D::CMRMWedgeGeom::Start, uint, and uint8. Referenced by activeInstance(), and applyGeomorph().
00499 {
00500 // no geomorphs? quit.
00501 if(geoms.size()==0)
00502 return;
00503
00504 clamp(alphaLod, 0.f, 1.f);
00505 float a= alphaLod;
00506 float a1= 1 - alphaLod;
00507
00508
00509 // info from VBuffer.
00510 uint8 *vertexPtr= (uint8*)_VBufferFinal.getVertexCoordPointer();
00511 uint flags= _VBufferFinal.getVertexFormat();
00512 sint32 vertexSize= _VBufferFinal.getVertexSize();
00513 // because of the unrolled code for 4 first UV, must assert this.
00514 nlassert(CVertexBuffer::MaxStage>=4);
00515 // must have XYZ.
00516 nlassert(flags & CVertexBuffer::PositionFlag);
00517
00518
00519 // If VBuffer Hard disabled
00520 if(vertexDestPtr==NULL)
00521 {
00522 // write into vertexPtr.
00523 vertexDestPtr= vertexPtr;
00524 }
00525
00526
00527 // if it is a common format
00528 if( flags== (CVertexBuffer::PositionFlag | CVertexBuffer::NormalFlag | CVertexBuffer::TexCoord0Flag) &&
00529 _VBufferFinal.getValueType(CVertexBuffer::TexCoord0) == CVertexBuffer::Float2 )
00530 {
00531 // use a faster method
00532 applyGeomorphPosNormalUV0(geoms, vertexPtr, vertexDestPtr, vertexSize, a, a1);
00533 }
00534 else
00535 {
00536 // for color interp
00537 uint i;
00538 uint ua= (uint)(a*256);
00539 clamp(ua, (uint)0, (uint)256);
00540 uint ua1= 256 - ua;
00541
00542 // if an offset is 0, it means that the component is not in the VBuffer.
00543 sint32 normalOff;
00544 sint32 colorOff;
00545 sint32 specularOff;
00546 sint32 uvOff[CVertexBuffer::MaxStage];
00547 bool has3Coords[CVertexBuffer::MaxStage];
00548
00549
00550 // Compute offset of each component of the VB.
00551 if(flags & CVertexBuffer::NormalFlag)
00552 normalOff= _VBufferFinal.getNormalOff();
00553 else
00554 normalOff= 0;
00555 if(flags & CVertexBuffer::PrimaryColorFlag)
00556 colorOff= _VBufferFinal.getColorOff();
00557 else
00558 colorOff= 0;
00559 if(flags & CVertexBuffer::SecondaryColorFlag)
00560 specularOff= _VBufferFinal.getSpecularOff();
00561 else
00562 specularOff= 0;
00563
00564 for(i= 0; i<CVertexBuffer::MaxStage;i++)
00565 {
00566 if(flags & (CVertexBuffer::TexCoord0Flag<<i))
00567 {
00568 uvOff[i]= _VBufferFinal.getTexCoordOff(i);
00569 has3Coords[i] = (_VBufferFinal.getValueType(i + CVertexBuffer::TexCoord0) == CVertexBuffer::Float3);
00570 }
00571 else
00572 {
00573 uvOff[i]= 0;
00574 }
00575 }
00576
00577
00578 // For all geomorphs.
00579 uint nGeoms= geoms.size();
00580 CMRMWedgeGeom *ptrGeom= &(geoms[0]);
00581 uint8 *destPtr= vertexDestPtr;
00582 /* NB: optimisation: lot of "if" in this Loop, but because of BTB, they always cost nothing (prediction is good).
00583 NB: this also is why we unroll the 4 1st Uv. The other (if any), are done in the other loop.
00584 NB: optimisation for AGP write cominers: the order of write (vertex, normal, uvs...) is important for good
00585 use of AGP write combiners.
00586 We have 2 version : one that tests for 3 coordinates texture coords, and one that doesn't
00587 */
00588
00589 if (!has3Coords[0] && !has3Coords[1] && !has3Coords[2] && !has3Coords[3])
00590 {
00591 // there are no texture coordinate of dimension 3
00592 for(; nGeoms>0; nGeoms--, ptrGeom++, destPtr+= vertexSize )
00593 {
00594 uint8 *startPtr= vertexPtr + ptrGeom->Start*vertexSize;
00595 uint8 *endPtr= vertexPtr + ptrGeom->End*vertexSize;
00596
00597 // Vertex.
00598 {
00599 CVector *start= (CVector*)startPtr;
00600 CVector *end= (CVector*)endPtr;
00601 CVector *dst= (CVector*)destPtr;
00602 *dst= *start * a + *end * a1;
00603 }
00604
00605 // Normal.
00606 if(normalOff)
00607 {
00608 CVector *start= (CVector*)(startPtr + normalOff);
00609 CVector *end= (CVector*)(endPtr + normalOff);
00610 CVector *dst= (CVector*)(destPtr + normalOff);
00611 *dst= *start * a + *end * a1;
00612 }
00613
00614
00615 // Uvs.
00616 // uv[0].
00617 if(uvOff[0])
00618 {
00619 // Uv.
00620 CUV *start= (CUV*)(startPtr + uvOff[0]);
00621 CUV *end= (CUV*)(endPtr + uvOff[0]);
00622 CUV *dst= (CUV*)(destPtr + uvOff[0]);
00623 *dst= *start * a + *end * a1;
00624 }
00625 // uv[1].
00626 if(uvOff[1])
00627 {
00628 // Uv.
00629 CUV *start= (CUV*)(startPtr + uvOff[1]);
00630 CUV *end= (CUV*)(endPtr + uvOff[1]);
00631 CUV *dst= (CUV*)(destPtr + uvOff[1]);
00632 *dst= *start * a + *end * a1;
00633 }
00634 // uv[2].
00635 if(uvOff[2])
00636 {
00637 CUV *start= (CUV*)(startPtr + uvOff[2]);
00638 CUV *end= (CUV*)(endPtr + uvOff[2]);
00639 CUV *dst= (CUV*)(destPtr + uvOff[2]);
00640 *dst= *start * a + *end * a1;
00641 }
00642 // uv[3].
00643 if(uvOff[3])
00644 {
00645 // Uv.
00646 CUV *start= (CUV*)(startPtr + uvOff[3]);
00647 CUV *end= (CUV*)(endPtr + uvOff[3]);
00648 CUV *dst= (CUV*)(destPtr + uvOff[3]);
00649 *dst= *start * a + *end * a1;
00650 }
00651 }
00652 }
00653 else // THERE ARE TEXTURE COORDINATES OF DIMENSION 3
00654 {
00655 for(; nGeoms>0; nGeoms--, ptrGeom++, destPtr+= vertexSize )
00656 {
00657 uint8 *startPtr= vertexPtr + ptrGeom->Start*vertexSize;
00658 uint8 *endPtr= vertexPtr + ptrGeom->End*vertexSize;
00659
00660 // Vertex.
00661 {
00662 CVector *start= (CVector*)startPtr;
00663 CVector *end= (CVector*)endPtr;
00664 CVector *dst= (CVector*)destPtr;
00665 *dst= *start * a + *end * a1;
00666 }
00667
00668 // Normal.
00669 if(normalOff)
00670 {
00671 CVector *start= (CVector*)(startPtr + normalOff);
00672 CVector *end= (CVector*)(endPtr + normalOff);
00673 CVector *dst= (CVector*)(destPtr + normalOff);
00674 *dst= *start * a + *end * a1;
00675 }
00676 // Uvs.
00677 // uv[0].
00678 if(uvOff[0])
00679 {
00680 if (!has3Coords[0])
00681 {
00682 // Uv.
00683 CUV *start= (CUV*)(startPtr + uvOff[0]);
00684 CUV *end= (CUV*)(endPtr + uvOff[0]);
00685 CUV *dst= (CUV*)(destPtr + uvOff[0]);
00686 *dst= *start * a + *end * a1;
00687 }
00688 else
00689 {
00690 // Uv.
00691 CUVW *start= (CUVW*)(startPtr + uvOff[0]);
00692 CUVW *end= (CUVW*)(endPtr + uvOff[0]);
00693 CUVW *dst= (CUVW*)(destPtr + uvOff[0]);
00694 *dst= *start * a + *end * a1;
00695 }
00696 }
00697 // uv[1].
00698 if(uvOff[1])
00699 {
00700 if (!has3Coords[1])
00701 {
00702 // Uv.
00703 CUV *start= (CUV*)(startPtr + uvOff[1]);
00704 CUV *end= (CUV*)(endPtr + uvOff[1]);
00705 CUV *dst= (CUV*)(destPtr + uvOff[1]);
00706 *dst= *start * a + *end * a1;
00707 }
00708 else
00709 {
00710 // Uv.
00711 CUVW *start= (CUVW*)(startPtr + uvOff[1]);
00712 CUVW *end= (CUVW*)(endPtr + uvOff[1]);
00713 CUVW *dst= (CUVW*)(destPtr + uvOff[1]);
00714 *dst= *start * a + *end * a1;
00715 }
00716 }
00717 // uv[2].
00718 if(uvOff[2])
00719 {
00720 if (!has3Coords[2])
00721 {
00722 // Uv.
00723 CUV *start= (CUV*)(startPtr + uvOff[2]);
00724 CUV *end= (CUV*)(endPtr + uvOff[2]);
00725 CUV *dst= (CUV*)(destPtr + uvOff[2]);
00726 *dst= *start * a + *end * a1;
00727 }
00728 else
00729 {
00730 // Uv.
00731 CUVW *start= (CUVW*)(startPtr + uvOff[2]);
00732 CUVW *end= (CUVW*)(endPtr + uvOff[2]);
00733 CUVW *dst= (CUVW*)(destPtr + uvOff[2]);
00734 *dst= *start * a + *end * a1;
00735 }
00736 }
00737 // uv[3].
00738 if(uvOff[3])
00739 {
00740 if (!has3Coords[3])
00741 {
00742 // Uv.
00743 CUV *start= (CUV*)(startPtr + uvOff[3]);
00744 CUV *end= (CUV*)(endPtr + uvOff[3]);
00745 CUV *dst= (CUV*)(destPtr + uvOff[3]);
00746 *dst= *start * a + *end * a1;
00747 }
00748 else
00749 {
00750 // Uv.
00751 CUVW *start= (CUVW*)(startPtr + uvOff[3]);
00752 CUVW *end= (CUVW*)(endPtr + uvOff[3]);
00753 CUVW *dst= (CUVW*)(destPtr + uvOff[3]);
00754 *dst= *start * a + *end * a1;
00755 }
00756 }
00757 // color.
00758 if(colorOff)
00759 {
00760 CRGBA *start= (CRGBA*)(startPtr + colorOff);
00761 CRGBA *end= (CRGBA*)(endPtr + colorOff);
00762 CRGBA *dst= (CRGBA*)(destPtr + colorOff);
00763 dst->blendFromui(*start, *end, ua1);
00764 }
00765 // specular.
00766 if(specularOff)
00767 {
00768 CRGBA *start= (CRGBA*)(startPtr + specularOff);
00769 CRGBA *end= (CRGBA*)(endPtr + specularOff);
00770 CRGBA *dst= (CRGBA*)(destPtr + specularOff);
00771 dst->blendFromui(*start, *end, ua1);
00772 }
00773 }
00774 }
00775
00776
00777 // Process extra UVs (maybe never, so don't bother optims :)).
00778 // For all stages after 4.
00779 for(i=4;i<CVertexBuffer::MaxStage;i++)
00780 {
00781 uint nGeoms= geoms.size();
00782 CMRMWedgeGeom *ptrGeom= &(geoms[0]);
00783 uint8 *destPtr= vertexDestPtr;
00784
00785 if(uvOff[i]==0)
00786 continue;
00787
00788 // For all geomorphs.
00789 for(; nGeoms>0; nGeoms--, ptrGeom++, destPtr+= vertexSize )
00790 {
00791 uint8 *startPtr= vertexPtr + ptrGeom->Start*vertexSize;
00792 uint8 *endPtr= vertexPtr + ptrGeom->End*vertexSize;
00793
00794 // uv[i].
00795 // Uv.
00796 if (!has3Coords[i])
00797 {
00798 CUV *start= (CUV*)(startPtr + uvOff[i]);
00799 CUV *end= (CUV*)(endPtr + uvOff[i]);
00800 CUV *dst= (CUV*)(destPtr + uvOff[i]);
00801 *dst= *start * a + *end * a1;
00802 }
00803 else
00804 {
00805 CUVW *start= (CUVW*)(startPtr + uvOff[i]);
00806 CUVW *end= (CUVW*)(endPtr + uvOff[i]);
00807 CUVW *dst= (CUVW*)(destPtr + uvOff[i]);
00808 *dst= *start * a + *end * a1;
00809 }
00810 }
00811 }
00812 }
00813 }
|
|
|
change materials Ids (called from CMesh::optimizeMaterialUsage())
Definition at line 462 of file mesh_mrm.cpp. References _Lods, getNbLod(), getNbRdrPass(), nlassert, uint, and uint32. Referenced by NL3D::CMeshMRM::optimizeMaterialUsage().
|
|
||||||||||||||||||||||||
|
Definition at line 1825 of file mesh_mrm_skin.cpp. Referenced by renderSkinGroupGeom(). |
|
||||||||||||
|
Skinning: Apply skinning to the _VBuffer (before geomorph).
Definition at line 207 of file mesh_mrm_skin.cpp. References _SkinWeights, _VBufferFinal, NL3D::computeBoneMatrixes3x4(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexFormat(), NL3D::CVertexBuffer::getVertexSize(), index, NL3D::CMeshMRMGeom::CLod::InfluencedVertices, NL3D::CMesh::CSkinWeight::MatrixId, NL3D::CMeshMRMGeom::CLod::MatrixInfluences, NL3D_MESH_SKINNING_MAX_MATRIX, nlassert, sint32, uint, uint32, uint8, and NL3D::CMesh::CSkinWeight::Weights. Referenced by renderSkin().
00208 {
00209 nlassert(_Skinned);
00210 if(_SkinWeights.size()==0)
00211 return;
00212
00213 // get vertexPtr.
00214 //===========================
00215 uint8 *destVertexPtr= (uint8*)_VBufferFinal.getVertexCoordPointer();
00216 uint flags= _VBufferFinal.getVertexFormat();
00217 sint32 vertexSize= _VBufferFinal.getVertexSize();
00218 // must have XYZ.
00219 nlassert(flags & CVertexBuffer::PositionFlag);
00220
00221
00222 // compute src array.
00223 CMesh::CSkinWeight *srcSkinPtr;
00224 CVector *srcVertexPtr;
00225 srcSkinPtr= &_SkinWeights[0];
00226 srcVertexPtr= &_OriginalSkinVertices[0];
00227
00228
00229
00230 // Compute usefull Matrix for this lod.
00231 //===========================
00232 // Those arrays map the array of bones in skeleton.
00233 static vector<CMatrix3x4> boneMat3x4;
00234 computeBoneMatrixes3x4(boneMat3x4, lod.MatrixInfluences, skeleton);
00235
00236
00237 // apply skinning.
00238 //===========================
00239 // assert, code below is written especially for 4 per vertex.
00240 nlassert(NL3D_MESH_SKINNING_MAX_MATRIX==4);
00241 for(uint i=0;i<NL3D_MESH_SKINNING_MAX_MATRIX;i++)
00242 {
00243 uint nInf= lod.InfluencedVertices[i].size();
00244 if( nInf==0 )
00245 continue;
00246 uint32 *infPtr= &(lod.InfluencedVertices[i][0]);
00247
00248 // apply the skin to the vertices
00249 switch(i)
00250 {
00251 //=========
00252 case 0:
00253 // Special case for Vertices influenced by one matrix. Just copy result of mul.
00254 // for all InfluencedVertices only.
00255 for(;nInf>0;nInf--, infPtr++)
00256 {
00257 uint index= *infPtr;
00258 CMesh::CSkinWeight *srcSkin= srcSkinPtr + index;
00259 CVector *srcVertex= srcVertexPtr + index;
00260 uint8 *dstVertexVB= destVertexPtr + index * vertexSize;
00261 CVector *dstVertex= (CVector*)(dstVertexVB);
00262
00263
00264 // Vertex.
00265 boneMat3x4[ srcSkin->MatrixId[0] ].mulSetPoint( *srcVertex, *dstVertex);
00266 }
00267 break;
00268
00269 //=========
00270 case 1:
00271 // for all InfluencedVertices only.
00272 for(;nInf>0;nInf--, infPtr++)
00273 {
00274 uint index= *infPtr;
00275 CMesh::CSkinWeight *srcSkin= srcSkinPtr + index;
00276 CVector *srcVertex= srcVertexPtr + index;
00277 uint8 *dstVertexVB= destVertexPtr + index * vertexSize;
00278 CVector *dstVertex= (CVector*)(dstVertexVB);
00279
00280
00281 // Vertex.
00282 boneMat3x4[ srcSkin->MatrixId[0] ].mulSetPoint( *srcVertex, srcSkin->Weights[0], *dstVertex);
00283 boneMat3x4[ srcSkin->MatrixId[1] ].mulAddPoint( *srcVertex, srcSkin->Weights[1], *dstVertex);
00284 }
00285 break;
00286
00287 //=========
00288 case 2:
00289 // for all InfluencedVertices only.
00290 for(;nInf>0;nInf--, infPtr++)
00291 {
00292 uint index= *infPtr;
00293 CMesh::CSkinWeight *srcSkin= srcSkinPtr + index;
00294 CVector *srcVertex= srcVertexPtr + index;
00295 uint8 *dstVertexVB= destVertexPtr + index * vertexSize;
00296 CVector *dstVertex= (CVector*)(dstVertexVB);
00297
00298
00299 // Vertex.
00300 boneMat3x4[ srcSkin->MatrixId[0] ].mulSetPoint( *srcVertex, srcSkin->Weights[0], *dstVertex);
00301 boneMat3x4[ srcSkin->MatrixId[1] ].mulAddPoint( *srcVertex, srcSkin->Weights[1], *dstVertex);
00302 boneMat3x4[ srcSkin->MatrixId[2] ].mulAddPoint( *srcVertex, srcSkin->Weights[2], *dstVertex);
00303 }
00304 break;
00305
00306 //=========
00307 case 3:
00308 // for all InfluencedVertices only.
00309 for(;nInf>0;nInf--, infPtr++)
00310 {
00311 uint index= *infPtr;
00312 CMesh::CSkinWeight *srcSkin= srcSkinPtr + index;
00313 CVector *srcVertex= srcVertexPtr + index;
00314 uint8 *dstVertexVB= destVertexPtr + index * vertexSize;
00315 CVector *dstVertex= (CVector*)(dstVertexVB);
00316
00317
00318 // Vertex.
00319 boneMat3x4[ srcSkin->MatrixId[0] ].mulSetPoint( *srcVertex, srcSkin->Weights[0], *dstVertex);
00320 boneMat3x4[ srcSkin->MatrixId[1] ].mulAddPoint( *srcVertex, srcSkin->Weights[1], *dstVertex);
00321 boneMat3x4[ srcSkin->MatrixId[2] ].mulAddPoint( *srcVertex, srcSkin->Weights[2], *dstVertex);
00322 boneMat3x4[ srcSkin->MatrixId[3] ].mulAddPoint( *srcVertex, srcSkin->Weights[3], *dstVertex);
00323 }
00324 break;
00325
00326 }
00327 }
00328 }
|
|
||||||||||||
|
The same as apply skin, but with normal modified. Normal is not normalized. 4 versions from slower to faster. Definition at line 741 of file mesh_mrm_skin.cpp. Referenced by renderSkin(). |
|
||||||||||||||||
|
The same as apply skin with normal, but with a tangent space added (encoded in a texture coordinate). The tangent space is modified, but not normalized (must be done in a vertex program). 4 versions from slower to faster. Definition at line 804 of file mesh_mrm_skin.cpp. Referenced by renderSkin(). |
|
|
The framework call this method when he will render instances of this meshGeom soon. Implements NL3D::IMeshGeom. Definition at line 2705 of file mesh_mrm.cpp. References _Lods, _MBRBkupNormalize, _VBufferFinal, NL3D::IDriver::activeVertexBuffer(), NL3D::IDriver::activeVertexBufferHard(), NL3D::CMeshGeomRenderContext::Driver, NL3D::IDriver::forceNormalize(), NL3D::CVertexBuffer::getNumVertices(), NL3D::IDriver::isForceNormalize(), NL3D::CMeshGeomRenderContext::RenderThroughVBHeap, and updateVertexBufferHard().
02706 {
02707 if(_Lods.empty())
02708 return;
02709
02710 IDriver *drv= rdrCtx.Driver;
02711
02712 if(rdrCtx.RenderThroughVBHeap)
02713 {
02714 // Don't setup VB in this case, since use the VBHeap setuped one.
02715 }
02716 else
02717 {
02718 updateVertexBufferHard(drv, _VBufferFinal.getNumVertices());
02719
02720 // active VB.
02721 if(_VBHard)
02722 {
02723 drv->activeVertexBufferHard(_VBHard);
02724 }
02725 else
02726 {
02727 drv->activeVertexBuffer(_VBufferFinal);
02728 }
02729 }
02730
02731
02732 // force normalisation of normals..
02733 _MBRBkupNormalize= drv->isForceNormalize();
02734 drv->forceNormalize(true);
02735
02736 }
|
|
|
Skinning: bkup Vertex/Normal into _OriginalSkin* from VBuffer.
Definition at line 2045 of file mesh_mrm.cpp. References _VBufferFinal, bkupOriginalSkinVerticesSubset(), NL3D::CVertexBuffer::getNumVertices(), and nlassert. Referenced by build().
02046 {
02047 nlassert(_Skinned);
02048
02049 // bkup the entire array.
02050 bkupOriginalSkinVerticesSubset(0, _VBufferFinal.getNumVertices());
02051 }
|
|
||||||||||||
|
Definition at line 2055 of file mesh_mrm.cpp. References _VBufferFinal, NL3D::CVertexBuffer::getNormalCoordPointer(), NL3D::CVertexBuffer::getNumTexCoordUsed(), NL3D::CVertexBuffer::getNumVertices(), NL3D::CVertexBuffer::getTexCoordPointer(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexFormat(), nlassert, and uint. Referenced by bkupOriginalSkinVertices(), and serialLodVertexData().
02056 {
02057 nlassert(_Skinned);
02058
02059 // Copy VBuffer content into Original vertices normals.
02060 if(_VBufferFinal.getVertexFormat() & CVertexBuffer::PositionFlag)
02061 {
02062 // copy vertices from VBuffer. (NB: unusefull geomorphed vertices are still copied, but doesn't matter).
02063 _OriginalSkinVertices.resize(_VBufferFinal.getNumVertices());
02064 for(uint i=wedgeStart; i<wedgeEnd;i++)
02065 {
02066 _OriginalSkinVertices[i]= *(CVector*)_VBufferFinal.getVertexCoordPointer(i);
02067 }
02068 }
02069 if(_VBufferFinal.getVertexFormat() & CVertexBuffer::NormalFlag)
02070 {
02071 // copy normals from VBuffer. (NB: unusefull geomorphed normals are still copied, but doesn't matter).
02072 _OriginalSkinNormals.resize(_VBufferFinal.getNumVertices());
02073 for(uint i=wedgeStart; i<wedgeEnd;i++)
02074 {
02075 _OriginalSkinNormals[i]= *(CVector*)_VBufferFinal.getNormalCoordPointer(i);
02076 }
02077 }
02078
02079 // is there tangent space added ?
02080 if (_MeshVertexProgram && _MeshVertexProgram->needTangentSpace())
02081 {
02082 // yes, backup it
02083 nlassert(_VBufferFinal.getNumTexCoordUsed() > 0);
02084 uint tgSpaceStage = _VBufferFinal.getNumTexCoordUsed() - 1;
02085 _OriginalTGSpace.resize(_VBufferFinal.getNumVertices());
02086 for(uint i=wedgeStart; i<wedgeEnd;i++)
02087 {
02088 _OriginalTGSpace[i]= *(CVector*)_VBufferFinal.getTexCoordPointer(i, tgSpaceStage);
02089 }
02090 }
02091 }
|
|
||||||||||||||||||||
|
Build a mesh, replacing old. this is much slower than CMeshGeom::build(), because it computes the MRM.
Definition at line 246 of file mesh_mrm.cpp. References _LevelDetail, _LodInfos, _Lods, _NbLodLoaded, _SkinWeights, _VBufferFinal, bkupOriginalSkinVertices(), NL3D::CMeshMRMGeom::CMeshBuildMRM::BlendShapes, NL3D::CMeshMorpher::BlendShapes, NL3D::CMesh::CMeshBuild::BonesNames, NL3D::CMRMLevelDetail::compileDistanceSetup(), NL3D::CMRMBuilder::compileMRM(), compileRunTime(), dirtMeshDataId(), NL3D::CMeshMRMGeom::CMeshBuildMRM::DistanceCoarsest, NL3D::CMRMLevelDetail::DistanceCoarsest, NL3D::CMeshMRMGeom::CMeshBuildMRM::DistanceFinest, NL3D::CMRMLevelDetail::DistanceFinest, NL3D::CMeshMRMGeom::CMeshBuildMRM::DistanceMiddle, NL3D::CMRMLevelDetail::DistanceMiddle, NL3D::CMesh::CMeshBuild::Faces, NL3D::CPrimitiveBlock::getNumTriangles(), NL3D::CMeshMRMGeom::CMeshBuildMRM::Lods, NL3D::makeBBox(), matrix, NL3D::CMRMLevelDetail::MaxFaceUsed, NL3D::CMesh::CMeshBuild::MeshVertexProgram, NL3D::CMRMLevelDetail::MinFaceUsed, NL3D_MESH_SKINNING_MAX_MATRIX, nlassert, params, NL3D::CMeshMRMGeom::CRdrPass::PBlock, NL3D::CMeshMRMGeom::CLod::RdrPass, NL3D::CVertexBuffer::reserve(), NLMISC::CAABBoxExt::setCenter(), NL3D::CVertexBuffer::setNumVertices(), NLMISC::CAABBoxExt::setSize(), NL3D::CMeshMRMGeom::CMeshBuildMRM::Skinned, NL3D::CMeshMRMGeom::CMeshBuildMRM::SkinWeights, uint, uint32, NL3D::CMeshMRMGeom::CMeshBuildMRM::VBuffer, and NL3D::CMesh::CMeshBuild::Vertices. Referenced by NL3D::CMeshMRM::build().
00248 {
00249
00250 // Dirt the VBuffer.
00251 _VertexBufferHardDirty= true;
00252
00253 // Empty geometry?
00254 if(m.Vertices.size()==0 || m.Faces.size()==0)
00255 {
00256 _VBufferFinal.setNumVertices(0);
00257 _VBufferFinal.reserve(0);
00258 _Lods.clear();
00259 _BBox.setCenter(CVector::Null);
00260 _BBox.setSize(CVector::Null);
00261 return;
00262 }
00263 nlassert(numMaxMaterial>0);
00264
00265
00266 // SmartPtr Copy VertexProgram effect.
00267 //================================================
00268 this->_MeshVertexProgram= m.MeshVertexProgram;
00269
00270
00272 //======================
00273 // NB: this is equivalent as building BBox from MRM VBuffer, because CMRMBuilder create new vertices
00274 // which are just interpolation of original vertices.
00275 _BBox= makeBBox(m.Vertices);
00276
00277
00279 //================================================
00280 CMRMBuilder mrmBuilder;
00281 CMeshBuildMRM meshBuildMRM;
00282
00283 mrmBuilder.compileMRM(m, bsList, params, meshBuildMRM, numMaxMaterial);
00284
00285 // Then just copy result!
00286 //================================================
00287 _VBufferFinal= meshBuildMRM.VBuffer;
00288 _Lods= meshBuildMRM.Lods;
00289 _Skinned= meshBuildMRM.Skinned;
00290 _SkinWeights= meshBuildMRM.SkinWeights;
00291
00292 // Compute degradation control.
00293 //================================================
00294 _LevelDetail.DistanceFinest= meshBuildMRM.DistanceFinest;
00295 _LevelDetail.DistanceMiddle= meshBuildMRM.DistanceMiddle;
00296 _LevelDetail.DistanceCoarsest= meshBuildMRM.DistanceCoarsest;
00297 nlassert(_LevelDetail.DistanceFinest>=0);
00298 nlassert(_LevelDetail.DistanceMiddle > _LevelDetail.DistanceFinest);
00299 nlassert(_LevelDetail.DistanceCoarsest > _LevelDetail.DistanceMiddle);
00300 // Compute OODistDelta and DistancePow
00301 _LevelDetail.compileDistanceSetup();
00302
00303
00304 // Build the _LodInfos.
00305 //================================================
00306 _LodInfos.resize(_Lods.size());
00307 uint32 precNWedges= 0;
00308 uint i;
00309 for(i=0;i<_Lods.size();i++)
00310 {
00311 _LodInfos[i].StartAddWedge= precNWedges;
00312 _LodInfos[i].EndAddWedges= _Lods[i].NWedges;
00313 precNWedges= _Lods[i].NWedges;
00314 // LodOffset is filled in serial() when stream is input.
00315 }
00316 // After build, all lods are present in memory.
00317 _NbLodLoaded= _Lods.size();
00318
00319
00320 // For load balancing.
00321 //================================================
00322 // compute Max Face Used
00323 _LevelDetail.MaxFaceUsed= 0;
00324 _LevelDetail.MinFaceUsed= 0;
00325 // Count of primitive block
00326 if(_Lods.size()>0)
00327 {
00328 uint pb;
00329 // Compute MinFaces.
00330 CLod &firstLod= _Lods[0];
00331 for (pb=0; pb<firstLod.RdrPass.size(); pb++)
00332 {
00333 CRdrPass &pass= firstLod.RdrPass[pb];
00334 // Sum tri
00335 _LevelDetail.MinFaceUsed+= pass.PBlock.getNumTriangles ();
00336 }
00337 // Compute MaxFaces.
00338 CLod &lastLod= _Lods[_Lods.size()-1];
00339 for (pb=0; pb<lastLod.RdrPass.size(); pb++)
00340 {
00341 CRdrPass &pass= lastLod.RdrPass[pb];
00342 // Sum tri
00343 _LevelDetail.MaxFaceUsed+= pass.PBlock.getNumTriangles ();
00344 }
00345 }
00346
00347
00348 // For skinning.
00349 //================================================
00350 if( _Skinned )
00351 {
00352 bkupOriginalSkinVertices();
00353 }
00354 // Inform that the mesh data has changed
00355 dirtMeshDataId();
00356
00357
00358 // For AGP SKinning optim, and for Render optim
00359 //================================================
00360 for(i=0;i<_Lods.size();i++)
00361 {
00362 _Lods[i].buildSkinVertexBlocks();
00363 // sort triangles for better cache use.
00364 _Lods[i].optimizeTriangleOrder();
00365 }
00366
00367 // Copy Blend Shapes
00368 //================================================
00369 _MeshMorpher.BlendShapes = meshBuildMRM.BlendShapes;
00370
00371
00372 // Compact bone id and build a bone id names
00373 //================================================
00374
00375 // Skinned ?
00376 if (_Skinned)
00377 {
00378 // Remap
00379 std::map<uint, uint> remap;
00380
00381 // Current bone
00382 uint currentBone = 0;
00383
00384 // Reserve memory
00385 _BonesName.reserve (m.BonesNames.size());
00386
00387 // For each vertices
00388 uint vert;
00389 for (vert=0; vert<_SkinWeights.size(); vert++)
00390 {
00391 // Found one ?
00392 bool found=false;
00393
00394 // For each weight
00395 uint weight;
00396 for (weight=0; weight<NL3D_MESH_SKINNING_MAX_MATRIX; weight++)
00397 {
00398 // Active ?
00399 if ((_SkinWeights[vert].Weights[weight]>0)||(weight==0))
00400 {
00401 // Look for it
00402 std::map<uint, uint>::iterator ite = remap.find (_SkinWeights[vert].MatrixId[weight]);
00403
00404 // Find ?
00405 if (ite == remap.end())
00406 {
00407 // Insert it
00408 remap.insert (std::map<uint, uint>::value_type (_SkinWeights[vert].MatrixId[weight], currentBone));
00409
00410 // Check the id
00411 nlassert (_SkinWeights[vert].MatrixId[weight]<m.BonesNames.size());
00412
00413 // Set the bone name
00414 _BonesName.push_back (m.BonesNames[_SkinWeights[vert].MatrixId[weight]]);
00415
00416 // Set the local bone id
00417 _SkinWeights[vert].MatrixId[weight] = currentBone++;
00418 }
00419 else
00420 {
00421 // Set the local bone id
00422 _SkinWeights[vert].MatrixId[weight] = ite->second;
00423 }
00424
00425 // Found one
00426 found = true;
00427 }
00428 }
00429
00430 // Found one ?
00431 nlassert (found);
00432 }
00433
00434 // Remap the vertex influence by lods
00435 uint lod;
00436 for (lod=0; lod<_Lods.size(); lod++)
00437 {
00438 // For each matrix used
00439 uint matrix;
00440 for (matrix=0; matrix<_Lods[lod].MatrixInfluences.size(); matrix++)
00441 {
00442 // Remap
00443 std::map<uint, uint>::iterator ite = remap.find (_Lods[lod].MatrixInfluences[matrix]);
00444
00445 // Find ?
00446 nlassert (ite != remap.end());
00447
00448 // Remap
00449 _Lods[lod].MatrixInfluences[matrix] = ite->second;
00450 }
00451 }
00452 }
00453
00454 // Misc.
00455 //===================
00456 // Some runtime not serialized compilation
00457 compileRunTime();
00458
00459 }
|
|
|
Definition at line 2482 of file mesh_mrm.cpp. References _SkinWeights, NL3D_MESH_SKINNING_MAX_MATRIX, uint, and uint32. Referenced by loadFirstLod().
02483 {
02484 if(_Skinned)
02485 {
02486 // parse all vertices, couting MaxBoneId used.
02487 uint32 maxBoneId= 0;
02488 // for each vertex
02489 uint vert;
02490 for (vert=0; vert<_SkinWeights.size(); vert++)
02491 {
02492 // For each weight
02493 for (uint weight=0; weight<NL3D_MESH_SKINNING_MAX_MATRIX; weight++)
02494 {
02495 // Active ?
02496 if ((_SkinWeights[vert].Weights[weight]>0)||(weight==0))
02497 {
02498 maxBoneId= max(_SkinWeights[vert].MatrixId[weight], maxBoneId);
02499 }
02500 }
02501 }
02502
02503 // alloc an array of maxBoneId+1, reset to 0.
02504 std::vector<uint8> boneUsage;
02505 boneUsage.resize(maxBoneId+1, 0);
02506
02507 // reparse all vertices, counting usage for each bone.
02508 for (vert=0; vert<_SkinWeights.size(); vert++)
02509 {
02510 // For each weight
02511 for (uint weight=0; weight<NL3D_MESH_SKINNING_MAX_MATRIX; weight++)
02512 {
02513 // Active ?
02514 if ((_SkinWeights[vert].Weights[weight]>0)||(weight==0))
02515 {
02516 // mark this bone as used.
02517 boneUsage[_SkinWeights[vert].MatrixId[weight]]= 1;
02518 }
02519 }
02520 }
02521
02522 // For each bone used
02523 _BonesId.clear();
02524 for(uint i=0; i<boneUsage.size();i++)
02525 {
02526 // if the bone is used by the mesh, add it to BoneId.
02527 if(boneUsage[i])
02528 _BonesId.push_back(i);
02529 }
02530 }
02531 }
|
|
||||||||||||||||
|
Change MRM Distance setup. NB: no-op if distanceFinest<0, distanceMiddle<=distanceFinest or if distanceCoarsest<=distanceMiddle.
Definition at line 228 of file mesh_mrm.cpp. References _LevelDetail, NL3D::CMRMLevelDetail::compileDistanceSetup(), NL3D::CMRMLevelDetail::DistanceCoarsest, NL3D::CMRMLevelDetail::DistanceFinest, and NL3D::CMRMLevelDetail::DistanceMiddle. Referenced by NL3D::CMeshMultiLod::changeMRMDistanceSetup(), and NL3D::CMeshMRM::changeMRMDistanceSetup().
00229 {
00230 // check input.
00231 if(distanceFinest<0) return;
00232 if(distanceMiddle<=distanceFinest) return;
00233 if(distanceCoarsest<=distanceMiddle) return;
00234
00235 // Change.
00236 _LevelDetail.DistanceFinest= distanceFinest;
00237 _LevelDetail.DistanceMiddle= distanceMiddle;
00238 _LevelDetail.DistanceCoarsest= distanceCoarsest;
00239
00240 // compile
00241 _LevelDetail.compileDistanceSetup();
00242 }
|
|
||||||||||||
|
choose the lod according to the alphaMRM [0,1] given.
Definition at line 898 of file mesh_mrm.cpp. References _Lods, _NbLodLoaded, and sint. Referenced by activeInstance(), profileSceneRender(), render(), renderSkin(), and renderSkinGroupGeom().
00899 {
00900 // Choose what Lod to draw.
00901 alphaMRM*= _Lods.size()-1;
00902 sint numLod= (sint)ceil(alphaMRM);
00903 if(numLod==0)
00904 {
00905 numLod= 0;
00906 alphaLod= 0;
00907 }
00908 else
00909 {
00910 // Lerp beetween lod i-1 and lod i.
00911 alphaLod= alphaMRM-(numLod-1);
00912 }
00913
00914
00915 // If lod chosen is not loaded, take the best loaded.
00916 if(numLod>=(sint)_NbLodLoaded)
00917 {
00918 numLod= _NbLodLoaded-1;
00919 alphaLod= 1;
00920 }
00921
00922 return numLod;
00923 }
|
|
||||||||||||
|
clip this mesh in a driver. true if visible.
Reimplemented from NL3D::IMeshGeom. Definition at line 856 of file mesh_mrm.cpp. References 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::CMeshMRM::clip().
00857 {
00858 // Speed Clip: clip just the sphere.
00859 CBSphere localSphere(_BBox.getCenter(), _BBox.getRadius());
00860 CBSphere worldSphere;
00861
00862 // transform the sphere in WorldMatrix (with nearly good scale info).
00863 localSphere.applyTransform(worldMatrix, worldSphere);
00864
00865 // if out of only plane, entirely out.
00866 for(sint i=0;i<(sint)pyramid.size();i++)
00867 {
00868 // We are sure that pyramid has normalized plane normals.
00869 // if SpherMax OUT return false.
00870 float d= pyramid[i]*worldSphere.Center;
00871 if(d>worldSphere.Radius)
00872 return false;
00873 }
00874
00875 // test if must do a precise clip, according to mesh size.
00876 if( _PreciseClipping )
00877 {
00878 CPlane localPlane;
00879
00880 // if out of only plane, entirely out.
00881 for(sint i=0;i<(sint)pyramid.size();i++)
00882 {
00883 // Transform the pyramid in Object space.
00884 localPlane= pyramid[i]*worldMatrix;
00885 // localPlane must be normalized, because worldMatrix mya have a scale.
00886 localPlane.normalize();
00887 // if the box is not partially inside the plane, quit
00888 if( !_BBox.clipBack(localPlane) )
00889 return false;
00890 }
00891 }
00892
00893 return true;
00894 }
|
|
|
Definition at line 2554 of file mesh_mrm.cpp. References _Lods, _ShadowSkinVertices, _SupportMeshBlockRendering, _SupportShadowSkinGrouping, _SupportSkinGrouping, _VBufferFinal, NL3D::CMeshMorpher::BlendShapes, NL3D::CPrimitiveBlock::getNumLine(), NL3D::CPrimitiveBlock::getNumQuad(), NL3D::CVertexBuffer::getNumVertices(), NLMISC::CAABBoxExt::getRadius(), NL3D::CVertexBuffer::getVertexFormat(), NL3D_MESH_PRECISE_CLIP_THRESHOLD, NL3D_MESH_SKIN_MANAGER_MAXVERTICES, NL3D_MESH_SKIN_MANAGER_VERTEXFORMAT, NL3D_SHADOW_MESH_SKIN_MANAGER_MAXVERTICES, NL3D_SHADOW_MESH_SKIN_MANAGER_VERTEXFORMAT, and uint. Referenced by build().
02555 {
02556 _PreciseClipping= _BBox.getRadius() >= NL3D_MESH_PRECISE_CLIP_THRESHOLD;
02557
02558 // Compute if can support SkinGrouping rendering
02559 if(_Lods.size()==0 || !_Skinned)
02560 {
02561 _SupportSkinGrouping= false;
02562 _SupportShadowSkinGrouping= false;
02563 }
02564 else
02565 {
02566 // The Mesh must follow those restrictions, to support group skinning
02567 _SupportSkinGrouping=
02568 _VBufferFinal.getVertexFormat() == NL3D_MESH_SKIN_MANAGER_VERTEXFORMAT &&
02569 _VBufferFinal.getNumVertices() < NL3D_MESH_SKIN_MANAGER_MAXVERTICES &&
02570 !_MeshVertexProgram;
02571 // Additionally, NONE of the RdrPass should have Quads or lines...
02572 for(uint i=0;i<_Lods.size();i++)
02573 {
02574 for(uint j=0;j<_Lods[i].RdrPass.size();j++)
02575 {
02576 CPrimitiveBlock &pb= _Lods[i].RdrPass[j].PBlock;
02577 if( pb.getNumQuad() || pb.getNumLine() )
02578 {
02579 _SupportSkinGrouping= false;
02580 break;
02581 }
02582 }
02583 }
02584
02585 // Support Shadow SkinGrouping if Shadow setuped, and if not too many vertices.
02586 _SupportShadowSkinGrouping= !_ShadowSkinVertices.empty() &&
02587 NL3D_SHADOW_MESH_SKIN_MANAGER_VERTEXFORMAT==CVertexBuffer::PositionFlag &&
02588 _ShadowSkinVertices.size() <= NL3D_SHADOW_MESH_SKIN_MANAGER_MAXVERTICES;
02589 }
02590
02591 // Support MeshBlockRendering only if not skinned/meshMorphed.
02592 _SupportMeshBlockRendering= !_Skinned && _MeshMorpher.BlendShapes.size()==0;
02593
02594 // \todo yoyo: support later MeshVertexProgram
02595 _SupportMeshBlockRendering= _SupportMeshBlockRendering && _MeshVertexProgram==NULL;
02596 }
|
|
|
Compute skinning id.
Definition at line 2293 of file mesh_mrm.cpp. References _BonesSphere, _Lods, _ShadowSkinVertices, _SkinWeights, NL3D::CSkeletonModel::Bones, NL3D::CSkeletonModel::flagBoneAndParents(), NL3D::CSkeletonModel::getBoneIdByName(), matrix, NL3D_MESH_SKINNING_MAX_MATRIX, nlassert, nlwarning, sint32, uint, uint32, and v. Referenced by NL3D::CMeshMRM::computeBonesId().
02294 {
02295 // Already computed ?
02296 if (!_BoneIdComputed)
02297 {
02298 // Get a pointer on the skeleton
02299 nlassert (skeleton);
02300 if (skeleton)
02301 {
02302 // Resize boneId to the good size.
02303 _BonesId.resize(_BonesName.size());
02304
02305 // Remap bones id table
02306 std::vector<uint> remap (_BonesName.size());
02307
02308 // **** For each bones, compute remap
02309 uint bone;
02310 for (bone=0; bone<remap.size(); bone++)
02311 {
02312 // Look for the bone
02313 sint32 boneId = skeleton->getBoneIdByName (_BonesName[bone]);
02314
02315 // Setup the _BoneId.
02316 _BonesId[bone]= boneId;
02317
02318 // Bones found ?
02319 if (boneId != -1)
02320 {
02321 // Set the bone id
02322 remap[bone] = (uint32)boneId;
02323 }
02324 else
02325 {
02326 // Put id 0
02327 remap[bone] = 0;
02328
02329 // Error
02330 nlwarning ("Bone %s not found in the skeleton.", _BonesName[bone].c_str());
02331 }
02332 }
02333
02334 // **** Remap the vertices, and compute Bone Spheres.
02335
02336 // Find the Geomorph space: to process only real vertices, not geomorphed ones.
02337 uint nGeomSpace= 0;
02338 uint lod;
02339 for (lod=0; lod<_Lods.size(); lod++)
02340 {
02341 nGeomSpace= max(nGeomSpace, (uint)_Lods[lod].Geomorphs.size());
02342 }
02343
02344 // Prepare Sphere compute
02345 nlassert(_OriginalSkinVertices.size() == _SkinWeights.size());
02346 static std::vector<CAABBox> boneBBoxes;
02347 static std::vector<bool> boneBBEmpty;
02348 boneBBoxes.clear();
02349 boneBBEmpty.clear();
02350 boneBBoxes.resize(_BonesId.size());
02351 boneBBEmpty.resize(_BonesId.size(), true);
02352
02353 // Remap the vertex, and compute the bone spheres. see CTransform::getSkinBoneSphere() doc.
02354 // for true vertices
02355 uint vert;
02356 for (vert=nGeomSpace; vert<_SkinWeights.size(); vert++)
02357 {
02358 // get the vertex position.
02359 CVector vertex= _OriginalSkinVertices[vert];
02360
02361 // For each weight
02362 uint weight;
02363 for (weight=0; weight<NL3D_MESH_SKINNING_MAX_MATRIX; weight++)
02364 {
02365 // Active ?
02366 if ((_SkinWeights[vert].Weights[weight]>0)||(weight==0))
02367 {
02368 // Check id
02369 uint srcId= _SkinWeights[vert].MatrixId[weight];
02370 nlassert (srcId < remap.size());
02371 // remap
02372 _SkinWeights[vert].MatrixId[weight] = remap[srcId];
02373
02374 // if the boneId is valid (ie found)
02375 if(_BonesId[srcId]>=0)
02376 {
02377 // transform the vertex pos in BoneSpace
02378 CVector p= skeleton->Bones[_BonesId[srcId]].getBoneBase().InvBindPos * vertex;
02379 // extend the bone bbox.
02380 if(boneBBEmpty[srcId])
02381 {
02382 boneBBoxes[srcId].setCenter(p);
02383 boneBBEmpty[srcId]= false;
02384 }
02385 else
02386 {
02387 boneBBoxes[srcId].extend(p);
02388 }
02389 }
02390 }
02391 else
02392 break;
02393 }
02394 }
02395
02396 // Compile spheres
02397 _BonesSphere.resize(_BonesId.size());
02398 for(bone=0;bone<_BonesSphere.size();bone++)
02399 {
02400 // If the bone is empty, mark with -1 in the radius.
02401 if(boneBBEmpty[bone])
02402 {
02403 _BonesSphere[bone].Radius= -1;
02404 }
02405 else
02406 {
02407 _BonesSphere[bone].Center= boneBBoxes[bone].getCenter();
02408 _BonesSphere[bone].Radius= boneBBoxes[bone].getRadius();
02409 }
02410 }
02411
02412 // **** Remap the vertex influence by lods
02413 for (lod=0; lod<_Lods.size(); lod++)
02414 {
02415 // For each matrix used
02416 uint matrix;
02417 for (matrix=0; matrix<_Lods[lod].MatrixInfluences.size(); matrix++)
02418 {
02419 // Check
02420 nlassert (_Lods[lod].MatrixInfluences[matrix]<remap.size());
02421
02422 // Remap
02423 _Lods[lod].MatrixInfluences[matrix] = remap[_Lods[lod].MatrixInfluences[matrix]];
02424 }
02425 }
02426
02427 // **** Remap Shadow Vertices.
02428 for(vert=0;vert<_ShadowSkinVertices.size();vert++)
02429 {
02430 CShadowVertex &v= _ShadowSkinVertices[vert];
02431 // Check id
02432 nlassert (v.MatrixId < remap.size());
02433 v.MatrixId= remap[v.MatrixId];
02434 }
02435
02436 // Computed
02437 _BoneIdComputed = true;
02438 }
02439 }
02440
02441 // Already extended ?
02442 if (!_BoneIdExtended)
02443 {
02444 nlassert (skeleton);
02445 if (skeleton)
02446 {
02447 // the total bone Usage of the mesh.
02448 vector<bool> boneUsage;
02449 boneUsage.resize(skeleton->Bones.size(), false);
02450
02451 // for all Bones marked as valid.
02452 uint i;
02453 for(i=0; i<_BonesId.size(); i++)
02454 {
02455 // if not a valid boneId, skip it.
02456 if(_BonesId[i]<0)
02457 continue;
02458
02459 // mark him and his father in boneUsage.
02460 skeleton->flagBoneAndParents(_BonesId[i], boneUsage);
02461 }
02462
02463 // fill _BonesIdExt with bones of _BonesId and their parents.
02464 _BonesIdExt.clear();
02465 for(i=0; i<boneUsage.size();i++)
02466 {
02467 // if the bone is used by the mesh, add it to BoneIdExt.
02468 if(boneUsage[i])
02469 _BonesIdExt.push_back(i);
02470 }
02471
02472 }
02473
02474 // Extended
02475 _BoneIdExtended= true;
02476 }
02477
02478 }
|
|
||||||||||||
|
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 2811 of file mesh_mrm.cpp. References _Lods, _VBufferFinal, 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(), NL3D::CMeshMRMGeom::CLod::RdrPass, NL3D::CPrimitiveBlock::setNumLine(), NL3D::CPrimitiveBlock::setNumQuad(), NL3D::CPrimitiveBlock::setNumTri(), uint, and uint32.
02812 {
02813 // Fill dst with Buffer content.
02814 memcpy(dst, _VBufferFinal.getVertexCoordPointer(), _VBufferFinal.getNumVertices()*_VBufferFinal.getVertexSize() );
02815
02816 // For All Lods
02817 for(uint lodId=0; lodId<_Lods.size();lodId++)
02818 {
02819 CLod &lod= _Lods[lodId];
02820
02821 // For all rdrPass.
02822 for(uint i=0;i<lod.RdrPass.size();i++)
02823 {
02824 // shift the PB
02825 CPrimitiveBlock &srcPb= lod.RdrPass[i].PBlock;
02826 CPrimitiveBlock &dstPb= lod.RdrPass[i].VBHeapPBlock;
02827 uint j;
02828
02829 // Lines.
02830 dstPb.setNumLine(srcPb.getNumLine());
02831 uint32 *srcLinePtr= srcPb.getLinePointer();
02832 uint32 *dstLinePtr= dstPb.getLinePointer();
02833 for(j=0; j<dstPb.getNumLine()*2;j++)
02834 {
02835 dstLinePtr[j]= srcLinePtr[j]+indexStart;
02836 }
02837 // Tris.
02838 dstPb.setNumTri(srcPb.getNumTri());
02839 uint32 *srcTriPtr= srcPb.getTriPointer();
02840 uint32 *dstTriPtr= dstPb.getTriPointer();
02841 for(j=0; j<dstPb.getNumTri()*3;j++)
02842 {
02843 dstTriPtr[j]= srcTriPtr[j]+indexStart;
02844 }
02845 // Quads.
02846 dstPb.setNumQuad(srcPb.getNumQuad());
02847 uint32 *srcQuadPtr= srcPb.getQuadPointer();
02848 uint32 *dstQuadPtr= dstPb.getQuadPointer();
02849 for(j=0; j<dstPb.getNumQuad()*4;j++)
02850 {
02851 dstQuadPtr[j]= srcQuadPtr[j]+indexStart;
02852 }
02853 }
02854 }
02855 }
|
|
|
Definition at line 2209 of file mesh_mrm.cpp. References nlassert. Referenced by ~CMeshMRMGeom().
02210 {
02211 // test (refptr) if the object still exist in memory.
02212 if(_VBHard!=NULL)
02213 {
02214 // A vbufferhard should still exist only if driver still exist.
02215 nlassert(_Driver!=NULL);
02216
02217 // delete it from driver.
02218 _Driver->deleteVertexBufferHard(_VBHard);
02219 _VBHard= NULL;
02220 }
02221 }
|
|
|
Increment the refCount, so instances RawSkins are no longer valid.
Definition at line 3052 of file mesh_mrm.cpp. References _MeshDataId. Referenced by build().
03053 {
03054 // see updateRawSkinNormal()
03055 _MeshDataId++;
03056 }
|
|
|
The framework call this method when it has done with this meshGeom Implements NL3D::IMeshGeom. Definition at line 2791 of file mesh_mrm.cpp. References _Lods, _MBRBkupNormalize, NL3D::CMeshGeomRenderContext::Driver, and NL3D::IDriver::forceNormalize().
02792 {
02793 if(_Lods.empty())
02794 return;
02795
02796 // bkup force normalisation.
02797 rdrCtx.Driver->forceNormalize(_MBRBkupNormalize);
02798 }
|
|
||||||||||||
|
Definition at line 1978 of file mesh_mrm_skin.cpp. |
|
|
get the bone names of the meshMRM.
Definition at line 182 of file mesh_mrm.h.
00182 {return _BonesName;}
|
|
|
get the extended axis aligned bounding box of the mesh
Implements NL3D::IMeshGeom. Definition at line 170 of file mesh_mrm.h. Referenced by NL3D::CMeshMRM::getBoundingBox().
00171 {
00172 return _BBox;
00173 }
|
|
|
Implemented in NLAIAGENT::CNumericIndex, NLAIC::IPointerGestion, NLAIC::CIdentType, and CAutomataDesc. Referenced by NLMISC::CClassRegistry::checkObject(), and NL3D::GetTextureSize(). |
|
|
Advanced. get the geomorphs for a special lod.
Definition at line 216 of file mesh_mrm.h.
00217 {
00218 return _Lods[lodId].Geomorphs;
00219 }
|
|
|
get the MRM level detail information
Definition at line 275 of file mesh_mrm.h. References _LevelDetail. Referenced by NL3D::CMeshMRMInstance::getMRMLevelDetail().
00275 {return _LevelDetail;}
|
|
|
get the number of BlendShapes
Definition at line 222 of file mesh_mrm.h. References NL3D::CMeshMorpher::BlendShapes, and uint.
00222 { return _MeshMorpher.BlendShapes.size(); }
|
|
|
get the number of LOD. Definition at line 186 of file mesh_mrm.h. Referenced by applyMaterialRemap(), NL3D::CMeshMRM::getNbLod(), and loadNextLod().
00186 { return _Lods.size() ; }
|
|
|
get the number of LOD currently loaded. Definition at line 140 of file mesh_mrm.h. References _NbLodLoaded, and uint. Referenced by loadNextLod(), and unloadNextLod().
00140 { return _NbLodLoaded ; }
|
|
|
get the number of rendering pass of a LOD.
Definition at line 192 of file mesh_mrm.h. Referenced by NL3D::CZoneLighter::addTriangles(), NL3D::CInstanceLighter::addTriangles(), applyMaterialRemap(), and NL3D::CMeshMRM::getNbRdrPass().
00192 { return _Lods[lodId].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 2700 of file mesh_mrm.cpp. References _Lods, _MBRCurrentLodId, and uint.
02701 {
02702 return _Lods[_MBRCurrentLodId].RdrPass.size();
02703 }
|
|
|
return the number of renderPasses for this mesh. Used only if sortPerMaterial()) is true Implements NL3D::IMeshGeom. Definition at line 2693 of file mesh_mrm.cpp. References uint.
02694 {
02695 // not used...
02696 return 0;
02697
02698 }
|
|
|
Get the num of shadow skin vertices.
Definition at line 3370 of file mesh_mrm.cpp. References _ShadowSkinVertices, and uint.
03371 {
03372 return _ShadowSkinVertices.size();
03373 }
|
|
|
get an approximation of the number of triangles this instance will render for a fixed distance.
Implements NL3D::IMeshGeom. Definition at line 2200 of file mesh_mrm.cpp. References _LevelDetail, and NL3D::CMRMLevelDetail::getNumTriangles(). Referenced by NL3D::CMeshMRM::getNumTriangles().
02201 {
02202 // NB: this is an approximation, but this is continious.
02203 return _LevelDetail.getNumTriangles(distance);
02204 }
|
|
||||||||||||
|
get the material ID associated with a rendering pass of a LOD.
Definition at line 209 of file mesh_mrm.h. References _Lods, uint, and uint32. Referenced by NL3D::CZoneLighter::addTriangles(), and NL3D::CMeshMRM::getRdrPassMaterial().
00210 {
00211 return _Lods[lodId].RdrPass[renderingPassIndex].MaterialId ;
00212 }
|
|
||||||||||||
|
get the primitive block associated with a rendering pass of a LOD.
Definition at line 199 of file mesh_mrm.h. Referenced by NL3D::CZoneLighter::addTriangles(), NL3D::CInstanceLighter::addTriangles(), and NL3D::CMeshMRM::getRdrPassPrimitiveBlock().
00200 {
00201 return _Lods[lodId].RdrPass[renderingPassIndex].PBlock ;
00202 }
|
|
|
see CTransform::getSkinBoneSphere() doc for the meaning of this value. computeBonesId must has been called before.
Definition at line 246 of file mesh_mrm.h. References _BonesSphere. Referenced by NL3D::CMeshMRMInstance::getSkinBoneSphere().
00246 {return _BonesSphere;}
|
|
|
return array of bones used by the skin. computeBonesId must has been called before.
Definition at line 243 of file mesh_mrm.h. Referenced by NL3D::CMeshMRMInstance::getSkinBoneUsage().
00243 {return _BonesId;}
|
|
|
get the skinWeights used by the mrm mesh. NB: same size of the vertexBuffer. empty if !isSkinned()
Definition at line 179 of file mesh_mrm.h. References _SkinWeights.
00179 {return _SkinWeights;}
|
|
||||||||||||
|
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 2802 of file mesh_mrm.cpp. References _SupportMeshBlockRendering, _VBufferFinal, NL3D::CVertexBuffer::getNumVertices(), NL3D::CVertexBuffer::getVertexFormat(), and uint.
02803 {
02804 // CMeshMRMGeom support VBHeap rendering, assuming _SupportMeshBlockRendering is true
02805 vertexFormat= _VBufferFinal.getVertexFormat();
02806 numVertices= _VBufferFinal.getNumVertices();
02807 return _SupportMeshBlockRendering;
02808 }
|
|
|
get the vertex buffer used by the mrm mesh. NB: this VB store all Vertices used by All LODs.
Definition at line 176 of file mesh_mrm.h. References _VBufferFinal. Referenced by NL3D::CZoneLighter::addTriangles(), NL3D::CInstanceLighter::addTriangles(), and NL3D::CMeshMRM::getVertexBuffer().
00176 { return _VBufferFinal ; }
|
|
|
True if this mesh has a vertexProgram.
Reimplemented from NL3D::IMeshGeom. Definition at line 287 of file mesh_mrm.h. Referenced by NL3D::CMeshMRMInstance::initRenderFilterType().
00287 {return _MeshVertexProgram!=NULL;}
|
|
|
Init instance info.
Implements NL3D::IMeshGeom. Definition at line 847 of file mesh_mrm.cpp. Referenced by NL3D::CMeshMRM::createInstance().
00848 {
00849 // init the instance with _MeshVertexProgram infos
00850 if(_MeshVertexProgram)
00851 _MeshVertexProgram->initInstance(mbi);
00852 }
|
|
|
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 from NL3D::IMeshGeom. Definition at line 2858 of file mesh_mrm.cpp.
02859 {
02860 // Yes, need it for geomorph
02861 return true;
02862 }
|
|
|
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 profileSceneRender(), and NL3D::CMeshGeom::profileSceneRender().
00215 {return _MeshVBHeapId!=0;}
|
|
|
Return true if the mesh is skinned, else return false.
Definition at line 231 of file mesh_mrm.h. Referenced by NL3D::CMeshMRMInstance::isSkinnable().
00232 {
00233 return _Skinned;
00234 }
|
|
|
load this mesh.
Definition at line 1757 of file mesh_mrm.cpp.
01758 {
01759
01760 // because loading, flag the VertexBufferHard.
01761 _VertexBufferHardDirty= true;
01762
01763
01764 // Load the header of the stream.
01765 // ==================
01766 sint verHeader= loadHeader(f);
01767
01768 // Read All lod subsets.
01769 // ==================
01770 for(uint i=0;i<_LodInfos.size(); i++)
01771 {
01772 // read the lod face data.
01773 f.serial(_Lods[i]);
01774 // read the lod vertex data.
01775 serialLodVertexData(f, _LodInfos[i].StartAddWedge, _LodInfos[i].EndAddWedges);
01776 // if reading, must bkup all original vertices from VB.
01777 // this is done in serialLodVertexData(). by subset
01778 }
01779
01780 // Now, all lods are loaded.
01781 _NbLodLoaded= _Lods.size();
01782
01783 // If version doen't have boneNames, must build BoneId now.
01784 if(verHeader <= 2)
01785 {
01786 buildBoneUsageVer2 ();
01787 }
01788 }
|
|
|
Load the header and the first lod of a MRM in a stream.
Definition at line 1951 of file mesh_mrm.cpp. References _LodInfos, _Lods, _NbLodLoaded, buildBoneUsageVer2(), loadHeader(), NLMISC::IStream::serial(), serialLodVertexData(), sint, and uint.
01952 {
01953
01954 // because loading, flag the VertexBufferHard.
01955 _VertexBufferHardDirty= true;
01956
01957 // Load the header of the stream.
01958 // ==================
01959 sint verHeader= loadHeader(f);
01960
01961
01962 // If empty MRM, quit.
01963 if(_LodInfos.size()==0)
01964 return;
01965
01966 /* If the version is <4, then SkinWeights are serialised per Lod.
01967 But for computebonesId(), we must have all SkinWeights RIGHT NOW.
01968 Hence, if too old version (<4), serialize all the MRM....
01969 */
01970 uint numLodToLoad;
01971 if(verHeader<4)
01972 numLodToLoad= _LodInfos.size();
01973 else
01974 numLodToLoad= 1;
01975
01976
01977 // Read lod subset(s).
01978 // ==================
01979 for(uint i=0;i<numLodToLoad; i++)
01980 {
01981 // read the lod face data.
01982 f.serial(_Lods[i]);
01983 // read the lod vertex data.
01984 serialLodVertexData(f, _LodInfos[i].StartAddWedge, _LodInfos[i].EndAddWedges);
01985 // if reading, must bkup all original vertices from VB.
01986 // this is done in serialLodVertexData(). by subset
01987 }
01988
01989 // Now, just first lod is loaded (but if too old file)
01990 _NbLodLoaded= numLodToLoad;
01991
01992 // If version doen't have boneNames, must build BoneId now.
01993 if(verHeader <= 2)
01994 {
01995 buildBoneUsageVer2 ();
01996 }
01997 }
|
|
|
load the header of this mesh. return the version of the header.
Definition at line 1627 of file mesh_mrm.cpp. References NLMISC::IStreamable::serial(), sint, sint32, uint, and uint32. Referenced by loadFirstLod().
01628 {
01629 /*
01630 Version 5:
01631 - Shadow Skinning
01632 Version 4:
01633 - serial SkinWeights per MRM, not per Lod
01634 Version 3:
01635 - Bones names.
01636 Version 2:
01637 - Mesh Vertex Program.
01638 Version 1:
01639 - added blend shapes
01640 Version 0:
01641 - base version.
01642 */
01643 sint ver= f.serialVersion(5);
01644
01645
01646 // if >= version 3, serial boens names
01647 if(ver>=3)
01648 {
01649 f.serialCont (_BonesName);
01650 }
01651
01652 // Version3-: Bones index are in skeleton model id list
01653 _BoneIdComputed = (ver < 3);
01654 // Must always recompute usage of parents of bones used.
01655 _BoneIdExtended = false;
01656
01657 // Mesh Vertex Program.
01658 if (ver >= 2)
01659 {
01660 IMeshVertexProgram *mvp= NULL;
01661 f.serialPolyPtr(mvp);
01662 _MeshVertexProgram= mvp;
01663 }
01664 else
01665 {
01666 // release vp
01667 _MeshVertexProgram= NULL;
01668 }
01669
01670 // blend shapes
01671 if (ver >= 1)
01672 f.serial (_MeshMorpher);
01673
01674 // serial Basic info.
01675 // ==================
01676 f.serial(_Skinned);
01677 f.serial(_BBox);
01678 f.serial(_LevelDetail.MaxFaceUsed);
01679 f.serial(_LevelDetail.MinFaceUsed);
01680 f.serial(_LevelDetail.DistanceFinest);
01681 f.serial(_LevelDetail.DistanceMiddle);
01682 f.serial(_LevelDetail.DistanceCoarsest);
01683 f.serial(_LevelDetail.OODistanceDelta);
01684 f.serial(_LevelDetail.DistancePow);
01685 // preload the Lods.
01686 f.serialCont(_LodInfos);
01687
01688 // read/save number of wedges.
01689 /* NB: prepare memory space too for vertices.
01690 \todo yoyo: TODO_OPTIMIZE. for now there is no Lod memory profit with vertices / skinWeights.
01691 But resizing arrays is a problem because of reallocation...
01692 */
01693 uint32 nWedges;
01694 f.serial(nWedges);
01695 // Prepare the VBuffer.
01696 _VBufferFinal.serialHeader(f);
01697 // If skinned, must allocate skinWeights.
01698 contReset(_SkinWeights);
01699 if(_Skinned)
01700 {
01701 _SkinWeights.resize(nWedges);
01702 }
01703
01704
01705 // If new version, serial SkinWeights in header, not in lods.
01706 if(ver >= 4)
01707 {
01708 f.serialCont(_SkinWeights);
01709 }
01710
01711
01712 // if >= version 5, serial Shadow Skin Information
01713 if(ver>=5)
01714 {
01715 f.serialCont (_ShadowSkinVertices);
01716 f.serialCont (_ShadowSkinTriangles);
01717 }
01718
01719
01720 // Serial lod offsets.
01721 // ==================
01722 // This is the reference pos, to load / save relative offsets.
01723 sint32 startPos = f.getPos();
01724 // Those are the lodOffsets, relative to startPos.
01725 vector<sint32> lodOffsets;
01726 lodOffsets.resize(_LodInfos.size(), 0);
01727
01728 // read all relative offsets, and build the absolute offset of LodInfos.
01729 for(uint i=0;i<_LodInfos.size(); i++)
01730 {
01731 f.serial(lodOffsets[i]);
01732 _LodInfos[i].LodOffset= startPos + lodOffsets[i];
01733 }
01734
01735
01736 // resest the Lod arrays. NB: each Lod is empty, and ready to receive Lod data.
01737 // ==================
01738 contReset(_Lods);
01739 _Lods.resize(_LodInfos.size());
01740
01741 // Flag the fact that no lod is loaded for now.
01742 _NbLodLoaded= 0;
01743
01744 // Inform that the mesh data has changed
01745 dirtMeshDataId();
01746
01747
01748 // Some runtime not serialized compilation
01749 compileRunTime();
01750
01751 // return version of the header
01752 return ver;
01753 }
|
|
|
Load next lod of a stream. use getNbLodLoaded() to know what Lod will be loaded. NB: if getNbLodLoaded() == getNbLod(), no op.
Definition at line 2001 of file mesh_mrm.cpp. References _LodInfos, _Lods, _NbLodLoaded, getNbLod(), getNbLodLoaded(), NLMISC::IStream::seek(), NLMISC::IStream::serial(), and serialLodVertexData().
02002 {
02003
02004 // because loading, flag the VertexBufferHard.
02005 _VertexBufferHardDirty= true;
02006
02007 // If all is loaded, quit.
02008 if(getNbLodLoaded() == getNbLod())
02009 return;
02010
02011 // Set pos to good lod.
02012 f.seek(_LodInfos[_NbLodLoaded].LodOffset, IStream::begin);
02013
02014 // Serial this lod data.
02015 // read the lod face data.
02016 f.serial(_Lods[_NbLodLoaded]);
02017 // read the lod vertex data.
02018 serialLodVertexData(f, _LodInfos[_NbLodLoaded].StartAddWedge, _LodInfos[_NbLodLoaded].EndAddWedges);
02019 // if reading, must bkup all original vertices from VB.
02020 // this is done in serialLodVertexData(). by subset
02021
02022
02023 // Inc LodLoaded count.
02024 _NbLodLoaded++;
02025 }
|
|
|
clip this mesh in a driver. true if visible.
|
|
||||||||||||||||||||
|
Scene profile.
Implements NL3D::IMeshGeom. Definition at line 2600 of file mesh_mrm.cpp. References _LevelDetail, _Lods, _VBufferFinal, NL3D::CScene::BenchRes, chooseLod(), NL3D::CMRMLevelDetail::getLevelDetailFromPolyCount(), NL3D::CPrimitiveBlock::getNumTri(), NL3D::CVertexBuffer::getVertexFormat(), NL3D::CScene::incrementProfileTriVBFormat(), NL3D::IMeshGeom::isMeshInVBHeap(), NL3D::CMeshMRMGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, NL3D::UScene::CBenchResults::MeshMRMProfileTriVBFormat, NL3D::UScene::CBenchResults::NumMeshMRMRdrBlock, NL3D::UScene::CBenchResults::NumMeshMRMRdrBlockWithVBHeap, NL3D::UScene::CBenchResults::NumMeshMRMRdrNormal, NL3D::UScene::CBenchResults::NumMeshMRMTriRdrBlock, NL3D::UScene::CBenchResults::NumMeshMRMTriRdrBlockWithVBHeap, NL3D::UScene::CBenchResults::NumMeshMRMTriRdrNormal, NL3D::UScene::CBenchResults::NumMeshMRMVBufferHard, NL3D::UScene::CBenchResults::NumMeshMRMVBufferStd, NL3D::CMeshMRMGeom::CRdrPass::PBlock, NL3D::CMeshMRMGeom::CLod::RdrPass, NL3D::CTraversal::Scene, sint, supportMeshBlockRendering(), uint, and uint32. Referenced by NL3D::CMeshMRM::profileSceneRender().
02601 {
02602 // get the result of the Load Balancing.
02603 float alphaMRM= _LevelDetail.getLevelDetailFromPolyCount(polygonCount);
02604
02605 // choose the lod.
02606 float alphaLod;
02607 sint numLod= chooseLod(alphaMRM, alphaLod);
02608
02609 // Render the choosen Lod.
02610 CLod &lod= _Lods[numLod];
02611
02612 // get the mesh instance.
02613 CMeshBaseInstance *mi= safe_cast<CMeshBaseInstance*>(trans);
02614
02615 // Profile all pass.
02616 uint triCount= 0;
02617 for (uint i=0;i<lod.RdrPass.size();i++)
02618 {
02619 CRdrPass &rdrPass= lod.RdrPass[i];
02620 // Profile with the Materials of the MeshInstance.
02621 if ( ( (mi->Materials[rdrPass.MaterialId].getBlend() == false) && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) ) ||
02622 ( (mi->Materials[rdrPass.MaterialId].getBlend() == true) && (rdrFlags & IMeshGeom::RenderTransparentMaterial) ) )
02623 {
02624 triCount+= rdrPass.PBlock.getNumTri();
02625 }
02626 }
02627
02628 // Profile
02629 if(triCount)
02630 {
02631 // tri per VBFormat
02632 rdrTrav->Scene->incrementProfileTriVBFormat(rdrTrav->Scene->BenchRes.MeshMRMProfileTriVBFormat,
02633 _VBufferFinal.getVertexFormat(), triCount);
02634
02635 // VBHard
02636 if(_VBHard)
02637 rdrTrav->Scene->BenchRes.NumMeshMRMVBufferHard++;
02638 else
02639 rdrTrav->Scene->BenchRes.NumMeshMRMVBufferStd++;
02640
02641 // rendered in BlockRendering, only if not transparent pass (known it if RenderTransparentMaterial is set)
02642 if(supportMeshBlockRendering() && (rdrFlags & IMeshGeom::RenderTransparentMaterial)==0 )
02643 {
02644 if(isMeshInVBHeap())
02645 {
02646 rdrTrav->Scene->BenchRes.NumMeshMRMRdrBlockWithVBHeap++;
02647 rdrTrav->Scene->BenchRes.NumMeshMRMTriRdrBlockWithVBHeap+= triCount;
02648 }
02649 else
02650 {
02651 rdrTrav->Scene->BenchRes.NumMeshMRMRdrBlock++;
02652 rdrTrav->Scene->BenchRes.NumMeshMRMTriRdrBlock+= triCount;
02653 }
02654 }
02655 else
02656 {
02657 rdrTrav->Scene->BenchRes.NumMeshMRMRdrNormal++;
02658 rdrTrav->Scene->BenchRes.NumMeshMRMTriRdrNormal+= triCount;
02659 }
02660 }
02661 }
|
|
||||||||||||||||||||||||
|
render() this mesh in a driver, given an instance and his materials.
Implements NL3D::IMeshGeom. Definition at line 927 of file mesh_mrm.cpp. References _LevelDetail, _Lods, _VBufferFinal, _VBufferOriginal, NL3D::IDriver::activeVertexBuffer(), NL3D::IDriver::activeVertexBufferHard(), applyGeomorph(), NL3D::CMeshMorpher::BlendShapes, NL3D::CTravCameraScene::CamPos, chooseLod(), NL3D::IDriver::forceNormalize(), NL3D::CMeshMRMGeom::CLod::Geomorphs, NL3D::CMeshBaseInstance::getBlendShapeFactors(), NL3D::CMRMLevelDetail::getLevelDetailFromPolyCount(), NL3D::CVertexBuffer::getNumVertices(), NL3D::CTransform::getOwnerScene(), NL3D::CScene::getRenderTrav(), NL3D::CTransform::getSkeletonModel(), NL3D::CTransform::getWorldMatrix(), H_AUTO, NL3D::CMeshMorpher::init(), NL3D::CMeshMorpher::initSkinned(), NLMISC::CMatrix::inverted(), NL3D::IDriver::isForceNormalize(), NL3D::CTransform::isSkinned(), NL3D::CMeshMRMGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, nlassert, NLMISC::OptFastFloor(), NL3D::CMeshMRMGeom::CLod::OriginalSkinRestored, NL3D::CMeshMRMGeom::CRdrPass::PBlock, NL3D::CMeshBlender::prepareRenderForGlobalAlpha(), NL3D::CMeshMRMGeom::CLod::RdrPass, NL3D::IDriver::render(), restoreOriginalSkinPart(), NL3D::CMeshBlender::restoreRender(), NL3D::IDriver::setupModelMatrix(), sint, uint, uint32, uint8, NL3D::CMeshMorpher::update(), NL3D::CMeshMorpher::updateSkinned(), and updateVertexBufferHard(). Referenced by NL3D::CMeshMRM::render().
00928 {
00929 nlassert(drv);
00930 if(_Lods.size()==0)
00931 return;
00932
00933
00934 // get the meshMRM instance.
00935 CMeshBaseInstance *mi= safe_cast<CMeshBaseInstance*>(trans);
00936 // get a ptr on scene
00937 CScene *ownerScene= mi->getOwnerScene();
00938 // get a ptr on renderTrav
00939 CRenderTrav *renderTrav= &ownerScene->getRenderTrav();
00940
00941
00942 // get the result of the Load Balancing.
00943 float alphaMRM= _LevelDetail.getLevelDetailFromPolyCount(polygonCount);
00944
00945 // choose the lod.
00946 float alphaLod;
00947 sint numLod= chooseLod(alphaMRM, alphaLod);
00948
00949
00950 // Render the choosen Lod.
00951 CLod &lod= _Lods[numLod];
00952 if(lod.RdrPass.size()==0)
00953 return;
00954
00955
00956 // Update the vertexBufferHard (if possible).
00957 // \toto yoyo: TODO_OPTIMIZE: allocate only what is needed for the current Lod (Max of all instances, like
00958 // the loading....) (see loadHeader()).
00959 updateVertexBufferHard(drv, _VBufferFinal.getNumVertices());
00960 /* currentVBHard is NULL if must disable it temporarily
00961 For now, never disable it, but switch of VBHard may be VERY EXPENSIVE if NV_vertex_array_range2 is not
00962 supported (old drivers).
00963 */
00964 IVertexBufferHard *currentVBHard= _VBHard;
00965
00966
00967 // get the skeleton model to which I am binded (else NULL).
00968 CSkeletonModel *skeleton;
00969 skeleton = mi->getSkeletonModel();
00970 // The mesh must not be skinned for render()
00971 nlassert(!(_Skinned && mi->isSkinned() && skeleton));
00972 bool bMorphApplied = _MeshMorpher.BlendShapes.size() > 0;
00973 bool useTangentSpace = _MeshVertexProgram && _MeshVertexProgram->needTangentSpace();
00974
00975
00976 // Profiling
00977 //===========
00978 H_AUTO( NL3D_MeshMRMGeom_RenderNormal );
00979
00980
00981 // Morphing
00982 // ========
00983 if (bMorphApplied)
00984 {
00985 // If _Skinned (NB: the skin is not applied) and if lod.OriginalSkinRestored, then restoreOriginalSkinPart is
00986 // not called but mush morpher write changed vertices into VBHard so its ok. The unchanged vertices
00987 // are written in the preceding call to restoreOriginalSkinPart.
00988 if (_Skinned)
00989 {
00990 _MeshMorpher.initSkinned(&_VBufferOriginal,
00991 &_VBufferFinal,
00992 currentVBHard,
00993 useTangentSpace,
00994 &_OriginalSkinVertices,
00995 &_OriginalSkinNormals,
00996 useTangentSpace ? &_OriginalTGSpace : NULL,
00997 false );
00998 _MeshMorpher.updateSkinned (mi->getBlendShapeFactors());
00999 }
01000 else // Not even skinned so we have to do all the stuff
01001 {
01002 _MeshMorpher.init(&_VBufferOriginal,
01003 &_VBufferFinal,
01004 currentVBHard,
01005 useTangentSpace);
01006 _MeshMorpher.update (mi->getBlendShapeFactors());
01007 }
01008 }
01009
01010 // Skinning.
01011 //===========
01012 // if mesh is skinned (but here skin not applied), we must copy vertices/normals from original vertices.
01013 if (_Skinned)
01014 {
01015 // do it for this Lod only, and if cache say it is necessary.
01016 if (!lod.OriginalSkinRestored)
01017 restoreOriginalSkinPart(lod, currentVBHard);
01018 }
01019
01020
01021 // set the instance worldmatrix.
01022 drv->setupModelMatrix(trans->getWorldMatrix());
01023
01024
01025 // Geomorph.
01026 //===========
01027 // Geomorph the choosen Lod (if not the coarser mesh).
01028 if(numLod>0)
01029 {
01030 applyGeomorph(lod.Geomorphs, alphaLod, currentVBHard);
01031 }
01032
01033
01034 // force normalisation of normals..
01035 bool bkupNorm= drv->isForceNormalize();
01036 drv->forceNormalize(true);
01037
01038
01039 // Setup meshVertexProgram
01040 //===========
01041
01042 // use MeshVertexProgram effect?
01043 bool useMeshVP= _MeshVertexProgram != NULL;
01044 if( useMeshVP )
01045 {
01046 CMatrix invertedObjectMatrix;
01047 invertedObjectMatrix = trans->getWorldMatrix().inverted();
01048 // really ok if success to begin VP
01049 useMeshVP= _MeshVertexProgram->begin(drv, mi->getOwnerScene(), mi, invertedObjectMatrix, renderTrav->CamPos);
01050 }
01051
01052
01053 // Render the lod.
01054 //===========
01055 // active VB.
01056 if(currentVBHard)
01057 drv->activeVertexBufferHard(currentVBHard);
01058 else
01059 drv->activeVertexBuffer(_VBufferFinal);
01060
01061
01062 // Global alpha used ?
01063 uint32 globalAlphaUsed= rdrFlags & IMeshGeom::RenderGlobalAlpha;
01064 uint8 globalAlphaInt=(uint8)NLMISC::OptFastFloor(globalAlpha*255);
01065
01066 // Render all pass.
01067 if (globalAlphaUsed)
01068 {
01069 bool gaDisableZWrite= (rdrFlags & IMeshGeom::RenderGADisableZWrite)?true:false;
01070
01071 // for all passes
01072 for(uint i=0;i<lod.RdrPass.size();i++)
01073 {
01074 CRdrPass &rdrPass= lod.RdrPass[i];
01075
01076 if ( ( (mi->Materials[rdrPass.MaterialId].getBlend() == false) && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) ) ||
01077 ( (mi->Materials[rdrPass.MaterialId].getBlend() == true) && (rdrFlags & IMeshGeom::RenderTransparentMaterial) ) )
01078 {
01079 // CMaterial Ref
01080 CMaterial &material=mi->Materials[rdrPass.MaterialId];
01081
01082 // Use a MeshBlender to modify material and driver.
01083 CMeshBlender blender;
01084 blender.prepareRenderForGlobalAlpha(material, drv, globalAlpha, globalAlphaInt, gaDisableZWrite);
01085
01086 // Setup VP material
01087 if (useMeshVP)
01088 {
01089 if(currentVBHard)
01090 _MeshVertexProgram->setupForMaterial(material, drv, ownerScene, currentVBHard);
01091 else
01092 _MeshVertexProgram->setupForMaterial(material, drv, ownerScene, &_VBufferFinal);
01093 }
01094
01095 // Render
01096 drv->render(rdrPass.PBlock, material);
01097
01098 // Resetup material/driver
01099 blender.restoreRender(material, drv, gaDisableZWrite);
01100 }
01101 }
01102 }
01103 else
01104 {
01105 for(uint i=0;i<lod.RdrPass.size();i++)
01106 {
01107 CRdrPass &rdrPass= lod.RdrPass[i];
01108
01109 if ( ( (mi->Materials[rdrPass.MaterialId].getBlend() == false) && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) ) ||
01110 ( (mi->Materials[rdrPass.MaterialId].getBlend() == true) && (rdrFlags & IMeshGeom::RenderTransparentMaterial) ) )
01111 {
01112 // CMaterial Ref
01113 CMaterial &material=mi->Materials[rdrPass.MaterialId];
01114
01115 // Setup VP material
01116 if (useMeshVP)
01117 {
01118 if(currentVBHard)
01119 _MeshVertexProgram->setupForMaterial(material, drv, ownerScene, currentVBHard);
01120 else
01121 _MeshVertexProgram->setupForMaterial(material, drv, ownerScene, &_VBufferFinal);
01122 }
01123
01124 // Render with the Materials of the MeshInstance.
01125 drv->render(rdrPass.PBlock, material);
01126 }
01127 }
01128 }
01129
01130
01131 // End VertexProgram effect
01132 if(useMeshVP)
01133 {
01134 // end it.
01135 _MeshVertexProgram->end(drv);
01136 }
01137
01138
01139 // bkup force normalisation.
01140 drv->forceNormalize(bkupNorm);
01141
01142 }
|
|
||||||||||||||||||||
|
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 2768 of file mesh_mrm.cpp. References _Lods, _MBRCurrentLodId, NL3D::CMeshGeomRenderContext::Driver, NL3D::CMeshMRMGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, NL3D::CMeshMRMGeom::CRdrPass::PBlock, NL3D::CMeshMRMGeom::CLod::RdrPass, NL3D::IDriver::render(), NL3D::CMeshGeomRenderContext::RenderThroughVBHeap, uint, and NL3D::CMeshMRMGeom::CRdrPass::VBHeapPBlock.
02769 {
02770 if(_Lods.empty())
02771 return;
02772
02773 CLod &lod= _Lods[_MBRCurrentLodId];
02774 CRdrPass &rdrPass= lod.RdrPass[rdrPassId];
02775
02776 if ( mi->Materials[rdrPass.MaterialId].getBlend() == false )
02777 {
02778 // CMaterial Ref
02779 CMaterial &material=mi->Materials[rdrPass.MaterialId];
02780
02781 // Render with the Materials of the MeshInstance.
02782 if(rdrCtx.RenderThroughVBHeap)
02783 // render shifted primitives
02784 rdrCtx.Driver->render(rdrPass.VBHeapPBlock, material);
02785 else
02786 rdrCtx.Driver->render(rdrPass.PBlock, material);
02787 }
02788 }
|
|
||||||||||||||||
|
Get the num of shadow skin vertices.
Definition at line 3376 of file mesh_mrm.cpp. References _ShadowSkinVertices, applyArrayShadowSkin(), NL3D::CTransform::getSkeletonModel(), H_AUTO_USE, nlassert, sint, uint, and uint8. Referenced by NL3D::CMeshMRMInstance::renderShadowSkinGeom().
03377 {
03378 uint numVerts= _ShadowSkinVertices.size();
03379
03380 if(numVerts==0)
03381 return 0;
03382
03383 // If the Lod is too big to render in the VBufferHard
03384 if(numVerts>remainingVertices)
03385 // return Failure
03386 return -1;
03387
03388 // get the skeleton model to which I am skinned
03389 CSkeletonModel *skeleton;
03390 skeleton = mi->getSkeletonModel();
03391 // must be skinned for renderSkin()
03392 nlassert(skeleton);
03393
03394
03395 // Profiling
03396 //===========
03397 H_AUTO_USE( NL3D_MeshMRMGeom_RenderShadow );
03398
03399
03400 // Skinning.
03401 //===========
03402
03403 // skinning with normal, but no tangent space
03404 applyArrayShadowSkin(&_ShadowSkinVertices[0], (CVector*)vbDest, skeleton, numVerts);
03405
03406
03407 // How many vertices are added to the VBuffer ???
03408 return numVerts;
03409 }
|
|
||||||||||||||||||||
|
Get the num of shadow skin vertices.
Definition at line 3412 of file mesh_mrm.cpp. References _ShadowSkinTriangles, H_AUTO_USE, min, nlassert, NL3D::IDriver::renderTriangles(), src, uint, and uint32. Referenced by NL3D::CMeshMRMInstance::renderShadowSkinPrimitives().
03413 {
03414 nlassert(drv);
03415
03416 if(_ShadowSkinTriangles.empty())
03417 return;
03418
03419 // Profiling
03420 //===========
03421 H_AUTO_USE( NL3D_MeshMRMGeom_RenderShadow );
03422
03423 // NB: the skeleton matrix has already been setuped by CSkeletonModel
03424 // NB: the normalize flag has already been setuped by CSkeletonModel
03425
03426 // TODO_SHADOW: optim: Special triangle cache for shadow!
03427 static vector<uint32> shiftedTris;
03428 if(shiftedTris.size()<_ShadowSkinTriangles.size())
03429 {
03430 shiftedTris.resize(_ShadowSkinTriangles.size());
03431 }
03432 uint32 *src= &_ShadowSkinTriangles[0];
03433 uint32 *dst= &shiftedTris[0];
03434 for(uint n= _ShadowSkinTriangles.size();n>0;n--, src++, dst++)
03435 {
03436 *dst= *src + baseVertex;
03437 }
03438
03439 // Render Triangles with cache
03440 //===========
03441
03442 uint numTris= _ShadowSkinTriangles.size()/3;
03443
03444 // This speed up 4 ms for 80K polys.
03445 uint memToCache= numTris*12;
03446 memToCache= min(memToCache, 4096U);
03447 CFastMem::precache(&shiftedTris[0], memToCache);
03448
03449 // Render with the Materials of the MeshInstance.
03450 drv->renderTriangles(castMat, &shiftedTris[0], numTris);
03451 }
|
|
||||||||||||
|
render() this mesh as a skin
Implements NL3D::IMeshGeom. Definition at line 1146 of file mesh_mrm.cpp. References _Lods, _VBufferFinal, _VBufferOriginal, NL3D::IDriver::activeVertexBuffer(), applyGeomorph(), applySkin(), applySkinWithNormal(), applySkinWithTangentSpace(), NL3D::CMeshMorpher::BlendShapes, NL3D::CTravCameraScene::CamPos, chooseLod(), NL3D::CMeshMRMGeom::CLod::Geomorphs, NL3D::CMeshBaseInstance::getBlendShapeFactors(), NL3D::CRenderTrav::getDriver(), NL3D::CVertexBuffer::getNumTexCoordUsed(), NL3D::CTransform::getOwnerScene(), NL3D::CScene::getRenderTrav(), NL3D::CTransform::getSkeletonModel(), NL3D::CVertexBuffer::getVertexFormat(), NL3D::CTransform::getWorldMatrix(), H_AUTO, NL3D::CMeshMorpher::initSkinned(), NLMISC::CMatrix::inverted(), NL3D::CTransform::isSkinned(), NL3D::CMeshMRMGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, nlassert, NL3D::CMeshMRMGeom::CLod::OriginalSkinRestored, NL3D::CMeshMRMGeom::CRdrPass::PBlock, NL3D::CMeshMRMGeom::CLod::RdrPass, NL3D::IDriver::render(), sint, uint, updateRawSkinNormal(), and NL3D::CMeshMorpher::updateSkinned(). Referenced by NL3D::CMeshMRMInstance::renderSkin().
01147 {
01148 H_AUTO( NL3D_MeshMRMGeom_renderSkin );
01149
01150 if(_Lods.size()==0)
01151 return;
01152
01153
01154 // get the meshMRM instance. only CMeshMRMInstance is possible when skinned (not MultiLod)
01155 CMeshMRMInstance *mi= safe_cast<CMeshMRMInstance*>(trans);
01156 // get a ptr on scene
01157 CScene *ownerScene= mi->getOwnerScene();
01158 // get a ptr on renderTrav
01159 CRenderTrav *renderTrav= &ownerScene->getRenderTrav();
01160 // get a ptr on the driver
01161 IDriver *drv= renderTrav->getDriver();
01162 nlassert(drv);
01163
01164
01165 // choose the lod.
01166 float alphaLod;
01167 sint numLod= chooseLod(alphaMRM, alphaLod);
01168
01169
01170 // Render the choosen Lod.
01171 CLod &lod= _Lods[numLod];
01172 if(lod.RdrPass.size()==0)
01173 return;
01174
01175
01176 /*
01177 YOYO: renderSkin() no more support vertexBufferHard()!!! for AGP Memory optimisation concern.
01178 AGP Skin rendering is made when supportSkinGrouping() is true
01179 Hence if a skin is to be rendered here, because it doesn't have a good vertex format, or it has
01180 MeshVertexProgram etc..., it will be rendered WITHOUT VBHard => slower.
01181 */
01182
01183
01184 // get the skeleton model to which I am skinned
01185 CSkeletonModel *skeleton;
01186 skeleton = mi->getSkeletonModel();
01187 // must be skinned for renderSkin()
01188 nlassert(_Skinned && mi->isSkinned() && skeleton);
01189 bool bMorphApplied = _MeshMorpher.BlendShapes.size() > 0;
01190 bool useNormal= (_VBufferFinal.getVertexFormat() & CVertexBuffer::NormalFlag)!=0;
01191 bool useTangentSpace = _MeshVertexProgram && _MeshVertexProgram->needTangentSpace();
01192
01193
01194 // Profiling
01195 //===========
01196 H_AUTO( NL3D_MeshMRMGeom_renderSkin_go );
01197
01198
01199 // Morphing
01200 // ========
01201 if (bMorphApplied)
01202 {
01203 // Since Skinned we must update original skin vertices and normals because skinning use it
01204 _MeshMorpher.initSkinned(&_VBufferOriginal,
01205 &_VBufferFinal,
01206 NULL,
01207 useTangentSpace,
01208 &_OriginalSkinVertices,
01209 &_OriginalSkinNormals,
01210 useTangentSpace ? &_OriginalTGSpace : NULL,
01211 true );
01212 _MeshMorpher.updateSkinned (mi->getBlendShapeFactors());
01213 }
01214
01215 // Skinning.
01216 //===========
01217
01218 // Never use RawSkin. Actually used in skinGrouping.
01219 updateRawSkinNormal(false, mi, numLod);
01220
01221 // applySkin.
01222 //--------
01223
01224 // If skin without normal (rare/usefull?) always simple (slow) case.
01225 if(!useNormal)
01226 {
01227 // skinning with just position
01228 applySkin (lod, skeleton);
01229 }
01230 else
01231 {
01232 // apply skin for this Lod only.
01233 if (!useTangentSpace)
01234 {
01235 // skinning with normal, but no tangent space
01236 applySkinWithNormal (lod, skeleton);
01237 }
01238 else
01239 {
01240 // Tangent space stored in the last texture coordinate
01241 applySkinWithTangentSpace(lod, skeleton, _VBufferFinal.getNumTexCoordUsed() - 1);
01242 }
01243 }
01244
01245 // endSkin.
01246 //--------
01247 // dirt this lod part. (NB: this is not optimal, but sufficient :) ).
01248 lod.OriginalSkinRestored= false;
01249
01250
01251 // NB: the skeleton matrix has already been setuped by CSkeletonModel
01252 // NB: the normalize flag has already been setuped by CSkeletonModel
01253
01254
01255 // Geomorph.
01256 //===========
01257 // Geomorph the choosen Lod (if not the coarser mesh).
01258 if(numLod>0)
01259 {
01260 applyGeomorph(lod.Geomorphs, alphaLod, NULL);
01261 }
01262
01263
01264 // Setup meshVertexProgram
01265 //===========
01266
01267 // use MeshVertexProgram effect?
01268 bool useMeshVP= _MeshVertexProgram != NULL;
01269 if( useMeshVP )
01270 {
01271 CMatrix invertedObjectMatrix;
01272 invertedObjectMatrix = skeleton->getWorldMatrix().inverted();
01273 // really ok if success to begin VP
01274 useMeshVP= _MeshVertexProgram->begin(drv, mi->getOwnerScene(), mi, invertedObjectMatrix, renderTrav->CamPos);
01275 }
01276
01277
01278 // Render the lod.
01279 //===========
01280 // active VB.
01281 drv->activeVertexBuffer(_VBufferFinal);
01282
01283
01284 // Render all pass.
01285 for(uint i=0;i<lod.RdrPass.size();i++)
01286 {
01287 CRdrPass &rdrPass= lod.RdrPass[i];
01288
01289 // CMaterial Ref
01290 CMaterial &material=mi->Materials[rdrPass.MaterialId];
01291
01292 // Setup VP material
01293 if (useMeshVP)
01294 {
01295 _MeshVertexProgram->setupForMaterial(material, drv, ownerScene, &_VBufferFinal);
01296 }
01297
01298 // Render with the Materials of the MeshInstance.
01299 drv->render(rdrPass.PBlock, material);
01300 }
01301
01302 // End VertexProgram effect
01303 if(useMeshVP)
01304 {
01305 // end it.
01306 _MeshVertexProgram->end(drv);
01307 }
01308 }
|
|
||||||||||||||||||||
|
Definition at line 1318 of file mesh_mrm.cpp. References _LastLodComputed, _Lods, NL3D::CMeshMRMInstance::_RawSkinCache, _VBufferFinal, applyRawSkinWithNormal(), NL3D::CMeshMorpher::BlendShapes, chooseLod(), NL3D::CRawSkinNormalCache::Geomorphs, NL3D::CMeshBaseInstance::getBlendShapeFactors(), NL3D::CRenderTrav::getDriver(), NL3D::CTransform::getOwnerScene(), NL3D::CScene::getRenderTrav(), NL3D::CTransform::getSkeletonModel(), NL3D::CVertexBuffer::getVertexFormat(), H_AUTO, NL3D::CTransform::isSkinned(), nlassert, NL3D::CMeshMRMGeom::CLod::NWedges, NL3D::CMeshMRMGeom::CLod::RdrPass, sint, NL3D::CRawSkinNormalCache::TotalHardVertices, NL3D::CRawSkinNormalCache::TotalSoftVertices, uint, uint8, NL3D::CMeshMorpher::updateRawSkin(), updateRawSkinNormal(), and NL3D::CRawSkinNormalCache::VertexRemap. Referenced by NL3D::CMeshMRMInstance::renderSkinGroupGeom().
01319 {
01320 H_AUTO( NL3D_MeshMRMGeom_rdrSkinGrpGeom )
01321
01322 // get a ptr on scene
01323 CScene *ownerScene= mi->getOwnerScene();
01324 // get a ptr on renderTrav
01325 CRenderTrav *renderTrav= &ownerScene->getRenderTrav();
01326 // get a ptr on the driver
01327 IDriver *drv= renderTrav->getDriver();
01328 nlassert(drv);
01329
01330
01331 // choose the lod.
01332 float alphaLod;
01333 sint numLod= chooseLod(alphaMRM, alphaLod);
01334 _LastLodComputed= numLod;
01335
01336
01337 // Render the choosen Lod.
01338 CLod &lod= _Lods[numLod];
01339 if(lod.RdrPass.size()==0)
01340 // return no vertices added
01341 return 0;
01342
01343 // If the Lod is too big to render in the VBufferHard
01344 if(lod.NWedges>remainingVertices)
01345 // return Failure
01346 return -1;
01347
01348 // get the skeleton model to which I am skinned
01349 CSkeletonModel *skeleton;
01350 skeleton = mi->getSkeletonModel();
01351 // must be skinned for renderSkin()
01352 nlassert(_Skinned && mi->isSkinned() && skeleton);
01353 bool bMorphApplied = _MeshMorpher.BlendShapes.size() > 0;
01354 bool useNormal= (_VBufferFinal.getVertexFormat() & CVertexBuffer::NormalFlag)!=0;
01355 nlassert(useNormal);
01356
01357
01358 // Profiling
01359 //===========
01360 H_AUTO( NL3D_MeshMRMGeom_rdrSkinGrpGeom_go );
01361
01362
01363 // Morphing
01364 // ========
01365
01366 // Use RawSkin?. compute before morphing, cause of updateRawSkin
01367 updateRawSkinNormal(true, mi, numLod);
01368 nlassert(mi->_RawSkinCache);
01369
01370 // Apply morph
01371 if (bMorphApplied)
01372 {
01373 // No need to manage lod.OriginalSkinRestored, since in case of SkinGroupGeom, the VBuffer final is not modified.
01374
01375 // copy directly from the original VB, and apply BlendShapes. Dest is directly the RawSkin
01376 _MeshMorpher.updateRawSkin(&_VBufferFinal,
01377 mi->_RawSkinCache->VertexRemap,
01378 mi->getBlendShapeFactors());
01379 }
01380
01381 // Skinning.
01382 //===========
01383
01384 // NB: the skeleton matrix has already been setuped by CSkeletonModel
01385 // NB: the normalize flag has already been setuped by CSkeletonModel
01386
01387 // applySkin with RawSkin.
01388 //--------
01389 // always RawSkin now in SkinGrouping, even with MeshMorpher
01390 {
01391 H_AUTO( NL3D_RawSkinning );
01392
01393 // RawSkin do all the job in optimized way: Skinning, copy to VBHard and Geomorph.
01394
01395 // skinning with normal, but no tangent space
01396 applyRawSkinWithNormal (lod, *(mi->_RawSkinCache), skeleton, vbDest, alphaLod);
01397
01398 // Vertices are packed in RawSkin mode (ie no holes due to MRM!)
01399 return mi->_RawSkinCache->Geomorphs.size() +
01400 mi->_RawSkinCache->TotalSoftVertices +
01401 mi->_RawSkinCache->TotalHardVertices;
01402 }
01403 }
|
|
||||||||||||||||||||
|
Definition at line 1406 of file mesh_mrm.cpp. References _LastLodComputed, _Lods, NL3D::CMeshMRMInstance::_ShiftedTriangleCache, NL3D::CRenderTrav::getDriver(), NL3D::CTransform::getOwnerScene(), NL3D::CScene::getRenderTrav(), NL3D::CMaterial::getShader(), NL3D::CMaterial::getTexture(), NL3D::IDriver::getTextureHandle(), H_AUTO, NL3D::CMeshMRMGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, min, nlassert, NL3D::CShiftedTriangleCache::CRdrPass::NumTriangles, NL3D::CShiftedTriangleCache::RdrPass, NL3D::CMeshMRMGeom::CLod::RdrPass, NL3D::CSkinSpecularRdrPass::RdrPassIndex, NL3D::IDriver::renderTriangles(), NL3D::CSkinSpecularRdrPass::SkinIndex, NL3D::CSkinSpecularRdrPass::SpecId, NL3D::CShiftedTriangleCache::CRdrPass::Triangles, uint, and updateShiftedTriangleCache(). Referenced by NL3D::CMeshMRMInstance::renderSkinGroupPrimitives().
01407 {
01408 H_AUTO( NL3D_MeshMRMGeom_rdrSkinGrpPrimitives );
01409
01410 // get a ptr on scene
01411 CScene *ownerScene= mi->getOwnerScene();
01412 // get a ptr on renderTrav
01413 CRenderTrav *renderTrav= &ownerScene->getRenderTrav();
01414 // get a ptr on the driver
01415 IDriver *drv= renderTrav->getDriver();
01416 nlassert(drv);
01417
01418 // Get the lod choosen in renderSkinGroupGeom()
01419 CLod &lod= _Lods[_LastLodComputed];
01420
01421
01422 // must update primitive cache
01423 updateShiftedTriangleCache(mi, _LastLodComputed, baseVertex);
01424 nlassert(mi->_ShiftedTriangleCache);
01425
01426
01427 // Render Triangles with cache
01428 //===========
01429 for(uint i=0;i<lod.RdrPass.size();i++)
01430 {
01431 CRdrPass &rdrPass= lod.RdrPass[i];
01432
01433 // CMaterial Ref
01434 CMaterial &material=mi->Materials[rdrPass.MaterialId];
01435
01436 // TestYoyo. Material Speed Test
01437 /*if( material.getDiffuse()!=CRGBA(250, 251, 252) )
01438 {
01439 material.setDiffuse(CRGBA(250, 251, 252));
01440 // Set all texture the same.
01441 static CSmartPtr<ITexture> pTexFile= new CTextureFile("fy_hom_visage_c1_fy_e1.tga");
01442 material.setTexture(0, pTexFile );
01443 // Remove Specular.
01444 if(material.getShader()==CMaterial::Specular)
01445 {
01446 CSmartPtr<ITexture> tex= material.getTexture(0);
01447 material.setShader(CMaterial::Normal);
01448 material.setTexture(0, tex );
01449 }
01450 // Remove MakeUp
01451 material.setTexture(1, NULL);
01452 }*/
01453
01454 // If the material is a specular material, don't render it now!
01455 if(material.getShader()==CMaterial::Specular)
01456 {
01457 // Add it to the rdrPass to sort!
01458 CSkinSpecularRdrPass specRdrPass;
01459 specRdrPass.SkinIndex= skinIndex;
01460 specRdrPass.RdrPassIndex= i;
01461 // Get the handle of the specular Map as the sort Key
01462 ITexture *specTex= material.getTexture(1);
01463 if(!specTex)
01464 specRdrPass.SpecId= 0;
01465 else
01466 specRdrPass.SpecId= drv->getTextureHandle( *specTex );
01467 // Append it to the list
01468 specularRdrPasses.push_back(specRdrPass);
01469 }
01470 else
01471 {
01472 // Get the shifted triangles.
01473 CShiftedTriangleCache::CRdrPass &shiftedRdrPass= mi->_ShiftedTriangleCache->RdrPass[i];
01474
01475 // This speed up 4 ms for 80K polys.
01476 uint memToCache= shiftedRdrPass.NumTriangles*12;
01477 memToCache= min(memToCache, 4096U);
01478 CFastMem::precache(shiftedRdrPass.Triangles, memToCache);
01479
01480 // Render with the Materials of the MeshInstance.
01481 drv->renderTriangles(material, shiftedRdrPass.Triangles, shiftedRdrPass.NumTriangles);
01482 }
01483 }
01484 }
|
|
||||||||||||
|
Definition at line 1488 of file mesh_mrm.cpp. References _LastLodComputed, _Lods, NL3D::CMeshMRMInstance::_ShiftedTriangleCache, NL3D::CRenderTrav::getDriver(), NL3D::CTransform::getOwnerScene(), NL3D::CScene::getRenderTrav(), H_AUTO, NL3D::CMeshMRMGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, min, nlassert, NL3D::CShiftedTriangleCache::CRdrPass::NumTriangles, NL3D::CShiftedTriangleCache::RdrPass, NL3D::CMeshMRMGeom::CLod::RdrPass, NL3D::IDriver::renderTriangles(), NL3D::CShiftedTriangleCache::CRdrPass::Triangles, and uint. Referenced by NL3D::CMeshMRMInstance::renderSkinGroupSpecularRdrPass().
01489 {
01490 H_AUTO( NL3D_MeshMRMGeom_rdrSkinGrpSpecularRdrPass );
01491
01492 // get a ptr on scene
01493 CScene *ownerScene= mi->getOwnerScene();
01494 // get a ptr on renderTrav
01495 CRenderTrav *renderTrav= &ownerScene->getRenderTrav();
01496 // get a ptr on the driver
01497 IDriver *drv= renderTrav->getDriver();
01498 nlassert(drv);
01499
01500 // Get the lod choosen in renderSkinGroupGeom()
01501 CLod &lod= _Lods[_LastLodComputed];
01502
01503
01504 // _ShiftedTriangleCache must have been computed in renderSkinGroupPrimitives
01505 nlassert(mi->_ShiftedTriangleCache);
01506
01507
01508 // Render Triangles with cache
01509 //===========
01510 CRdrPass &rdrPass= lod.RdrPass[rdrPassId];
01511
01512 // CMaterial Ref
01513 CMaterial &material=mi->Materials[rdrPass.MaterialId];
01514
01515 // Get the shifted triangles.
01516 CShiftedTriangleCache::CRdrPass &shiftedRdrPass= mi->_ShiftedTriangleCache->RdrPass[rdrPassId];
01517
01518 // This speed up 4 ms for 80K polys.
01519 uint memToCache= shiftedRdrPass.NumTriangles*12;
01520 memToCache= min(memToCache, 4096U);
01521 CFastMem::precache(shiftedRdrPass.Triangles, memToCache);
01522
01523 // Render with the Materials of the MeshInstance.
01524 drv->renderTriangles(material, shiftedRdrPass.Triangles, shiftedRdrPass.NumTriangles);
01525 }
|
|
||||||||||||
|
Skinning: same as restoreOriginalSkinVertices(), but for one Lod only.
Definition at line 2131 of file mesh_mrm.cpp. References _VBufferFinal, NL3D::CVertexBuffer::getNormalOff(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexFormat(), NL3D::CVertexBuffer::getVertexSize(), index, NL3D::CMeshMRMGeom::CLod::InfluencedVertices, NL3D_MESH_SKINNING_MAX_MATRIX, nlassert, NL3D::CMeshMRMGeom::CLod::OriginalSkinRestored, sint32, uint, uint32, and uint8. Referenced by render().
02132 {
02133 nlassert(_Skinned);
02134
02135
02136 /*
02137 YOYO: _Skinned mrms no more support vertexBufferHard
02138 see note in renderSkin()
02139 */
02140
02141 // get vertexPtr / normalOff.
02142 //===========================
02143 uint8 *destVertexPtr= (uint8*)_VBufferFinal.getVertexCoordPointer();
02144 uint flags= _VBufferFinal.getVertexFormat();
02145 sint32 vertexSize= _VBufferFinal.getVertexSize();
02146 // must have XYZ.
02147 nlassert(flags & CVertexBuffer::PositionFlag);
02148
02149 // Compute offset of each component of the VB.
02150 sint32 normalOff;
02151 if(flags & CVertexBuffer::NormalFlag)
02152 normalOff= _VBufferFinal.getNormalOff();
02153 else
02154 normalOff= 0;
02155
02156
02157 // compute src array.
02158 CVector *srcVertexPtr;
02159 CVector *srcNormalPtr= NULL;
02160 srcVertexPtr= &_OriginalSkinVertices[0];
02161 if(normalOff)
02162 srcNormalPtr= &(_OriginalSkinNormals[0]);
02163
02164
02165 // copy skinning.
02166 //===========================
02167 for(uint i=0;i<NL3D_MESH_SKINNING_MAX_MATRIX;i++)
02168 {
02169 uint nInf= lod.InfluencedVertices[i].size();
02170 if( nInf==0 )
02171 continue;
02172 uint32 *infPtr= &(lod.InfluencedVertices[i][0]);
02173
02174 // for all InfluencedVertices only.
02175 for(;nInf>0;nInf--, infPtr++)
02176 {
02177 uint index= *infPtr;
02178 CVector *srcVertex= srcVertexPtr + index;
02179 CVector *srcNormal= srcNormalPtr + index;
02180 uint8 *dstVertexVB= destVertexPtr + index * vertexSize;
02181 CVector *dstVertex= (CVector*)(dstVertexVB);
02182 CVector *dstNormal= (CVector*)(dstVertexVB + normalOff);
02183
02184
02185 // Vertex.
02186 *dstVertex= *srcVertex;
02187 // Normal.
02188 if(normalOff)
02189 *dstNormal= *srcNormal;
02190 }
02191 }
02192
02193
02194 // clean this lod part. (NB: this is not optimal, but sufficient :) ).
02195 lod.OriginalSkinRestored= true;
02196 }
|
|
|
Skinning: restore Vertex/Normal from _OriginalSkin* to VBuffer.
Definition at line 2095 of file mesh_mrm.cpp. References _VBufferFinal, NL3D::CVertexBuffer::getNormalCoordPointer(), NL3D::CVertexBuffer::getNumTexCoordUsed(), NL3D::CVertexBuffer::getNumVertices(), NL3D::CVertexBuffer::getTexCoordPointer(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexFormat(), nlassert, and uint.
02096 {
02097 nlassert(_Skinned);
02098
02099 // Copy VBuffer content into Original vertices normals.
02100 if(_VBufferFinal.getVertexFormat() & CVertexBuffer::PositionFlag)
02101 {
02102 // copy vertices from VBuffer. (NB: unusefull geomorphed vertices are still copied, but doesn't matter).
02103 for(uint i=0; i<_VBufferFinal.getNumVertices();i++)
02104 {
02105 *(CVector*)_VBufferFinal.getVertexCoordPointer(i)= _OriginalSkinVertices[i];
02106 }
02107 }
02108 if(_VBufferFinal.getVertexFormat() & CVertexBuffer::NormalFlag)
02109 {
02110 // copy normals from VBuffer. (NB: unusefull geomorphed normals are still copied, but doesn't matter).
02111 for(uint i=0; i<_VBufferFinal.getNumVertices();i++)
02112 {
02113 *(CVector*)_VBufferFinal.getNormalCoordPointer(i)= _OriginalSkinNormals[i];
02114 }
02115 }
02116 if (_MeshVertexProgram && _MeshVertexProgram->needTangentSpace())
02117 {
02118 uint numTexCoords = _VBufferFinal.getNumTexCoordUsed();
02119 nlassert(numTexCoords >= 2);
02120 nlassert(_OriginalTGSpace.size() == _VBufferFinal.getNumVertices());
02121 // copy tangent space vectors
02122 for(uint i = 0; i < _VBufferFinal.getNumVertices(); ++i)
02123 {
02124 *(CVector*)_VBufferFinal.getTexCoordPointer(i, numTexCoords - 1)= _OriginalTGSpace[i];
02125 }
02126 }
02127 }
|
|
|
save the entire mesh.
Definition at line 1792 of file mesh_mrm.cpp. References nlassert, sint, sint32, uint, and uint32.
01793 {
01794 /*
01795 Version 5:
01796 - Shadow Skinning
01797 Version 4:
01798 - serial SkinWeights per MRM, not per Lod
01799 Version 3:
01800 - Bones names.
01801 Version 2:
01802 - Mesh Vertex Program.
01803 Version 1:
01804 - added blend shapes
01805 Version 0:
01806 - base version.
01807 */
01808 sint ver= f.serialVersion(5);
01809 uint i;
01810
01811 // if >= version 3, serial bones names
01812 f.serialCont (_BonesName);
01813
01814 // Warning, if you have skinned this shape, you can't write it anymore because skinning id have been changed!
01815 nlassert (_BoneIdComputed==false);
01816
01817 // Mesh Vertex Program.
01818 if (ver >= 2)
01819 {
01820 IMeshVertexProgram *mvp= NULL;
01821 mvp= _MeshVertexProgram;
01822 f.serialPolyPtr(mvp);
01823 }
01824
01825 // blend shapes
01826 if (ver >= 1)
01827 f.serial (_MeshMorpher);
01828
01829 // must have good original Skinned Vertex before writing.
01830 if( _Skinned )
01831 {
01832 restoreOriginalSkinVertices();
01833 }
01834
01835
01836 // serial Basic info.
01837 // ==================
01838 f.serial(_Skinned);
01839 f.serial(_BBox);
01840 f.serial(_LevelDetail.MaxFaceUsed);
01841 f.serial(_LevelDetail.MinFaceUsed);
01842 f.serial(_LevelDetail.DistanceFinest);
01843 f.serial(_LevelDetail.DistanceMiddle);
01844 f.serial(_LevelDetail.DistanceCoarsest);
01845 f.serial(_LevelDetail.OODistanceDelta);
01846 f.serial(_LevelDetail.DistancePow);
01847 f.serialCont(_LodInfos);
01848
01849 // save number of wedges.
01850 uint32 nWedges;
01851 nWedges= _VBufferFinal.getNumVertices();
01852 f.serial(nWedges);
01853 // Save the VBuffer header.
01854 _VBufferFinal.serialHeader(f);
01855
01856
01857 // If new version, serial SkinWeights in header, not in lods.
01858 if(ver >= 4)
01859 {
01860 f.serialCont(_SkinWeights);
01861 }
01862
01863 // if >= version 5, serial Shadow Skin Information
01864 if(ver>=5)
01865 {
01866 f.serialCont (_ShadowSkinVertices);
01867 f.serialCont (_ShadowSkinTriangles);
01868 }
01869
01870 // Serial lod offsets.
01871 // ==================
01872 // This is the reference pos, to load / save relative offsets.
01873 sint32 startPos = f.getPos();
01874 // Those are the lodOffsets, relative to startPos.
01875 vector<sint32> lodOffsets;
01876 lodOffsets.resize(_LodInfos.size(), 0);
01877
01878 // write all dummy offset. For now (since we don't know what to set), compute the offset of
01879 // the sint32 to come back in serial lod parts below.
01880 for(i=0;i<_LodInfos.size(); i++)
01881 {
01882 lodOffsets[i]= f.getPos();
01883 f.serial(lodOffsets[i]);
01884 }
01885
01886 // Serial lod subsets.
01887 // ==================
01888
01889 // Save all the lods.
01890 for(i=0;i<_LodInfos.size(); i++)
01891 {
01892 // get current absolute position.
01893 sint32 absCurPos= f.getPos();
01894
01895 // come back to "relative lodOffset" absolute position in the stream. (temp stored in lodOffset[i]).
01896 f.seek(lodOffsets[i], IStream::begin);
01897
01898 // write the relative position of the lod to the stream.
01899 sint32 relCurPos= absCurPos - startPos;
01900 f.serial(relCurPos);
01901
01902 // come back to absCurPos, to save the lod.
01903 f.seek(absCurPos, IStream::begin);
01904
01905 // And so now, save the lod.
01906 // write the lod face data.
01907 f.serial(_Lods[i]);
01908 // write the lod vertex data.
01909 serialLodVertexData(f, _LodInfos[i].StartAddWedge, _LodInfos[i].EndAddWedges);
01910 }
01911
01912
01913 }
|
|
|
serial this meshGeom.
Implements NLMISC::IStreamable. Definition at line 1613 of file mesh_mrm.cpp.
|
|
||||||||||||||||
|
serial a subset of the vertices.
Definition at line 1918 of file mesh_mrm.cpp. References _SkinWeights, _VBufferFinal, bkupOriginalSkinVerticesSubset(), NLMISC::IStream::isReading(), NLMISC::IStream::serial(), NL3D::CVertexBuffer::serialSubset(), NLMISC::IStream::serialVersion(), sint, and uint. Referenced by loadFirstLod(), and loadNextLod().
01919 {
01920 /*
01921 Version 1:
01922 - serial SkinWeights per MRM, not per Lod
01923 */
01924 sint ver= f.serialVersion(1);
01925
01926 // VBuffer part.
01927 _VBufferFinal.serialSubset(f, startWedge, endWedge);
01928
01929 // SkinWeights.
01930 if(_Skinned)
01931 {
01932 // Serialize SkinWeight per lod only for old versions.
01933 if(ver<1)
01934 {
01935 for(uint i= startWedge; i<endWedge; i++)
01936 {
01937 f.serial(_SkinWeights[i]);
01938 }
01939 }
01940 // if reading, must copy original vertices from VB.
01941 if( f.isReading())
01942 {
01943 bkupOriginalSkinVerticesSubset(startWedge, endWedge);
01944 }
01945 }
01946 }
|
|
||||||||||||
|
Setup the ShadowMesh.
Definition at line 3359 of file mesh_mrm.cpp. References _ShadowSkinTriangles, _ShadowSkinVertices, _SupportShadowSkinGrouping, NL3D_SHADOW_MESH_SKIN_MANAGER_MAXVERTICES, and NL3D_SHADOW_MESH_SKIN_MANAGER_VERTEXFORMAT.
03360 {
03361 _ShadowSkinVertices= shadowVertices;
03362 _ShadowSkinTriangles= triangles;
03363 // update flag. Support Shadow SkinGrouping if Shadow setuped, and if not too many vertices.
03364 _SupportShadowSkinGrouping= !_ShadowSkinVertices.empty() &&
03365 NL3D_SHADOW_MESH_SKIN_MANAGER_VERTEXFORMAT==CVertexBuffer::PositionFlag &&
03366 _ShadowSkinVertices.size() <= NL3D_SHADOW_MESH_SKIN_MANAGER_MAXVERTICES;
03367 }
|
|
|
true if the sort criterion must be by material. Else, sort per instance. Implements NL3D::IMeshGeom. Definition at line 2687 of file mesh_mrm.cpp.
02688 {
02689 // Can't do it per material since 2 lods may not have the same number of RdrPass!!
02690 return false;
02691 }
|
|
|
true if this meshGeom support meshBlock rendering. return false if skinned/meshMorphed. Implements NL3D::IMeshGeom. Definition at line 2673 of file mesh_mrm.cpp. Referenced by profileSceneRender(), and NL3D::CMeshMRM::supportMeshBlockRendering().
02674 {
02675 /*
02676 Yoyo: Don't Support It for MRM because too Slow!!
02677 The problem is that lock() unlock() on each instance, on the same VBHeap IS AS SLOWER AS
02678 VB switching.
02679
02680 TODO_OPTIMIZE: find a way to optimize MRM.
02681 */
02682 return false;
02683 //return _SupportMeshBlockRendering;
02684 }
|
|
|
Render the ShadowSkin (SkinGroup like).
Definition at line 325 of file mesh_mrm.h. References _SupportShadowSkinGrouping. Referenced by NL3D::CMeshMRMInstance::supportShadowSkinGrouping().
00325 {return _SupportShadowSkinGrouping;}
|
|
|
Definition at line 1312 of file mesh_mrm.cpp. References _SupportSkinGrouping. Referenced by NL3D::CMeshMRMInstance::supportSkinGrouping().
01313 {
01314 return _SupportSkinGrouping;
01315 }
|
|
|
UnLoad Lod getNbLodLoaded()-1 from memory. use getNbLodLoaded()-1 to know what Lod will be unloaded. NB: if getNbLodLoaded() <= 1, no op. Definition at line 2029 of file mesh_mrm.cpp. References _Lods, _NbLodLoaded, and getNbLodLoaded().
02030 {
02031 // If just first lod remain (or no lod), quit
02032 if(getNbLodLoaded() <= 1)
02033 return;
02034
02035 // Reset the entire Lod object. (Free Memory).
02036 contReset(_Lods[_NbLodLoaded-1]);
02037
02038
02039 // Dec LodLoaded count.
02040 _NbLodLoaded--;
02041 }
|
|
||||||||||||||||
|
compute RawSkin info in the MRMInstance according to current skin setup.
Definition at line 3060 of file mesh_mrm.cpp. References _Lods, _MeshDataId, NL3D::CMeshMRMInstance::_RawSkinCache, _SkinWeights, _VBufferFinal, NL3D::CMeshMorpher::BlendShapes, NL3D::CRawSkinNormalCache::clearArrays(), NL3D::CMeshMRMInstance::clearRawSkinCache(), NL3D::CRawSkinNormalCache::Geomorphs, NL3D::CMeshMRMGeom::CLod::Geomorphs, NL3D::CVertexBuffer::getNumVertices(), NL3D::CVertexBuffer::getTexCoordPointer(), H_AUTO, NL3D::CRawSkinNormalCache::HardVertices, NL3D::CMeshMRMGeom::CLod::InfluencedVertices, NL3D::CRawSkinNormalCache::LodId, NL3D::CRawSkinNormalCache::MeshDataId, NL3D_MESH_SKINNING_MAX_MATRIX, nlassert, NL3D::CMeshMRMGeom::CLod::RdrPass, NL3D::CRawSkinNormalCache::RdrPass, NLMISC::CObjectVector< CRawSkinVertex *, false >::resize(), NLMISC::CObjectVector< CRawVertexNormalSkin4, false >::resize(), NLMISC::CObjectVector< CRawVertexNormalSkin3, false >::resize(), NLMISC::CObjectVector< CRawVertexNormalSkin2, false >::resize(), NLMISC::CObjectVector< CRawVertexNormalSkin1, false >::resize(), sint, NLMISC::CObjectVector< CRawVertexNormalSkin4, false >::size(), NLMISC::CObjectVector< CRawVertexNormalSkin3, false >::size(), NLMISC::CObjectVector< CRawVertexNormalSkin2, false >::size(), NLMISC::CObjectVector< CRawVertexNormalSkin1, false >::size(), NL3D::CRawSkinNormalCache::SoftVertices, NL3D::CRawSkinNormalCache::TotalHardVertices, NL3D::CRawSkinNormalCache::TotalSoftVertices, uint, uint32, NL3D::CRawSkinNormalCache::VertexRemap, NL3D::CRawSkinNormalCache::Vertices1, NL3D::CRawSkinNormalCache::Vertices2, NL3D::CRawSkinNormalCache::Vertices3, and NL3D::CRawSkinNormalCache::Vertices4. Referenced by renderSkin(), and renderSkinGroupGeom().
03061 {
03062 if(!enabled)
03063 {
03064 // if the instance cache is not cleared, must clear.
03065 if(mi->_RawSkinCache)
03066 mi->clearRawSkinCache();
03067 }
03068 else
03069 {
03070 // If the instance has no RawSkin, or has a too old RawSkin cache, must delete it, and recreate
03071 if( !mi->_RawSkinCache || mi->_RawSkinCache->MeshDataId!=_MeshDataId)
03072 {
03073 // first delete if too old.
03074 if(mi->_RawSkinCache)
03075 mi->clearRawSkinCache();
03076 // Then recreate, and use _MeshDataId to verify that the instance works with same data.
03077 mi->_RawSkinCache= new CRawSkinNormalCache;
03078 mi->_RawSkinCache->MeshDataId= _MeshDataId;
03079 mi->_RawSkinCache->LodId= -1;
03080 }
03081
03082
03083 /* If the instance rawSkin has a different Lod (or if -1), then must recreate it.
03084 NB: The lod may change each frame per instance, but suppose not so many change, so we can cache those data.
03085 */
03086 if( mi->_RawSkinCache->LodId != curLodId )
03087 {
03088 H_AUTO( NL3D_CMeshMRMGeom_updateRawSkinNormal );
03089
03090 CRawSkinNormalCache &skinLod= *mi->_RawSkinCache;
03091 CLod &lod= _Lods[curLodId];
03092 uint i;
03093 sint rawIdx;
03094
03095 // Clear the raw skin mesh.
03096 skinLod.clearArrays();
03097
03098 // Cache this lod
03099 mi->_RawSkinCache->LodId= curLodId;
03100
03101 // For each matrix influence.
03102 nlassert(NL3D_MESH_SKINNING_MAX_MATRIX==4);
03103
03104 // For each vertex, acknowledge if it is a src for geomorph.
03105 static vector<uint8> softVertices;
03106 softVertices.clear();
03107 softVertices.resize( _VBufferFinal.getNumVertices(), 0 );
03108 for(i=0;i<lod.Geomorphs.size();i++)
03109 {
03110 softVertices[lod.Geomorphs[i].Start]= 1;
03111 softVertices[lod.Geomorphs[i].End]= 1;
03112 }
03113
03114 // The remap from old index in _VBufferFinal to RawSkin vertices (without Geomorphs).
03115 static vector<uint32> vertexRemap;
03116 vertexRemap.resize( _VBufferFinal.getNumVertices() );
03117 sint softSize[4];
03118 sint hardSize[4];
03119 sint softStart[4];
03120 sint hardStart[4];
03121 // count vertices
03122 skinLod.TotalSoftVertices= 0;
03123 skinLod.TotalHardVertices= 0;
03124 for(i=0;i<4;i++)
03125 {
03126 softSize[i]= 0;
03127 hardSize[i]= 0;
03128 // Count.
03129 for(uint j=0;j<lod.InfluencedVertices[i].size();j++)
03130 {
03131 uint vid= lod.InfluencedVertices[i][j];
03132 if(softVertices[vid])
03133 softSize[i]++;
03134 else
03135 hardSize[i]++;
03136 }
03137 skinLod.TotalSoftVertices+= softSize[i];
03138 skinLod.TotalHardVertices+= hardSize[i];
03139 skinLod.SoftVertices[i]= softSize[i];
03140 skinLod.HardVertices[i]= hardSize[i];
03141 }
03142 // compute offsets
03143 softStart[0]= 0;
03144 hardStart[0]= skinLod.TotalSoftVertices;
03145 for(i=1;i<4;i++)
03146 {
03147 softStart[i]= softStart[i-1]+softSize[i-1];
03148 hardStart[i]= hardStart[i-1]+hardSize[i-1];
03149 }
03150 // compute remap
03151 for(i=0;i<4;i++)
03152 {
03153 uint softIdx= softStart[i];
03154 uint hardIdx= hardStart[i];
03155 for(uint j=0;j<lod.InfluencedVertices[i].size();j++)
03156 {
03157 uint vid= lod.InfluencedVertices[i][j];
03158 if(softVertices[vid])
03159 vertexRemap[vid]= softIdx++;
03160 else
03161 vertexRemap[vid]= hardIdx++;
03162 }
03163 }
03164
03165
03166 // Resize the dest array.
03167 skinLod.Vertices1.resize(lod.InfluencedVertices[0].size());
03168 skinLod.Vertices2.resize(lod.InfluencedVertices[1].size());
03169 skinLod.Vertices3.resize(lod.InfluencedVertices[2].size());
03170 skinLod.Vertices4.resize(lod.InfluencedVertices[3].size());
03171
03172 // Remap for BlendShape. Lasts 2 bits tells what RawSkin Array to seek (1 to 4),
03173 // low Bits indicate the number in them. 0xFFFFFFFF is a special value indicating "NotUsed in this lod"
03174 static vector<uint32> vertexFinalRemap;
03175 vertexFinalRemap.clear();
03176 vertexFinalRemap.resize(vertexRemap.size(), 0xFFFFFFFF);
03177
03178 // 1 Matrix skinning.
03179 //========
03180 for(i=0;i<skinLod.Vertices1.size();i++)
03181 {
03182 // get the dest vertex.
03183 uint vid= lod.InfluencedVertices[0][i];
03184 // where to store?
03185 rawIdx= vertexRemap[vid];
03186 if(softVertices[vid])
03187 rawIdx-= softStart[0];
03188 else
03189 rawIdx+= softSize[0]-hardStart[0];
03190 // for BlendShapes remapping
03191 vertexFinalRemap[vid]= (0<<30) + rawIdx;
03192 // fill raw struct
03193 skinLod.Vertices1[rawIdx].MatrixId[0]= _SkinWeights[vid].MatrixId[0];
03194 skinLod.Vertices1[rawIdx].Vertex.Pos= _OriginalSkinVertices[vid];
03195 skinLod.Vertices1[rawIdx].Vertex.Normal= _OriginalSkinNormals[vid];
03196 skinLod.Vertices1[rawIdx].Vertex.UV= *(CUV*)_VBufferFinal.getTexCoordPointer(vid);
03197 }
03198
03199 // 2 Matrix skinning.
03200 //========
03201 for(i=0;i<skinLod.Vertices2.size();i++)
03202 {
03203 // get the dest vertex.
03204 uint vid= lod.InfluencedVertices[1][i];
03205 // where to store?
03206 rawIdx= vertexRemap[vid];
03207 if(softVertices[vid])
03208 rawIdx-= softStart[1];
03209 else
03210 rawIdx+= softSize[1]-hardStart[1];
03211 // for BlendShapes remapping
03212 vertexFinalRemap[vid]= (1<<30) + rawIdx;
03213 // fill raw struct
03214 skinLod.Vertices2[rawIdx].MatrixId[0]= _SkinWeights[vid].MatrixId[0];
03215 skinLod.Vertices2[rawIdx].MatrixId[1]= _SkinWeights[vid].MatrixId[1];
03216 skinLod.Vertices2[rawIdx].Weights[0]= _SkinWeights[vid].Weights[0];
03217 skinLod.Vertices2[rawIdx].Weights[1]= _SkinWeights[vid].Weights[1];
03218 skinLod.Vertices2[rawIdx].Vertex.Pos= _OriginalSkinVertices[vid];
03219 skinLod.Vertices2[rawIdx].Vertex.Normal= _OriginalSkinNormals[vid];
03220 skinLod.Vertices2[rawIdx].Vertex.UV= *(CUV*)_VBufferFinal.getTexCoordPointer(vid);
03221 }
03222
03223 // 3 Matrix skinning.
03224 //========
03225 for(i=0;i<skinLod.Vertices3.size();i++)
03226 {
03227 // get the dest vertex.
03228 uint vid= lod.InfluencedVertices[2][i];
03229 // where to store?
03230 rawIdx= vertexRemap[vid];
03231 if(softVertices[vid])
03232 rawIdx-= softStart[2];
03233 else
03234 rawIdx+= softSize[2]-hardStart[2];
03235 // for BlendShapes remapping
03236 vertexFinalRemap[vid]= (2<<30) + rawIdx;
03237 // fill raw struct
03238 skinLod.Vertices3[rawIdx].MatrixId[0]= _SkinWeights[vid].MatrixId[0];
03239 skinLod.Vertices3[rawIdx].MatrixId[1]= _SkinWeights[vid].MatrixId[1];
03240 skinLod.Vertices3[rawIdx].MatrixId[2]= _SkinWeights[vid].MatrixId[2];
03241 skinLod.Vertices3[rawIdx].Weights[0]= _SkinWeights[vid].Weights[0];
03242 skinLod.Vertices3[rawIdx].Weights[1]= _SkinWeights[vid].Weights[1];
03243 skinLod.Vertices3[rawIdx].Weights[2]= _SkinWeights[vid].Weights[2];
03244 skinLod.Vertices3[rawIdx].Vertex.Pos= _OriginalSkinVertices[vid];
03245 skinLod.Vertices3[rawIdx].Vertex.Normal= _OriginalSkinNormals[vid];
03246 skinLod.Vertices3[rawIdx].Vertex.UV= *(CUV*)_VBufferFinal.getTexCoordPointer(vid);
03247 }
03248
03249 // 4 Matrix skinning.
03250 //========
03251 for(i=0;i<skinLod.Vertices4.size();i++)
03252 {
03253 // get the dest vertex.
03254 uint vid= lod.InfluencedVertices[3][i];
03255 // where to store?
03256 rawIdx= vertexRemap[vid];
03257 if(softVertices[vid])
03258 rawIdx-= softStart[3];
03259 else
03260 rawIdx+= softSize[3]-hardStart[3];
03261 // for BlendShapes remapping
03262 vertexFinalRemap[vid]= (3<<30) + rawIdx;
03263 // fill raw struct
03264 skinLod.Vertices4[rawIdx].MatrixId[0]= _SkinWeights[vid].MatrixId[0];
03265 skinLod.Vertices4[rawIdx].MatrixId[1]= _SkinWeights[vid].MatrixId[1];
03266 skinLod.Vertices4[rawIdx].MatrixId[2]= _SkinWeights[vid].MatrixId[2];
03267 skinLod.Vertices4[rawIdx].MatrixId[3]= _SkinWeights[vid].MatrixId[3];
03268 skinLod.Vertices4[rawIdx].Weights[0]= _SkinWeights[vid].Weights[0];
03269 skinLod.Vertices4[rawIdx].Weights[1]= _SkinWeights[vid].Weights[1];
03270 skinLod.Vertices4[rawIdx].Weights[2]= _SkinWeights[vid].Weights[2];
03271 skinLod.Vertices4[rawIdx].Weights[3]= _SkinWeights[vid].Weights[3];
03272 skinLod.Vertices4[rawIdx].Vertex.Pos= _OriginalSkinVertices[vid];
03273 skinLod.Vertices4[rawIdx].Vertex.Normal= _OriginalSkinNormals[vid];
03274 skinLod.Vertices4[rawIdx].Vertex.UV= *(CUV*)_VBufferFinal.getTexCoordPointer(vid);
03275 }
03276
03277 // Remap Geomorphs.
03278 //========
03279 uint numGeoms= lod.Geomorphs.size();
03280 skinLod.Geomorphs.resize( numGeoms );
03281 for(i=0;i<numGeoms;i++)
03282 {
03283 // NB: don't add "numGeoms" to the index because RawSkin look in a TempArray in RAM, wich start at 0...
03284 skinLod.Geomorphs[i].Start= vertexRemap[lod.Geomorphs[i].Start];
03285 skinLod.Geomorphs[i].End= vertexRemap[lod.Geomorphs[i].End];
03286 }
03287
03288 // Remap RdrPass.
03289 //========
03290 skinLod.RdrPass.resize(lod.RdrPass.size());
03291 for(i=0;i<skinLod.RdrPass.size();i++)
03292 {
03293 // NB: since RawSkin is possible only with SkinGrouping, and since SkniGrouping is
03294 // possible only with no Quads/Lines, we should have only Tris here.
03295 nlassert( lod.RdrPass[i].PBlock.getNumQuad()== 0);
03296 nlassert( lod.RdrPass[i].PBlock.getNumLine()== 0);
03297 // remap tris.
03298 skinLod.RdrPass[i].setNumTri(lod.RdrPass[i].PBlock.getNumTri());
03299 uint32 *srcTriPtr= lod.RdrPass[i].PBlock.getTriPointer();
03300 uint32 *dstTriPtr= skinLod.RdrPass[i].getTriPointer();
03301 uint32 numIndices= lod.RdrPass[i].PBlock.getNumTri()*3;
03302 for(uint j=0;j<numIndices;j++, srcTriPtr++, dstTriPtr++)
03303 {
03304 uint vid= *srcTriPtr;
03305 // If this index refers to a Geomorphed vertex, don't modify!
03306 if(vid<numGeoms)
03307 *dstTriPtr= vid;
03308 else
03309 *dstTriPtr= vertexRemap[vid] + numGeoms;
03310 }
03311 }
03312
03313 // Case of MeshMorpher
03314 //========
03315 if(_MeshMorpher.BlendShapes.size()>0)
03316 {
03317 skinLod.VertexRemap.resize(vertexFinalRemap.size());
03318
03319 for(i=0;i<vertexFinalRemap.size();i++)
03320 {
03321 uint vfr= vertexFinalRemap[i];
03322 if(vfr!=0xFFFFFFFF)
03323 {
03324 uint rsArrayId= vfr >> 30;
03325 uint rsIndex= vfr & ((1<<30)-1);
03326 switch(rsArrayId)
03327 {
03328 case 0:
03329 skinLod.VertexRemap[i]= &skinLod.Vertices1[rsIndex].Vertex;
03330 break;
03331 case 1:
03332 skinLod.VertexRemap[i]= &skinLod.Vertices2[rsIndex].Vertex;
03333 break;
03334 case 2:
03335 skinLod.VertexRemap[i]= &skinLod.Vertices3[rsIndex].Vertex;
03336 break;
03337 case 3:
03338 skinLod.VertexRemap[i]= &skinLod.Vertices4[rsIndex].Vertex;
03339 break;
03340 };
03341 }
03342 else
03343 skinLod.VertexRemap[i]= NULL;
03344 }
03345 }
03346 }
03347 }
03348 }
|
|
||||||||||||||||
|
Definition at line 1529 of file mesh_mrm.cpp. References _Lods, _MeshDataId, NL3D::CMeshMRMInstance::_RawSkinCache, NL3D::CMeshMRMInstance::_ShiftedTriangleCache, NL3D::CShiftedTriangleCache::BaseVertex, NL3D::CMeshMRMInstance::clearShiftedTriangleCache(), NLMISC::CObjectVector< uint32, false >::getPtr(), NL3D::CShiftedTriangleCache::LodId, NL3D::CShiftedTriangleCache::MeshDataId, NL3D::CShiftedTriangleCache::CRdrPass::NumTriangles, NL3D::CShiftedTriangleCache::RawIndices, NL3D::CShiftedTriangleCache::RdrPass, NL3D::CMeshMRMGeom::CLod::RdrPass, NL3D::CRawSkinNormalCache::RdrPass, NLMISC::CObjectVector< uint32, false >::resize(), NLMISC::CObjectVector< CRdrPass, false >::resize(), sint, NL3D::CShiftedTriangleCache::CRdrPass::Triangles, uint, and uint32. Referenced by renderSkinGroupPrimitives().
01530 {
01531 // if the instance has a cache, but not sync to us, delete it.
01532 if( mi->_ShiftedTriangleCache && (
01533 mi->_ShiftedTriangleCache->MeshDataId != _MeshDataId ||
01534 mi->_ShiftedTriangleCache->LodId != curLodId ||
01535 mi->_ShiftedTriangleCache->BaseVertex != baseVertex) )
01536 {
01537 mi->clearShiftedTriangleCache();
01538 }
01539
01540 // If the instance has not a valid cache, must create it.
01541 if( !mi->_ShiftedTriangleCache )
01542 {
01543 mi->_ShiftedTriangleCache= new CShiftedTriangleCache;
01544 // Fill the cache Key.
01545 mi->_ShiftedTriangleCache->MeshDataId= _MeshDataId;
01546 mi->_ShiftedTriangleCache->LodId= curLodId;
01547 mi->_ShiftedTriangleCache->BaseVertex= baseVertex;
01548
01549 // Build list of PBlock. From Lod, or from RawSkin cache.
01550 static vector<CPrimitiveBlock*> pbList;
01551 pbList.clear();
01552 if(mi->_RawSkinCache)
01553 {
01554 pbList.resize(mi->_RawSkinCache->RdrPass.size());
01555 for(uint i=0;i<pbList.size();i++)
01556 {
01557 pbList[i]= &mi->_RawSkinCache->RdrPass[i];
01558 }
01559 }
01560 else
01561 {
01562 CLod &lod= _Lods[curLodId];
01563 pbList.resize(lod.RdrPass.size());
01564 for(uint i=0;i<pbList.size();i++)
01565 {
01566 pbList[i]= &lod.RdrPass[i].PBlock;
01567 }
01568 }
01569
01570 // Build RdrPass
01571 mi->_ShiftedTriangleCache->RdrPass.resize(pbList.size());
01572
01573 // First pass, count number of triangles, and fill header info
01574 uint totalTri= 0;
01575 uint i;
01576 for(i=0;i<pbList.size();i++)
01577 {
01578 mi->_ShiftedTriangleCache->RdrPass[i].NumTriangles= pbList[i]->getNumTri();
01579 totalTri+= pbList[i]->getNumTri();
01580 }
01581
01582 // Allocate triangles indices.
01583 mi->_ShiftedTriangleCache->RawIndices.resize(totalTri*3);
01584 uint32 *rawPtr= mi->_ShiftedTriangleCache->RawIndices.getPtr();
01585
01586 // Second pass, fill ptrs, and fill Arrays
01587 uint indexTri= 0;
01588 for(i=0;i<pbList.size();i++)
01589 {
01590 CShiftedTriangleCache::CRdrPass &dstRdrPass= mi->_ShiftedTriangleCache->RdrPass[i];
01591 dstRdrPass.Triangles= rawPtr + indexTri*3;
01592
01593 // Fill the array
01594 uint numTris= pbList[i]->getNumTri();
01595 if(numTris)
01596 {
01597 uint nIds= numTris*3;
01598 // index, and fill
01599 uint32 *pSrcTri= pbList[i]->getTriPointer();
01600 uint32 *pDstTri= dstRdrPass.Triangles;
01601 for(;nIds>0;nIds--,pSrcTri++,pDstTri++)
01602 *pDstTri= *pSrcTri + baseVertex;
01603 }
01604
01605 // Next
01606 indexTri+= dstRdrPass.NumTriangles;
01607 }
01608 }
01609 }
|
|
||||||||||||
|
update Skeleton Usage. increment or decrement. computeBonesId must has been called before.
Definition at line 2535 of file mesh_mrm.cpp. References NL3D::CSkeletonModel::Bones, NL3D::CSkeletonModel::decBoneUsage(), NL3D::CSkeletonModel::incBoneUsage(), nlerror, and uint. Referenced by NL3D::CMeshMRM::updateSkeletonUsage().
02536 {
02537 // For all Bones used.
02538 for(uint i=0; i<_BonesIdExt.size();i++)
02539 {
02540 uint boneId= _BonesIdExt[i];
02541 // Some explicit Error.
02542 if(boneId>=sm->Bones.size())
02543 nlerror(" Skin is incompatible with Skeleton: tries to use bone %d", boneId);
02544 // increment or decrement not Forced, because CMeshGeom use getActiveBoneSkinMatrix().
02545 if(increment)
02546 sm->incBoneUsage(boneId, CSkeletonModel::UsageNormal);
02547 else
02548 sm->decBoneUsage(boneId, CSkeletonModel::UsageNormal);
02549 }
02550 }
|
|
||||||||||||
|
Definition at line 2224 of file mesh_mrm.cpp. References _VBufferFinal, 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(), NL3D::IDriver::supportVertexBufferHard(), and uint32. Referenced by beginMesh(), and render().
02225 {
02226 if(!drv->supportVertexBufferHard() || numVertices==0)
02227 return;
02228
02229
02239 bool avoidVBHard;
02240 avoidVBHard= _Skinned || ( _MeshMorpher.BlendShapes.size()>0 && drv->slowUnlockVertexBufferHard() );
02241 if( _VertexBufferHardDirty && avoidVBHard )
02242 {
02243 // delete possible old VBHard.
02244 if(_VBHard!=NULL)
02245 {
02246 // VertexBufferHard lifetime < Driver lifetime.
02247 nlassert(_Driver!=NULL);
02248 _Driver->deleteVertexBufferHard(_VBHard);
02249 }
02250 return;
02251 }
02252
02253
02254 // If the vbufferhard is not here, or if dirty, or if do not have enough vertices.
02255 if(_VBHard==NULL || _VertexBufferHardDirty || _VBHard->getNumVertices() < numVertices)
02256 {
02257 _VertexBufferHardDirty= false;
02258
02259 // delete possible old _VBHard.
02260 if(_VBHard!=NULL)
02261 {
02262 // VertexBufferHard lifetime < Driver lifetime.
02263 nlassert(_Driver!=NULL);
02264 _Driver->deleteVertexBufferHard(_VBHard);
02265 }
02266
02267 // bkup drv in a refptr. (so we know if the vbuffer hard has to be deleted).
02268 _Driver= drv;
02269 // try to create new one, in AGP Ram
02270 _VBHard= _Driver->createVertexBufferHard(_VBufferFinal.getVertexFormat(), _VBufferFinal.getValueTypePointer (), numVertices, IDriver::VBHardAGP, _VBufferFinal.getUVRouting());
02271
02272
02273 // If KO, use normal VertexBuffer, else, Fill it with VertexBuffer.
02274 if(_VBHard!=NULL)
02275 {
02276 void *vertexPtr= _VBHard->lock();
02277
02278 nlassert(_VBufferFinal.getVertexFormat() == _VBHard->getVertexFormat());
02279 nlassert(_VBufferFinal.getNumVertices() >= numVertices);
02280 nlassert(_VBufferFinal.getVertexSize() == _VBHard->getVertexSize());
02281
02282 // \todo yoyo: TODO_DX8 and DX8 ???
02283 // Because same internal format, just copy all block.
02284 memcpy(vertexPtr, _VBufferFinal.getVertexCoordPointer(), numVertices * _VBufferFinal.getVertexSize() );
02285
02286 _VBHard->unlock();
02287 }
02288 }
02289
02290 }
|
|
|
Definition at line 416 of file mesh_mrm.h. |
|
|
Definition at line 333 of file mesh_mrm.h. |
|
|
For clipping. this is the BB of all vertices of all Lods.
Definition at line 515 of file mesh_mrm.h. |
|
|
This boolean is true if the bones id have been passed in the skeleton.
Definition at line 493 of file mesh_mrm.h. |
|
|
true if the _BonesIdExt have been computed (for bone Usage).
Definition at line 495 of file mesh_mrm.h. |
|
|
This array give the index in the skeleton of the local bones used. computed at first computeBoneId().
Definition at line 506 of file mesh_mrm.h. |
|
|
Same as _BonesId but with parent of bones added. (used for bone usage).
Definition at line 508 of file mesh_mrm.h. |
|
|
This array give the name of the local bones.
Definition at line 504 of file mesh_mrm.h. |
|
|
see CTransform::getSkinBoneSphere() doc for the meaning of this value
Definition at line 510 of file mesh_mrm.h. Referenced by computeBonesId(), and getSkinBoneSphere(). |
|
|
Definition at line 534 of file mesh_mrm.h. |
|
|
Last lod rendered. used with renderSkinGroup*() only.
Definition at line 501 of file mesh_mrm.h. Referenced by renderSkinGroupGeom(), renderSkinGroupPrimitives(), and renderSkinGroupSpecularRdrPass(). |
|
|
Definition at line 525 of file mesh_mrm.h. Referenced by activeInstance(), build(), changeMRMDistanceSetup(), getLevelDetail(), getNumTriangles(), profileSceneRender(), and render(). |
|
|
Info for pre-loading Lods.
Definition at line 519 of file mesh_mrm.h. Referenced by build(), loadFirstLod(), and loadNextLod(). |
|
|
|
BeginMesh setup.
Definition at line 562 of file mesh_mrm.h. Referenced by beginMesh(), and endMesh(). |
|
|
global setup at activateInstance()
Definition at line 564 of file mesh_mrm.h. Referenced by activeInstance(), CMeshMRMGeom(), getNumRdrPassesForInstance(), and renderPass(). |
|
|
Each time the mesh is loaded/built, this increment.
Definition at line 639 of file mesh_mrm.h. Referenced by CMeshMRMGeom(), dirtMeshDataId(), updateRawSkinNormal(), and updateShiftedTriangleCache(). |
|
|
Definition at line 552 of file mesh_mrm.h. |
|
|
Definition at line 555 of file mesh_mrm.h. |
|
|
Definition at line 520 of file mesh_mrm.h. Referenced by build(), chooseLod(), CMeshMRMGeom(), getNbLodLoaded(), loadFirstLod(), loadNextLod(), and unloadNextLod(). |
|
|
Definition at line 481 of file mesh_mrm.h. |
|
|
Skinning: this is the list of vertices (mirror of VBuffer), at the bind Pos.
Definition at line 480 of file mesh_mrm.h. |
|
|
Definition at line 482 of file mesh_mrm.h. |
|
|
NB: HERE FOR PACKING ONLY. For clipping. Estimate if we must do a Precise clipping (ie with bboxes).
Definition at line 538 of file mesh_mrm.h. |
|
|
Definition at line 571 of file mesh_mrm.h. Referenced by renderShadowSkinPrimitives(), and setShadowMesh(). |
|
|
Definition at line 570 of file mesh_mrm.h. Referenced by compileRunTime(), computeBonesId(), getNumShadowSkinVertices(), renderShadowSkinGeom(), and setShadowMesh(). |
|
|
Skinning: This tells if the mesh is correctly skinned (suuport skinning).
Definition at line 478 of file mesh_mrm.h. |
|
|
This is the array of SkinWeights, same size as the VB.
Definition at line 490 of file mesh_mrm.h. Referenced by applySkin(), build(), buildBoneUsageVer2(), computeBonesId(), getSkinWeights(), serialLodVertexData(), and updateRawSkinNormal(). |
|
|
setuped at compileRunTime.
Definition at line 560 of file mesh_mrm.h. Referenced by CMeshMRMGeom(), compileRunTime(), and getVBHeapInfo(). |
|
|
Definition at line 572 of file mesh_mrm.h. Referenced by CMeshMRMGeom(), compileRunTime(), setShadowMesh(), and supportShadowSkinGrouping(). |
|
|
if true, then maybe use faster render
Definition at line 498 of file mesh_mrm.h. Referenced by CMeshMRMGeom(), compileRunTime(), and supportSkinGrouping(). |
|
|
Definition at line 532 of file mesh_mrm.h. |
|
|
The Final VBuffer.
Definition at line 487 of file mesh_mrm.h. Referenced by applyGeomorph(), applyGeomorphWithVBHardPtr(), applySkin(), beginMesh(), bkupOriginalSkinVertices(), bkupOriginalSkinVerticesSubset(), build(), compileRunTime(), computeMeshVBHeap(), getVBHeapInfo(), getVertexBuffer(), profileSceneRender(), render(), renderSkin(), renderSkinGroupGeom(), restoreOriginalSkinPart(), restoreOriginalSkinVertices(), serialLodVertexData(), updateRawSkinNormal(), and updateVertexBufferHard(). |
|
|
The Original VBuffer.
Definition at line 485 of file mesh_mrm.h. Referenced by render(), and renderSkin(). |
|
|
Definition at line 535 of file mesh_mrm.h. |
|
|
Definition at line 380 of file mesh_mrm_skin.cpp. |
|
|
Definition at line 382 of file mesh_mrm_skin.cpp. |
|
|
Definition at line 384 of file mesh_mrm_skin.cpp. |
|
|
Definition at line 386 of file mesh_mrm_skin.cpp. |
|
|
Definition at line 389 of file mesh_mrm_skin.cpp. Referenced by applyArrayShadowSkin(). |
1.3.6