#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(). |