NL3D::CMeshMRMSkinnedGeom Class Reference

#include <mesh_mrm_skinned.h>

Inheritance diagram for NL3D::CMeshMRMSkinnedGeom:

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

Detailed Description

An MRM mesh geometry, with no materials information.

To build a CMeshMRMSkinnedGeom, you should:

NB: internally, build() use CMRMBuilder, a builder of MRM.

Author:
Lionel Berenguier

Nevrax France

Date:
2001

Definition at line 90 of file mesh_mrm_skinned.h.

RawSkin optimisation.

uint NumCacheVertexNormal1 = NL_BlockByteL1 / sizeof(CRawVertexNormalSkinned1)
uint NumCacheVertexNormal2 = NL_BlockByteL1 / sizeof(CRawVertexNormalSkinned2)
uint NumCacheVertexNormal3 = NL_BlockByteL1 / sizeof(CRawVertexNormalSkinned3)
uint NumCacheVertexNormal4 = NL_BlockByteL1 / sizeof(CRawVertexNormalSkinned4)
uint NumCacheVertexShadow = NL_BlockByteL1 / sizeof(CMeshMRMSkinnedGeom::CShadowVertex)
void applyArrayRawSkinNormal1 (CRawVertexNormalSkinned1 *src, uint8 *destVertexPtr, CMatrix3x4 *boneMat3x4, uint nInf)
void applyArrayRawSkinNormal2 (CRawVertexNormalSkinned2 *src, uint8 *destVertexPtr, CMatrix3x4 *boneMat3x4, uint nInf)
void applyArrayRawSkinNormal3 (CRawVertexNormalSkinned3 *src, uint8 *destVertexPtr, CMatrix3x4 *boneMat3x4, uint nInf)
void applyArrayRawSkinNormal4 (CRawVertexNormalSkinned4 *src, uint8 *destVertexPtr, CMatrix3x4 *boneMat3x4, uint nInf)
void dirtMeshDataId ()
 Increment the refCount, so instances RawSkins are no longer valid.

void updateRawSkinNormal (bool enabled, CMeshMRMSkinnedInstance *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 fillAGPSkinPartWithVBHardPtr (CLod &lod, uint8 *vertexDst)
bool _PreciseClipping
 NB: HERE FOR PACKING ONLY. For clipping. Estimate if we must do a Precise clipping (ie with bboxes).


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, uint numMaxMaterial, const CMRMParameters &params=CMRMParameters())
void changeMRMDistanceSetup (float distanceFinest, float distanceMiddle, float distanceCoarsest)
 CMeshMRMSkinnedGeom ()
 Constructor.

virtual std::string getClassName ()=0
const CMRMLevelDetailgetLevelDetail () const
 get the MRM level detail information

virtual bool hasMeshVertexProgram () const
 True if this mesh has a vertexProgram.

 ~CMeshMRMSkinnedGeom ()
Mesh Block Render Interface
virtual bool isActiveInstanceNeedVBFill () const
bool isMeshInVBHeap () const
Mesh Block Render Interface
bool isMeshInVBHeap () const
Mesh Block Render Implementation
virtual void activeInstance (CMeshGeomRenderContext &rdrCtx, CMeshBaseInstance *inst, float polygonCount, void *vbDst)
virtual void beginMesh (CMeshGeomRenderContext &rdrCtx)
virtual void endMesh (CMeshGeomRenderContext &rdrCtx)
virtual uint getNumRdrPassesForInstance (CMeshBaseInstance *inst) const
virtual uint getNumRdrPassesForMesh () 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 (CMeshMRMSkinnedGeom)
 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)
 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.

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

Mesh Block Render Interface
virtual void computeMeshVBHeap (void *dst, uint indexStart)
virtual bool getVBHeapInfo (uint &vertexFormat, uint &numVertices)
virtual bool isActiveInstanceNeedVBFill () const
bool isMeshInVBHeap () const
Geometry accessors
const std::vector< std::string > & getBonesName () const
 get the bone names of the meshMRM.

const NLMISC::CAABBoxExtgetBoundingBox () 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 getNbLod () const
uint getNbRdrPass (uint lodId) const
uint32 getRdrPassMaterial (uint lodId, uint renderingPassIndex) const
void getRdrPassPrimitiveBlock (uint lodId, uint renderingPassIndex, CPrimitiveBlock &block) const
void getSkinWeights (std::vector< CMesh::CSkinWeight > &skinWeights) const
 get the skin weight buffer

void getVertexBuffer (CVertexBuffer &output) const
 get the vertex buffer used by the mrm mesh. NB: this VB store all Vertices used by All LODs.

ShadowMap Skin rendering
uint getNumShadowSkinVertices () const
 Get the num of shadow skin vertices.

sint renderShadowSkinGeom (CMeshMRMSkinnedInstance *mi, uint remainingVertices, uint8 *vbDest)
 Get the num of shadow skin vertices.

void renderShadowSkinPrimitives (CMeshMRMSkinnedInstance *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 (CMeshMRMSkinnedInstance *mi, float alphaMRM, uint remainingVertices, uint8 *vbDest)
void renderSkinGroupPrimitives (CMeshMRMSkinnedInstance *mi, uint baseVertex, std::vector< CSkinSpecularRdrPass > &specularRdrPasses, uint skinIndex)
void renderSkinGroupSpecularRdrPass (CMeshMRMSkinnedInstance *mi, uint rdrPassId)
bool supportSkinGrouping () const

Private Member Functions

void applyGeomorph (std::vector< CMRMWedgeGeom > &geoms, float alphaLod)
 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 applyGeomorphPosNormalUV0Int (std::vector< CMRMWedgeGeom > &geoms, uint8 *vertexPtr, uint8 *vertexDestPtr, sint32 vertexSize, sint a, sint a1)
 Faster, but common geomorph apply.

void applyGeomorphWithVBHardPtr (std::vector< CMRMWedgeGeom > &geoms, float alphaLod)
 Apply the geomorph to the VBhard ptr, if not NULL.

void applyRawSkinWithNormal (CLod &lod, CRawSkinnedNormalCache &rawSkinLod, const CSkeletonModel *skeleton, uint8 *vbHard, float alphaLod)
sint chooseLod (float alphaMRM, float &alphaLod)
 choose the lod according to the alphaMRM [0,1] given.

void compileRunTime ()
void updateShiftedTriangleCache (CMeshMRMSkinnedInstance *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< CLod_Lods
 List of Lods.

CPackedVertexBuffer _VBufferFinal
CMRMLevelDetail _LevelDetail

Friends

class CMRMBuilder
Structures for building a MRM mesh.
class CLod


Member Enumeration Documentation

enum NL3D::IMeshGeom::TRenderFlag [inherited]
 

Render Flags, used in render.

Enumeration values:
RenderOpaqueMaterial 
RenderTransparentMaterial 
RenderPassOpaque 
RenderGlobalAlpha 
RenderGADisableZWrite 

Definition at line 82 of file mesh_geom.h.

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


Constructor & Destructor Documentation

NL3D::CMeshMRMSkinnedGeom::CMeshMRMSkinnedGeom  ) 
 

Constructor.

Definition at line 171 of file mesh_mrm_skinned.cpp.

00172 {
00173         _BoneIdComputed = false;
00174         _BoneIdExtended = false;
00175         _PreciseClipping= false;
00176         _MeshDataId= 0;
00177         _SupportShadowSkinGrouping= false;
00178 }

NL3D::CMeshMRMSkinnedGeom::~CMeshMRMSkinnedGeom  ) 
 

Definition at line 182 of file mesh_mrm_skinned.cpp.

00183 {
00184 }


Member Function Documentation

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

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

Implements NL3D::IMeshGeom.

Definition at line 233 of file mesh_mrm_skinned.h.

00233 {};

void NL3D::CMeshMRMSkinnedGeom::applyArrayRawSkinNormal1 CRawVertexNormalSkinned1 src,
uint8 destVertexPtr,
CMatrix3x4 boneMat3x4,
uint  nInf
[private]
 

Definition at line 2390 of file mesh_mrm_skinned.cpp.

void NL3D::CMeshMRMSkinnedGeom::applyArrayRawSkinNormal2 CRawVertexNormalSkinned2 src,
uint8 destVertexPtr,
CMatrix3x4 boneMat3x4,
uint  nInf
[private]
 

Definition at line 2569 of file mesh_mrm_skinned.cpp.

void NL3D::CMeshMRMSkinnedGeom::applyArrayRawSkinNormal3 CRawVertexNormalSkinned3 src,
uint8 destVertexPtr,
CMatrix3x4 boneMat3x4,
uint  nInf
[private]
 

Definition at line 2872 of file mesh_mrm_skinned.cpp.

void NL3D::CMeshMRMSkinnedGeom::applyArrayRawSkinNormal4 CRawVertexNormalSkinned4 src,
uint8 destVertexPtr,
CMatrix3x4 boneMat3x4,
uint  nInf
[private]
 

Definition at line 3266 of file mesh_mrm_skinned.cpp.

void NL3D::CMeshMRMSkinnedGeom::applyArrayShadowSkin CShadowVertex src,
CVector dst,
CSkeletonModel skeleton,
uint  numVerts
[private]
 

Definition at line 2283 of file mesh_mrm_skinned.cpp.

References NL3D::computeBoneMatrixes3x4(), NL3D::CMeshMRMSkinnedGeom::CLod::MatrixInfluences, min, src, and uint.

Referenced by renderShadowSkinGeom().

02284 {
02285         // For all matrix this Mesh use. (the shadow geometry cannot use other Matrix than the mesh use).
02286         // NB: take the best lod since the lower lods cannot use other Matrix than the higher one.
02287         static  vector<CMatrix3x4>              boneMat3x4;
02288         CLod    &lod= _Lods[_Lods.size()-1];
02289         computeBoneMatrixes3x4(boneMat3x4, lod.MatrixInfluences, skeleton);
02290 
02291         // Then do the skin
02292         for(;numVerts>0;)
02293         {
02294                 // number of vertices to process for this block.
02295                 uint    nBlockInf= min(NumCacheVertexShadow, numVerts);
02296                 // next block.
02297                 numVerts-= nBlockInf;
02298 
02299                 // cache the data in L1 cache.
02300                 CFastMem::precache(src, nBlockInf * sizeof(CShadowVertex));
02301 
02302                 //  for all InfluencedVertices only.
02303                 for(;nBlockInf>0;nBlockInf--, src++, dst++)
02304                 {
02305                         boneMat3x4[ src->MatrixId ].mulSetPoint( src->Vertex, *dst );
02306                 }
02307         }
02308 }

void NL3D::CMeshMRMSkinnedGeom::applyGeomorph std::vector< CMRMWedgeGeom > &  geoms,
float  alphaLod
[private]
 

Apply the geomorph to the _VBuffer, or the VBhard, if exist/used.

Definition at line 410 of file mesh_mrm_skinned.cpp.

References applyGeomorphWithVBHardPtr().

Referenced by render().

00411 {
00412         applyGeomorphWithVBHardPtr(geoms, alphaLod);
00413 }

void NL3D::CMeshMRMSkinnedGeom::applyGeomorphPosNormalUV0 std::vector< CMRMWedgeGeom > &  geoms,
uint8 vertexPtr,
uint8 vertexDestPtr,
sint32  vertexSize,
float  a,
float  a1
[private]
 

Faster, but common geomorph apply.

Definition at line 438 of file mesh_mrm_skinned.cpp.

References NL3D::CMRMWedgeGeom::End, nlassert, sint32, NL3D::CMRMWedgeGeom::Start, uint, and uint8.

00439 {
00440         nlassert(vertexSize==32);
00441 
00442 
00443         // For all geomorphs.
00444         uint                    nGeoms= geoms.size();
00445         CMRMWedgeGeom   *ptrGeom= &(geoms[0]);
00446         uint8                   *destPtr= vertexDestPtr;
00447         for(; nGeoms>0; nGeoms--, ptrGeom++, destPtr+= vertexSize )
00448         {
00449                 // Consider the Pos/Normal/UV as an array of 8 float to interpolate.
00450                 float                   *start= (float*)(vertexPtr + (ptrGeom->Start<<5));
00451                 float                   *end=   (float*)(vertexPtr + (ptrGeom->End<<5));
00452                 float                   *dst=   (float*)(destPtr);
00453 
00454                 // unrolled
00455                 dst[0]= start[0] * a + end[0]* a1;
00456                 dst[1]= start[1] * a + end[1]* a1;
00457                 dst[2]= start[2] * a + end[2]* a1;
00458                 dst[3]= start[3] * a + end[3]* a1;
00459                 dst[4]= start[4] * a + end[4]* a1;
00460                 dst[5]= start[5] * a + end[5]* a1;
00461                 dst[6]= start[6] * a + end[6]* a1;
00462                 dst[7]= start[7] * a + end[7]* a1;
00463         }
00464 }

void NL3D::CMeshMRMSkinnedGeom::applyGeomorphPosNormalUV0Int std::vector< CMRMWedgeGeom > &  geoms,
uint8 vertexPtr,
uint8 vertexDestPtr,
sint32  vertexSize,
sint  a,
sint  a1
[private]
 

Faster, but common geomorph apply.

Definition at line 468 of file mesh_mrm_skinned.cpp.

References NL3D::CMRMWedgeGeom::End, sint, sint16, sint32, NL3D::CMRMWedgeGeom::Start, uint, and uint8.

Referenced by applyGeomorphWithVBHardPtr().

00469 {
00470         // For all geomorphs.
00471         uint                    nGeoms= geoms.size();
00472         CMRMWedgeGeom   *ptrGeom= &(geoms[0]);
00473         uint8                   *destPtr= vertexDestPtr;
00474         for(; nGeoms>0; nGeoms--, ptrGeom++, destPtr+= vertexSize )
00475         {
00476                 // Consider the Pos/Normal/UV as an array of 8 float to interpolate.
00477                 sint16                  *start= (sint16*)(vertexPtr + (ptrGeom->Start*vertexSize));
00478                 sint16                  *end=   (sint16*)(vertexPtr + (ptrGeom->End*vertexSize));
00479                 sint16                  *dst=   (sint16*)(destPtr);
00480 
00481                 /* Hulud
00482                  * This is slow but, we don't care because this method is called for debug purpose only (watch skin without skinning)
00483                  */
00484 
00485                 // unrolled
00486                 dst[0]= (sint16)(((sint)(start[0]) * a + (sint)(end[0]) * a1)>>8);
00487                 dst[1]= (sint16)(((sint)(start[1]) * a + (sint)(end[1]) * a1)>>8);
00488                 dst[2]= (sint16)(((sint)(start[2]) * a + (sint)(end[2]) * a1)>>8);
00489                 dst[3]= (sint16)(((sint)(start[3]) * a + (sint)(end[3]) * a1)>>8);
00490                 dst[4]= (sint16)(((sint)(start[4]) * a + (sint)(end[4]) * a1)>>8);
00491                 dst[5]= (sint16)(((sint)(start[5]) * a + (sint)(end[5]) * a1)>>8);
00492                 dst[6]= (sint16)(((sint)(start[6]) * a + (sint)(end[6]) * a1)>>8);
00493                 dst[7]= (sint16)(((sint)(start[7]) * a + (sint)(end[7]) * a1)>>8);
00494         }
00495 }

void NL3D::CMeshMRMSkinnedGeom::applyGeomorphWithVBHardPtr std::vector< CMRMWedgeGeom > &  geoms,
float  alphaLod
[private]
 

Apply the geomorph to the VBhard ptr, if not NULL.

Definition at line 417 of file mesh_mrm_skinned.cpp.

References applyGeomorphPosNormalUV0Int(), NLMISC::clamp(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getPackedVertices(), sint, sint32, uint, and uint8.

Referenced by applyGeomorph().

00418 {
00419         // no geomorphs? quit.
00420         if(geoms.size()==0)
00421                 return;
00422 
00423         clamp(alphaLod, 0.f, 1.f);
00424         sint            a= (uint)floor((256.f*alphaLod)+0.5f);
00425         sint            a1= 256 - a;
00426 
00427 
00428         // info from VBuffer.
00429         uint8           *vertexPtr= (uint8*)_VBufferFinal.getPackedVertices();
00430         sint32          vertexSize= sizeof(CPackedVertexBuffer::CPackedVertex);
00431 
00432         // use a faster method
00433         applyGeomorphPosNormalUV0Int(geoms, vertexPtr, vertexPtr, vertexSize, a, a1);
00434 }

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

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

Definition at line 395 of file mesh_mrm_skinned.cpp.

References getNbLod(), getNbRdrPass(), nlassert, uint, and uint32.

Referenced by NL3D::CMeshMRMSkinned::optimizeMaterialUsage().

00396 {
00397         for(uint lod=0;lod<getNbLod();lod++)
00398         {
00399                 for(uint rp=0;rp<getNbRdrPass(lod);rp++)
00400                 {
00401                         // remap
00402                         uint32  &matId= _Lods[lod].RdrPass[rp].MaterialId;
00403                         nlassert(remap[matId]>=0);
00404                         matId= remap[matId];
00405                 }
00406         }
00407 }

void NL3D::CMeshMRMSkinnedGeom::applyRawSkinWithNormal CLod lod,
CRawSkinnedNormalCache rawSkinLod,
const CSkeletonModel skeleton,
uint8 vbHard,
float  alphaLod
[private]
 

The same as apply skin, but with normal modified. Normal is not normalized. 4 versions from slower to faster.

Definition at line 3320 of file mesh_mrm_skinned.cpp.

Referenced by renderSkinGroupGeom().

virtual void NL3D::CMeshMRMSkinnedGeom::beginMesh CMeshGeomRenderContext rdrCtx  )  [inline, virtual]
 

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

Implements NL3D::IMeshGeom.

Definition at line 232 of file mesh_mrm_skinned.h.

00232 {};

void NL3D::CMeshMRMSkinnedGeom::build CMesh::CMeshBuild m,
uint  numMaxMaterial,
const CMRMParameters params = CMRMParameters()
 

Build a mesh, replacing old. this is much slower than CMeshGeom::build(), because it computes the MRM.

Parameters:
params parameters of the MRM build process.

Definition at line 206 of file mesh_mrm_skinned.cpp.

References NL3D::CMeshMRMSkinnedGeom::CMeshBuildMRM::BlendShapes, NL3D::CMesh::CMeshBuild::BonesNames, NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::build(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::clear(), NL3D::CMRMLevelDetail::compileDistanceSetup(), NL3D::CMRMBuilder::compileMRM(), compileRunTime(), dirtMeshDataId(), NL3D::CMeshMRMSkinnedGeom::CMeshBuildMRM::DistanceCoarsest, NL3D::CMRMLevelDetail::DistanceCoarsest, NL3D::CMeshMRMSkinnedGeom::CMeshBuildMRM::DistanceFinest, NL3D::CMRMLevelDetail::DistanceFinest, NL3D::CMeshMRMSkinnedGeom::CMeshBuildMRM::DistanceMiddle, NL3D::CMRMLevelDetail::DistanceMiddle, NL3D::CMesh::CMeshBuild::Faces, NL3D::CMeshMRMSkinnedGeom::CRdrPass::getNumTriangle(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getNumVertices(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getPackedVertices(), NL3D::CMeshMRMSkinnedGeom::CMeshBuildMRM::Lods, NL3D::makeBBox(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::Matrices, matrix, NL3D::CMRMLevelDetail::MaxFaceUsed, NL3D::CMRMLevelDetail::MinFaceUsed, NL3D_MESH_MRM_SKINNED_MAX_MATRIX, nlassert, params, NL3D::CMeshMRMSkinnedGeom::CLod::RdrPass, NLMISC::CAABBoxExt::setCenter(), NLMISC::CAABBoxExt::setSize(), NL3D::CMeshMRMSkinnedGeom::CMeshBuildMRM::Skinned, NL3D::CMeshMRMSkinnedGeom::CMeshBuildMRM::SkinWeights, uint, NL3D::CMeshMRMSkinnedGeom::CMeshBuildMRM::VBuffer, NL3D::CMesh::CMeshBuild::Vertices, and NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::Weights.

Referenced by NL3D::CMeshMRMSkinned::build().

00208 {
00209         // Empty geometry?
00210         if(m.Vertices.size()==0 || m.Faces.size()==0)
00211         {
00212                 _VBufferFinal.clear();
00213                 _Lods.clear();
00214                 _BBox.setCenter(CVector::Null);
00215                 _BBox.setSize(CVector::Null);
00216                 return;
00217         }
00218         nlassert(numMaxMaterial>0);
00219 
00220 
00222         //======================
00223         // NB: this is equivalent as building BBox from MRM VBuffer, because CMRMBuilder create new vertices 
00224         // which are just interpolation of original vertices.
00225         _BBox= makeBBox(m.Vertices);
00226 
00227 
00229         //================================================
00230         CMRMBuilder                     mrmBuilder;
00231         CMeshBuildMRM           meshBuildMRM;
00232         std::vector<CMesh::CMeshBuild*> bsList;
00233 
00234         mrmBuilder.compileMRM(m, bsList, params, meshBuildMRM, numMaxMaterial);
00235         nlassert (meshBuildMRM.Skinned);
00236 
00237         // Then build the packed vertex buffer
00238         //================================================
00239         _VBufferFinal.build (meshBuildMRM.VBuffer, meshBuildMRM.SkinWeights);
00240         _Lods= meshBuildMRM.Lods;
00241 
00242         // Compute degradation control.
00243         //================================================
00244         _LevelDetail.DistanceFinest= meshBuildMRM.DistanceFinest;
00245         _LevelDetail.DistanceMiddle= meshBuildMRM.DistanceMiddle;
00246         _LevelDetail.DistanceCoarsest= meshBuildMRM.DistanceCoarsest;
00247         nlassert(_LevelDetail.DistanceFinest>=0);
00248         nlassert(_LevelDetail.DistanceMiddle > _LevelDetail.DistanceFinest);
00249         nlassert(_LevelDetail.DistanceCoarsest > _LevelDetail.DistanceMiddle);
00250         // Compute OODistDelta and DistancePow
00251         _LevelDetail.compileDistanceSetup();
00252 
00253 
00254         // For load balancing.
00255         //================================================
00256         // compute Max Face Used
00257         _LevelDetail.MaxFaceUsed= 0;
00258         _LevelDetail.MinFaceUsed= 0;
00259         // Count of primitive block
00260         if(_Lods.size()>0)
00261         {
00262                 uint    pb;
00263                 // Compute MinFaces.
00264                 CLod    &firstLod= _Lods[0];
00265                 for (pb=0; pb<firstLod.RdrPass.size(); pb++)
00266                 {
00267                         CRdrPass &pass= firstLod.RdrPass[pb];
00268                         // Sum tri
00269                         _LevelDetail.MinFaceUsed+= pass.getNumTriangle ();
00270                 }
00271                 // Compute MaxFaces.
00272                 CLod    &lastLod= _Lods[_Lods.size()-1];
00273                 for (pb=0; pb<lastLod.RdrPass.size(); pb++)
00274                 {
00275                         CRdrPass &pass= lastLod.RdrPass[pb];
00276                         // Sum tri
00277                         _LevelDetail.MaxFaceUsed+= pass.getNumTriangle ();
00278                 }
00279         }
00280 
00281 
00282         // For skinning.
00283         //================================================
00284 
00285         // Inform that the mesh data has changed
00286         dirtMeshDataId();
00287 
00288 
00289         // For AGP SKinning optim, and for Render optim
00290         //================================================
00291         uint i;
00292         for(i=0;i<_Lods.size();i++)
00293         {
00294                 // sort triangles for better cache use.
00295                 _Lods[i].optimizeTriangleOrder();
00296         }
00297 
00298         // No Blend Shapes
00299         //================================================      
00300         nlassert (meshBuildMRM.BlendShapes.size() == 0);
00301 
00302         // Compact bone id and build a bone id names
00303         //================================================      
00304 
00305         // Remap
00306         std::map<uint, uint> remap;
00307 
00308         // Current bone
00309         uint currentBone = 0;
00310 
00311         // Reserve memory
00312         _BonesName.reserve (m.BonesNames.size());
00313 
00314         // For each vertices
00315         uint vert;
00316         CPackedVertexBuffer::CPackedVertex *vertices = _VBufferFinal.getPackedVertices();
00317         for (vert=0; vert<_VBufferFinal.getNumVertices(); vert++)
00318         {
00319                 // Found one ?
00320                 bool found=false;
00321                 
00322                 // For each weight
00323                 uint weight;
00324                 for (weight=0; weight<NL3D_MESH_MRM_SKINNED_MAX_MATRIX; weight++)
00325                 {
00326                         // Active ?
00327                         if ((vertices[vert].Weights[weight]>0)||(weight==0))
00328                         {
00329                                 // Look for it
00330                                 std::map<uint, uint>::iterator ite = remap.find (vertices[vert].Matrices[weight]);
00331 
00332                                 // Find ?
00333                                 if (ite == remap.end())
00334                                 {
00335                                         // Insert it
00336                                         remap.insert (std::map<uint, uint>::value_type (vertices[vert].Matrices[weight], currentBone));
00337 
00338                                         // Check the id
00339                                         nlassert (vertices[vert].Matrices[weight]<m.BonesNames.size());
00340 
00341                                         // Set the bone name
00342                                         _BonesName.push_back (m.BonesNames[vertices[vert].Matrices[weight]]);
00343 
00344                                         // Set the local bone id
00345                                         vertices[vert].Matrices[weight] = currentBone++;
00346                                 }
00347                                 else
00348                                 {
00349                                         // Set the local bone id
00350                                         vertices[vert].Matrices[weight] = ite->second;
00351                                 }
00352 
00353                                 // Found one
00354                                 found = true;
00355                         }
00356                 }
00357 
00358                 // Found one ?
00359                 nlassert (found);
00360         }
00361 
00362         // Remap the vertex influence by lods
00363         uint lod;
00364         for (lod=0; lod<_Lods.size(); lod++)
00365         {
00366                 // For each matrix used
00367                 uint matrix;
00368                 for (matrix=0; matrix<_Lods[lod].MatrixInfluences.size(); matrix++)
00369                 {
00370                         // Remap
00371                         std::map<uint, uint>::iterator ite = remap.find (_Lods[lod].MatrixInfluences[matrix]);
00372 
00373                         // Not find ?
00374                         if (ite == remap.end())
00375                         {
00376                                 // Remove it
00377                                 _Lods[lod].MatrixInfluences.erase (_Lods[lod].MatrixInfluences.begin()+matrix);
00378                                 matrix--;
00379                                 continue;
00380                         }
00381 
00382                         // Remap
00383                         _Lods[lod].MatrixInfluences[matrix] = ite->second;
00384                 }
00385         }
00386 
00387         // Misc.
00388         //===================
00389         // Some runtime not serialized compilation
00390         compileRunTime();
00391 
00392 }

void NL3D::CMeshMRMSkinnedGeom::changeMRMDistanceSetup float  distanceFinest,
float  distanceMiddle,
float  distanceCoarsest
 

Change MRM Distance setup. NB: no-op if distanceFinest<0, distanceMiddle<=distanceFinest or if distanceCoarsest<=distanceMiddle.

Parameters:
distanceFinest The MRM has its max faces when dist<=distanceFinest.
distanceMiddle The MRM has 50% of its faces at dist==distanceMiddle.
distanceCoarsest The MRM has faces/Divisor (ie near 0) when dist>=distanceCoarsest.

Definition at line 188 of file mesh_mrm_skinned.cpp.

References NL3D::CMRMLevelDetail::compileDistanceSetup(), NL3D::CMRMLevelDetail::DistanceCoarsest, NL3D::CMRMLevelDetail::DistanceFinest, and NL3D::CMRMLevelDetail::DistanceMiddle.

Referenced by NL3D::CMeshMRMSkinned::changeMRMDistanceSetup().

00189 {
00190         // check input.
00191         if(distanceFinest<0)    return;
00192         if(distanceMiddle<=distanceFinest)      return;
00193         if(distanceCoarsest<=distanceMiddle)    return;
00194 
00195         // Change.
00196         _LevelDetail.DistanceFinest= distanceFinest;
00197         _LevelDetail.DistanceMiddle= distanceMiddle;
00198         _LevelDetail.DistanceCoarsest= distanceCoarsest;
00199 
00200         // compile 
00201         _LevelDetail.compileDistanceSetup();
00202 }

sint NL3D::CMeshMRMSkinnedGeom::chooseLod float  alphaMRM,
float &  alphaLod
[inline, private]
 

choose the lod according to the alphaMRM [0,1] given.

Definition at line 547 of file mesh_mrm_skinned.cpp.

References sint.

Referenced by profileSceneRender(), render(), and renderSkinGroupGeom().

00548 {
00549         // Choose what Lod to draw.
00550         alphaMRM*= _Lods.size()-1;
00551         sint    numLod= (sint)ceil(alphaMRM);
00552         if(numLod==0)
00553         {
00554                 numLod= 0;
00555                 alphaLod= 0;
00556         }
00557         else
00558         {
00559                 // Lerp beetween lod i-1 and lod i.
00560                 alphaLod= alphaMRM-(numLod-1);
00561         }
00562 
00563         return numLod;
00564 }

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

clip this mesh in a driver. true if visible.

Reimplemented from NL3D::IMeshGeom.

Definition at line 505 of file mesh_mrm_skinned.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::CMeshMRMSkinned::clip().

00506 {
00507         // Speed Clip: clip just the sphere.
00508         CBSphere        localSphere(_BBox.getCenter(), _BBox.getRadius());
00509         CBSphere        worldSphere;
00510 
00511         // transform the sphere in WorldMatrix (with nearly good scale info).
00512         localSphere.applyTransform(worldMatrix, worldSphere);
00513 
00514         // if out of only plane, entirely out.
00515         for(sint i=0;i<(sint)pyramid.size();i++)
00516         {
00517                 // We are sure that pyramid has normalized plane normals.
00518                 // if SpherMax OUT return false.
00519                 float   d= pyramid[i]*worldSphere.Center;
00520                 if(d>worldSphere.Radius)
00521                         return false;
00522         }
00523 
00524         // test if must do a precise clip, according to mesh size.
00525         if( _PreciseClipping )
00526         {
00527                 CPlane  localPlane;
00528 
00529                 // if out of only plane, entirely out.
00530                 for(sint i=0;i<(sint)pyramid.size();i++)
00531                 {
00532                         // Transform the pyramid in Object space.
00533                         localPlane= pyramid[i]*worldMatrix;
00534                         // localPlane must be normalized, because worldMatrix mya have a scale.
00535                         localPlane.normalize();
00536                         // if the box is not partially inside the plane, quit
00537                         if( !_BBox.clipBack(localPlane) )
00538                                 return false;
00539                 }
00540         }
00541 
00542         return true;
00543 }

void NL3D::CMeshMRMSkinnedGeom::compileRunTime  )  [private]
 

Definition at line 1273 of file mesh_mrm_skinned.cpp.

References NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getNumVertices(), NLMISC::CAABBoxExt::getRadius(), NL3D_MESH_PRECISE_CLIP_THRESHOLD, NL3D_MESH_SKIN_MANAGER_MAXVERTICES, NL3D_SHADOW_MESH_SKIN_MANAGER_MAXVERTICES, NL3D_SHADOW_MESH_SKIN_MANAGER_VERTEXFORMAT, and nlassert.

Referenced by build(), and serial().

01274 {
01275         _PreciseClipping= _BBox.getRadius() >= NL3D_MESH_PRECISE_CLIP_THRESHOLD;
01276 
01277         // The Mesh must follow those restrictions, to support group skinning
01278         nlassert (_VBufferFinal.getNumVertices() < NL3D_MESH_SKIN_MANAGER_MAXVERTICES);
01279 
01280         // Support Shadow SkinGrouping if Shadow setuped, and if not too many vertices.
01281         _SupportShadowSkinGrouping= !_ShadowSkinVertices.empty() &&
01282                 NL3D_SHADOW_MESH_SKIN_MANAGER_VERTEXFORMAT==CVertexBuffer::PositionFlag &&
01283                 _ShadowSkinVertices.size() <= NL3D_SHADOW_MESH_SKIN_MANAGER_MAXVERTICES;
01284 }

void NL3D::CMeshMRMSkinnedGeom::computeBonesId CSkeletonModel skeleton  ) 
 

Compute skinning id.

Definition at line 1062 of file mesh_mrm_skinned.cpp.

References NL3D::CSkeletonModel::Bones, NL3D::CSkeletonModel::flagBoneAndParents(), NL3D::CSkeletonModel::getBoneIdByName(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getNumVertices(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getPackedVertices(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getPos(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::Matrices, matrix, NL3D_MESH_SKINNING_MAX_MATRIX, nlassert, nlwarning, sint32, uint, uint32, v, and NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::Weights.

Referenced by NL3D::CMeshMRMSkinned::computeBonesId().

01063 {
01064         // Already computed ?
01065         if (!_BoneIdComputed)
01066         {
01067                 // Get a pointer on the skeleton
01068                 nlassert (skeleton);
01069                 if (skeleton)
01070                 {
01071                         // Resize boneId to the good size.
01072                         _BonesId.resize(_BonesName.size());
01073 
01074                         // Remap bones id table
01075                         std::vector<uint> remap (_BonesName.size());
01076 
01077                         // **** For each bones, compute remap
01078                         uint bone;
01079                         for (bone=0; bone<remap.size(); bone++)
01080                         {
01081                                 // Look for the bone
01082                                 sint32 boneId = skeleton->getBoneIdByName (_BonesName[bone]);
01083 
01084                                 // Setup the _BoneId.
01085                                 _BonesId[bone]= boneId;
01086 
01087                                 // Bones found ?
01088                                 if (boneId != -1)
01089                                 {
01090                                         // Set the bone id
01091                                         remap[bone] = (uint32)boneId;
01092                                 }
01093                                 else
01094                                 {
01095                                         // Put id 0
01096                                         remap[bone] = 0;
01097 
01098                                         // Error
01099                                         nlwarning ("Bone %s not found in the skeleton.", _BonesName[bone].c_str());
01100                                 }
01101                         }
01102 
01103                         // **** Remap the vertices, and compute Bone Spheres.
01104 
01105                         // Find the Geomorph space: to process only real vertices, not geomorphed ones.
01106                         uint    nGeomSpace= 0;
01107                         uint    lod;
01108                         for (lod=0; lod<_Lods.size(); lod++)
01109                         {
01110                                 nGeomSpace= max(nGeomSpace, (uint)_Lods[lod].Geomorphs.size());
01111                         }
01112 
01113                         // Prepare Sphere compute
01114                         static std::vector<CAABBox>             boneBBoxes;
01115                         static std::vector<bool>                boneBBEmpty;
01116                         boneBBoxes.clear();
01117                         boneBBEmpty.clear();
01118                         boneBBoxes.resize(_BonesId.size());
01119                         boneBBEmpty.resize(_BonesId.size(), true);
01120 
01121 
01122                         // Remap the vertex, and compute the bone spheres. see CTransform::getSkinBoneSphere() doc.
01123                         // for true vertices
01124                         uint vert;
01125                         const uint vertexCount = _VBufferFinal.getNumVertices();
01126                         CPackedVertexBuffer::CPackedVertex *vertices = _VBufferFinal.getPackedVertices();
01127                         for (vert=nGeomSpace; vert<vertexCount; vert++)
01128                         {
01129                                 // get the vertex position.
01130                                 CVector vertex;
01131                                 _VBufferFinal.getPos (vertex, vertices[vert]);
01132 
01133                                 // For each weight
01134                                 uint weight;
01135                                 for (weight=0; weight<NL3D_MESH_SKINNING_MAX_MATRIX; weight++)
01136                                 {
01137                                         // Active ?
01138                                         if ((vertices[vert].Weights[weight]>0)||(weight==0))
01139                                         {
01140                                                 // Check id
01141                                                 uint    srcId= vertices[vert].Matrices[weight];
01142                                                 nlassert (srcId < remap.size());
01143                                                 // remap
01144                                                 vertices[vert].Matrices[weight] = remap[srcId];
01145 
01146                                                 // if the boneId is valid (ie found)
01147                                                 if(_BonesId[srcId]>=0)
01148                                                 {
01149                                                         // transform the vertex pos in BoneSpace
01150                                                         CVector         p= skeleton->Bones[_BonesId[srcId]].getBoneBase().InvBindPos * vertex;
01151                                                         // extend the bone bbox.
01152                                                         if(boneBBEmpty[srcId])
01153                                                         {
01154                                                                 boneBBoxes[srcId].setCenter(p);
01155                                                                 boneBBEmpty[srcId]= false;
01156                                                         }
01157                                                         else
01158                                                         {
01159                                                                 boneBBoxes[srcId].extend(p);
01160                                                         }
01161                                                 }
01162                                         }
01163                                         else
01164                                                 break;
01165                                 }                               
01166                         }
01167 
01168                         // Compile spheres
01169                         _BonesSphere.resize(_BonesId.size());
01170                         for(bone=0;bone<_BonesSphere.size();bone++)
01171                         {
01172                                 // If the bone is empty, mark with -1 in the radius.
01173                                 if(boneBBEmpty[bone])
01174                                 {
01175                                         _BonesSphere[bone].Radius= -1;
01176                                 }
01177                                 else
01178                                 {
01179                                         _BonesSphere[bone].Center= boneBBoxes[bone].getCenter();
01180                                         _BonesSphere[bone].Radius= boneBBoxes[bone].getRadius();
01181                                 }
01182                         }
01183 
01184                         // **** Remap the vertex influence by lods
01185                         for (lod=0; lod<_Lods.size(); lod++)
01186                         {
01187                                 // For each matrix used
01188                                 uint matrix;
01189                                 for (matrix=0; matrix<_Lods[lod].MatrixInfluences.size(); matrix++)
01190                                 {
01191                                         // Check
01192                                         nlassert (_Lods[lod].MatrixInfluences[matrix]<remap.size());
01193 
01194                                         // Remap
01195                                         _Lods[lod].MatrixInfluences[matrix] = remap[_Lods[lod].MatrixInfluences[matrix]];
01196                                 }
01197                         }
01198 
01199                         // **** Remap Shadow Vertices.
01200                         for(vert=0;vert<_ShadowSkinVertices.size();vert++)
01201                         {
01202                                 CShadowVertex   &v= _ShadowSkinVertices[vert];
01203                                 // Check id
01204                                 nlassert (v.MatrixId < remap.size());
01205                                 v.MatrixId= remap[v.MatrixId];
01206                         }
01207 
01208                         // Computed
01209                         _BoneIdComputed = true;
01210                 }
01211         }
01212 
01213         // Already extended ?
01214         if (!_BoneIdExtended)
01215         {
01216                 nlassert (skeleton);
01217                 if (skeleton)
01218                 {
01219                         // the total bone Usage of the mesh.
01220                         vector<bool>    boneUsage;
01221                         boneUsage.resize(skeleton->Bones.size(), false);
01222 
01223                         // for all Bones marked as valid.
01224                         uint    i;
01225                         for(i=0; i<_BonesId.size(); i++)
01226                         {
01227                                 // if not a valid boneId, skip it.
01228                                 if(_BonesId[i]<0)
01229                                         continue;
01230 
01231                                 // mark him and his father in boneUsage.
01232                                 skeleton->flagBoneAndParents(_BonesId[i], boneUsage);
01233                         }
01234 
01235                         // fill _BonesIdExt with bones of _BonesId and their parents.
01236                         _BonesIdExt.clear();
01237                         for(i=0; i<boneUsage.size();i++)
01238                         {
01239                                 // if the bone is used by the mesh, add it to BoneIdExt.
01240                                 if(boneUsage[i])
01241                                         _BonesIdExt.push_back(i);
01242                         }
01243 
01244                 }
01245 
01246                 // Extended
01247                 _BoneIdExtended= true;
01248         }
01249 
01250 }

virtual void NL3D::IMeshGeom::computeMeshVBHeap void *  dst,
uint  indexStart
[inline, virtual, inherited]
 

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

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

Reimplemented in NL3D::CMeshGeom, and NL3D::CMeshMRMGeom.

Definition at line 207 of file mesh_geom.h.

References uint.

Referenced by NL3D::CMeshBlockManager::allocateMeshVBHeap().

00207 {}

void NL3D::CMeshMRMSkinnedGeom::dirtMeshDataId  )  [private]
 

Increment the refCount, so instances RawSkins are no longer valid.

Definition at line 1560 of file mesh_mrm_skinned.cpp.

Referenced by build(), and serial().

01561 {
01562         // see updateRawSkinNormal()
01563         _MeshDataId++;
01564 }

virtual void NL3D::CMeshMRMSkinnedGeom::endMesh CMeshGeomRenderContext rdrCtx  )  [inline, virtual]
 

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

Implements NL3D::IMeshGeom.

Definition at line 235 of file mesh_mrm_skinned.h.

00235 {};

void NL3D::CMeshMRMSkinnedGeom::fillAGPSkinPartWithVBHardPtr CLod lod,
uint8 vertexDst
[private]
 

const std::vector<std::string>& NL3D::CMeshMRMSkinnedGeom::getBonesName  )  const [inline]
 

get the bone names of the meshMRM.

Definition at line 161 of file mesh_mrm_skinned.h.

00161 {return _BonesName;}

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

get the extended axis aligned bounding box of the mesh

Implements NL3D::IMeshGeom.

Definition at line 148 of file mesh_mrm_skinned.h.

Referenced by NL3D::CMeshMRMSkinned::getBoundingBox().

00149         {
00150                 return _BBox;
00151         }

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

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

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

const std::vector<CMRMWedgeGeom>& NL3D::CMeshMRMSkinnedGeom::getGeomorphs uint  lodId  )  const [inline]
 

Advanced. get the geomorphs for a special lod.

Definition at line 195 of file mesh_mrm_skinned.h.

References uint.

00196         {
00197                 return _Lods[lodId].Geomorphs;
00198         }

const CMRMLevelDetail& NL3D::CMeshMRMSkinnedGeom::getLevelDetail  )  const [inline]
 

get the MRM level detail information

Definition at line 241 of file mesh_mrm_skinned.h.

Referenced by NL3D::CMeshMRMSkinnedInstance::getMRMLevelDetail().

00241 {return _LevelDetail;}

uint NL3D::CMeshMRMSkinnedGeom::getNbLod  )  const [inline]
 

get the number of LOD.

Definition at line 165 of file mesh_mrm_skinned.h.

References uint.

Referenced by applyMaterialRemap(), and NL3D::CMeshMRMSkinned::getNbLod().

00165 { return _Lods.size() ; }

uint NL3D::CMeshMRMSkinnedGeom::getNbRdrPass uint  lodId  )  const [inline]
 

get the number of rendering pass of a LOD.

Parameters:
lodId the id of the LOD.

Definition at line 171 of file mesh_mrm_skinned.h.

References uint.

Referenced by applyMaterialRemap(), and NL3D::CMeshMRMSkinned::getNbRdrPass().

00171 { return _Lods[lodId].RdrPass.size() ; }

virtual uint NL3D::CMeshMRMSkinnedGeom::getNumRdrPassesForInstance CMeshBaseInstance inst  )  const [inline, virtual]
 

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

Implements NL3D::IMeshGeom.

Definition at line 231 of file mesh_mrm_skinned.h.

References uint.

00231 { return 0; };

virtual uint NL3D::CMeshMRMSkinnedGeom::getNumRdrPassesForMesh  )  const [inline, virtual]
 

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

Implements NL3D::IMeshGeom.

Definition at line 230 of file mesh_mrm_skinned.h.

References uint.

00230 { return 0; };

uint NL3D::CMeshMRMSkinnedGeom::getNumShadowSkinVertices  )  const
 

Get the num of shadow skin vertices.

Definition at line 1837 of file mesh_mrm_skinned.cpp.

References uint.

01838 {
01839         return _ShadowSkinVertices.size();
01840 }

float NL3D::CMeshMRMSkinnedGeom::getNumTriangles float  distance  )  [virtual]
 

get an approximation of the number of triangles this instance will render for a fixed distance.

Implements NL3D::IMeshGeom.

Definition at line 1055 of file mesh_mrm_skinned.cpp.

References NL3D::CMRMLevelDetail::getNumTriangles().

Referenced by NL3D::CMeshMRMSkinned::getNumTriangles().

01056 {
01057         // NB: this is an approximation, but this is continious.
01058         return _LevelDetail.getNumTriangles(distance);
01059 }

uint32 NL3D::CMeshMRMSkinnedGeom::getRdrPassMaterial uint  lodId,
uint  renderingPassIndex
const [inline]
 

get the material ID associated with a rendering pass of a LOD.

Parameters:
lodId the id of the LOD.
renderingPassIndex the index of the rendering pass in the matrix block

Definition at line 188 of file mesh_mrm_skinned.h.

References uint, and uint32.

Referenced by NL3D::CMeshMRMSkinned::getRdrPassMaterial().

00189         {
00190                 return _Lods[lodId].RdrPass[renderingPassIndex].MaterialId ;
00191         }

void NL3D::CMeshMRMSkinnedGeom::getRdrPassPrimitiveBlock uint  lodId,
uint  renderingPassIndex,
CPrimitiveBlock block
const [inline]
 

get the primitive block associated with a rendering pass of a LOD.

Parameters:
lodId the id of the LOD.
renderingPassIndex the index of the rendering pass

Definition at line 178 of file mesh_mrm_skinned.h.

References uint.

Referenced by NL3D::CMeshMRMSkinned::getRdrPassPrimitiveBlock().

00179         {
00180                 _Lods[lodId].getRdrPassPrimitiveBlock(renderingPassIndex, block);
00181         }

const std::vector<NLMISC::CBSphere>& NL3D::CMeshMRMSkinnedGeom::getSkinBoneSphere  )  const [inline]
 

see CTransform::getSkinBoneSphere() doc for the meaning of this value. computeBonesId must has been called before.

Definition at line 216 of file mesh_mrm_skinned.h.

Referenced by NL3D::CMeshMRMSkinnedInstance::getSkinBoneSphere().

00216 {return _BonesSphere;}

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

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

Definition at line 213 of file mesh_mrm_skinned.h.

Referenced by NL3D::CMeshMRMSkinnedInstance::getSkinBoneUsage().

00213 {return _BonesId;}

void NL3D::CMeshMRMSkinnedGeom::getSkinWeights std::vector< CMesh::CSkinWeight > &  skinWeights  )  const
 

get the skin weight buffer

Definition at line 2107 of file mesh_mrm_skinned.cpp.

References NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getNumVertices(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getPackedVertices(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::getWeight(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::Matrices, NL3D_MESH_MRM_SKINNED_MAX_MATRIX, and uint.

02108 {
02109         const uint vertexCount = _VBufferFinal.getNumVertices();
02110         skinWeights.resize (vertexCount);
02111         const CPackedVertexBuffer::CPackedVertex *vertices = _VBufferFinal.getPackedVertices();
02112         uint i;
02113         for (i=0; i<vertexCount; i++)
02114         {
02115                 const CPackedVertexBuffer::CPackedVertex &vertex = vertices[i];
02116 
02117                 uint j;
02118                 // Matrices
02119                 for (j=0; j<NL3D_MESH_MRM_SKINNED_MAX_MATRIX; j++)
02120                 {
02121                         skinWeights[i].MatrixId[j] = vertex.Matrices[j];
02122                         vertex.getWeight (skinWeights[i].Weights[j], j);
02123                 }
02124         }
02125 }

virtual bool NL3D::IMeshGeom::getVBHeapInfo uint vertexFormat,
uint numVertices
[inline, virtual, inherited]
 

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 in NL3D::CMeshGeom, and NL3D::CMeshMRMGeom.

Definition at line 200 of file mesh_geom.h.

References uint.

Referenced by NL3D::CMeshBlockManager::allocateMeshVBHeap().

00200 {return false;}

void NL3D::CMeshMRMSkinnedGeom::getVertexBuffer CVertexBuffer output  )  const
 

get the vertex buffer used by the mrm mesh. NB: this VB store all Vertices used by All LODs.

Definition at line 2088 of file mesh_mrm_skinned.cpp.

References NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::getNormal(), NL3D::CVertexBuffer::getNormalCoordPointer(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getNumVertices(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getPackedVertices(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getPos(), NL3D::CVertexBuffer::getTexCoordPointer(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::getU(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::getV(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::setNumVertices(), NL3D::CVertexBuffer::setVertexFormat(), and uint.

Referenced by NL3D::CMeshMRMSkinned::getVertexBuffer(), and render().

02089 {
02090         output.setVertexFormat (CVertexBuffer::PositionFlag|CVertexBuffer::NormalFlag|CVertexBuffer::TexCoord0Flag);
02091         const uint numVertices = _VBufferFinal.getNumVertices();
02092         output.setNumVertices (numVertices);
02093         uint i;
02094         const CPackedVertexBuffer::CPackedVertex        *vertex = _VBufferFinal.getPackedVertices();
02095         for (i=0; i<numVertices; i++)
02096         {
02097                 _VBufferFinal.getPos(*(CVector*)output.getVertexCoordPointer(i), vertex[i]);
02098                 vertex[i].getNormal(*(CVector*)output.getNormalCoordPointer(i));
02099                 float *texCoord = (float*)output.getTexCoordPointer(i,0);
02100                 vertex[i].getU(texCoord[0]);
02101                 vertex[i].getV(texCoord[1]);
02102         }
02103 }

virtual bool NL3D::CMeshMRMSkinnedGeom::hasMeshVertexProgram  )  const [inline, virtual]
 

True if this mesh has a vertexProgram.

Reimplemented from NL3D::IMeshGeom.

Definition at line 253 of file mesh_mrm_skinned.h.

Referenced by NL3D::CMeshMRMSkinnedInstance::initRenderFilterType().

00253 {return false;}

void NL3D::CMeshMRMSkinnedGeom::initInstance CMeshBaseInstance mbi  )  [virtual]
 

Init instance info.

Implements NL3D::IMeshGeom.

Definition at line 499 of file mesh_mrm_skinned.cpp.

Referenced by NL3D::CMeshMRMSkinned::createInstance().

00500 {
00501 }

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

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

Reimplemented in NL3D::CMeshMRMGeom.

Definition at line 212 of file mesh_geom.h.

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

00212 {return false;}

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

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

Definition at line 215 of file mesh_geom.h.

References NL3D::IMeshGeom::_MeshVBHeapId.

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

00215 {return _MeshVBHeapId!=0;}

NL3D::CMeshMRMSkinnedGeom::NLMISC_DECLARE_CLASS CMeshMRMSkinnedGeom   ) 
 

clip this mesh in a driver. true if visible.

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

Scene profile.

Implements NL3D::IMeshGeom.

Definition at line 1288 of file mesh_mrm_skinned.cpp.

References NL3D::CScene::BenchRes, chooseLod(), NL3D::CMRMLevelDetail::getLevelDetailFromPolyCount(), NL3D::CMeshMRMSkinnedGeom::CRdrPass::getNumTriangle(), NL3D::CScene::incrementProfileTriVBFormat(), NL3D::CMeshMRMSkinnedGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, NL3D::UScene::CBenchResults::MeshMRMProfileTriVBFormat, NL3D_MESH_SKIN_MANAGER_VERTEXFORMAT, NL3D::UScene::CBenchResults::NumMeshMRMRdrNormal, NL3D::UScene::CBenchResults::NumMeshMRMTriRdrNormal, NL3D::UScene::CBenchResults::NumMeshMRMVBufferStd, NL3D::CMeshMRMSkinnedGeom::CLod::RdrPass, NL3D::CTraversal::Scene, sint, uint, and uint32.

Referenced by NL3D::CMeshMRMSkinned::profileSceneRender().

01289 {
01290         // get the result of the Load Balancing.
01291         float   alphaMRM= _LevelDetail.getLevelDetailFromPolyCount(polygonCount);
01292 
01293         // choose the lod.
01294         float   alphaLod;
01295         sint    numLod= chooseLod(alphaMRM, alphaLod);
01296 
01297         // Render the choosen Lod.
01298         CLod    &lod= _Lods[numLod];
01299 
01300         // get the mesh instance.
01301         CMeshBaseInstance       *mi= safe_cast<CMeshBaseInstance*>(trans);
01302 
01303         // Profile all pass.
01304         uint    triCount= 0;
01305         for (uint i=0;i<lod.RdrPass.size();i++)
01306         {
01307                 CRdrPass        &rdrPass= lod.RdrPass[i];
01308                 // Profile with the Materials of the MeshInstance.
01309                 if ( ( (mi->Materials[rdrPass.MaterialId].getBlend() == false) && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) ) ||
01310                          ( (mi->Materials[rdrPass.MaterialId].getBlend() == true) && (rdrFlags & IMeshGeom::RenderTransparentMaterial) ) )
01311                 {
01312                         triCount+= rdrPass.getNumTriangle();
01313                 }
01314         }
01315 
01316         // Profile
01317         if(triCount)
01318         {
01319                 // tri per VBFormat
01320                 rdrTrav->Scene->incrementProfileTriVBFormat(rdrTrav->Scene->BenchRes.MeshMRMProfileTriVBFormat, 
01321                         NL3D_MESH_SKIN_MANAGER_VERTEXFORMAT, triCount);
01322 
01323                 rdrTrav->Scene->BenchRes.NumMeshMRMVBufferStd++;
01324                 rdrTrav->Scene->BenchRes.NumMeshMRMRdrNormal++;
01325                 rdrTrav->Scene->BenchRes.NumMeshMRMTriRdrNormal+= triCount;
01326         }
01327 }

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

render() this mesh in a driver, given an instance and his materials.

Implements NL3D::IMeshGeom.

Definition at line 568 of file mesh_mrm_skinned.cpp.

References NL3D::IDriver::activeVertexBuffer(), applyGeomorph(), chooseLod(), NL3D::IDriver::forceNormalize(), NL3D::CMeshMRMSkinnedGeom::CLod::Geomorphs, NL3D::CMRMLevelDetail::getLevelDetailFromPolyCount(), NL3D::CTransform::getOwnerScene(), NL3D::CMeshMRMSkinnedGeom::CLod::getRdrPassPrimitiveBlock(), NL3D::CScene::getRenderTrav(), NL3D::CTransform::getSkeletonModel(), getVertexBuffer(), NL3D::CTransform::getWorldMatrix(), H_AUTO, NL3D::IDriver::isForceNormalize(), NL3D::CTransform::isSkinned(), NL3D::CMeshMRMSkinnedGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, nlassert, NLMISC::OptFastFloor(), NL3D::CMeshBlender::prepareRenderForGlobalAlpha(), NL3D::CMeshMRMSkinnedGeom::CLod::RdrPass, NL3D::IDriver::render(), NL3D::CMeshBlender::restoreRender(), NL3D::IDriver::setupModelMatrix(), sint, uint, uint32, and uint8.

Referenced by NL3D::CMeshMRMSkinned::render().

00569 {
00570         nlassert(drv);
00571         if(_Lods.size()==0)
00572                 return;
00573 
00574 
00575         // get the meshMRM instance.
00576         CMeshBaseInstance       *mi= safe_cast<CMeshBaseInstance*>(trans);
00577         // get a ptr on scene
00578         CScene                          *ownerScene= mi->getOwnerScene();
00579         // get a ptr on renderTrav
00580         CRenderTrav                     *renderTrav= &ownerScene->getRenderTrav();
00581 
00582 
00583         // get the result of the Load Balancing.
00584         float   alphaMRM= _LevelDetail.getLevelDetailFromPolyCount(polygonCount);
00585 
00586         // choose the lod.
00587         float   alphaLod;
00588         sint    numLod= chooseLod(alphaMRM, alphaLod);
00589 
00590 
00591         // Render the choosen Lod.
00592         CLod    &lod= _Lods[numLod];
00593         if(lod.RdrPass.size()==0)
00594                 return;
00595 
00596 
00597         // get the skeleton model to which I am binded (else NULL).
00598         CSkeletonModel *skeleton;
00599         skeleton = mi->getSkeletonModel();
00600         // The mesh must not be skinned for render()
00601         nlassert(!(mi->isSkinned() && skeleton));
00602 
00603 
00604         // Profiling
00605         //===========
00606         H_AUTO( NL3D_MeshMRMGeom_RenderNormal );
00607 
00608         // Skinning.
00609         //===========
00610 
00611         // set the instance worldmatrix.
00612         drv->setupModelMatrix(trans->getWorldMatrix());
00613 
00614 
00615         // Geomorph.
00616         //===========
00617         // Geomorph the choosen Lod (if not the coarser mesh).
00618         if(numLod>0)
00619         {
00620                 applyGeomorph(lod.Geomorphs, alphaLod);
00621         }
00622 
00623 
00624         // force normalisation of normals..
00625         bool    bkupNorm= drv->isForceNormalize();
00626         drv->forceNormalize(true);                      
00627 
00628 
00629         // Setup meshVertexProgram
00630         //===========
00631 
00632         // Render the lod.
00633         //===========
00634         // active VB.
00635 
00636         /* Hulud
00637          * This is slow but, we don't care because this method is called for debug purpose only (watch skin without skinning)
00638          */
00639         CVertexBuffer tmp;
00640         getVertexBuffer (tmp);
00641 
00642         drv->activeVertexBuffer(tmp);
00643 
00644 
00645         // Global alpha used ?
00646         uint32  globalAlphaUsed= rdrFlags & IMeshGeom::RenderGlobalAlpha;
00647         uint8   globalAlphaInt=(uint8)NLMISC::OptFastFloor(globalAlpha*255);
00648 
00649         // Render all pass.
00650         if (globalAlphaUsed)
00651         {
00652                 bool    gaDisableZWrite= (rdrFlags & IMeshGeom::RenderGADisableZWrite)?true:false;
00653 
00654                 // for all passes
00655                 for(uint i=0;i<lod.RdrPass.size();i++)
00656                 {
00657                         CRdrPass        &rdrPass= lod.RdrPass[i];
00658 
00659                         if ( ( (mi->Materials[rdrPass.MaterialId].getBlend() == false) && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) ) ||
00660                                  ( (mi->Materials[rdrPass.MaterialId].getBlend() == true) && (rdrFlags & IMeshGeom::RenderTransparentMaterial) ) )
00661                         {
00662                                 // CMaterial Ref
00663                                 CMaterial &material=mi->Materials[rdrPass.MaterialId];
00664 
00665                                 // Use a MeshBlender to modify material and driver.
00666                                 CMeshBlender    blender;
00667                                 blender.prepareRenderForGlobalAlpha(material, drv, globalAlpha, globalAlphaInt, gaDisableZWrite);
00668 
00669                                 /* Hulud
00670                                  * This is slow but, we don't care because this method is called for debug purpose only (watch skin without skinning)
00671                                  */
00672                                 CPrimitiveBlock block;
00673                                 lod.getRdrPassPrimitiveBlock (i, block);
00674 
00675                                 // Render
00676                                 drv->render(block, material);
00677 
00678                                 // Resetup material/driver
00679                                 blender.restoreRender(material, drv, gaDisableZWrite);
00680                         }
00681                 }
00682         }
00683         else
00684         {
00685                 for(uint i=0;i<lod.RdrPass.size();i++)
00686                 {
00687                         CRdrPass        &rdrPass= lod.RdrPass[i];
00688 
00689                         if ( ( (mi->Materials[rdrPass.MaterialId].getBlend() == false) && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) ) ||
00690                                  ( (mi->Materials[rdrPass.MaterialId].getBlend() == true) && (rdrFlags & IMeshGeom::RenderTransparentMaterial) ) )
00691                         {
00692                                 // CMaterial Ref
00693                                 CMaterial &material=mi->Materials[rdrPass.MaterialId];
00694 
00695                                 /* Hulud
00696                                  * This is slow but, we don't care because this method is called for debug purpose only (watch skin without skinning)
00697                                  */
00698                                 CPrimitiveBlock block;
00699                                 lod.getRdrPassPrimitiveBlock (i, block);
00700 
00701                                 // Render with the Materials of the MeshInstance.
00702                                 drv->render(block, material);
00703                         }
00704                 }
00705         }
00706 
00707         // bkup force normalisation.
00708         drv->forceNormalize(bkupNorm);
00709 
00710 }

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

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

Implements NL3D::IMeshGeom.

Definition at line 234 of file mesh_mrm_skinned.h.

References uint.

00234 {};

sint NL3D::CMeshMRMSkinnedGeom::renderShadowSkinGeom CMeshMRMSkinnedInstance mi,
uint  remainingVertices,
uint8 vbDest
 

Get the num of shadow skin vertices.

Definition at line 1843 of file mesh_mrm_skinned.cpp.

References applyArrayShadowSkin(), NL3D::CTransform::getSkeletonModel(), H_AUTO_USE, nlassert, sint, uint, and uint8.

Referenced by NL3D::CMeshMRMSkinnedInstance::renderShadowSkinGeom().

01844 {
01845         uint    numVerts= _ShadowSkinVertices.size();
01846 
01847         if(numVerts==0)
01848                 return 0;
01849 
01850         // If the Lod is too big to render in the VBufferHard
01851         if(numVerts>remainingVertices)
01852                 // return Failure
01853                 return -1;
01854 
01855         // get the skeleton model to which I am skinned
01856         CSkeletonModel *skeleton;
01857         skeleton = mi->getSkeletonModel();
01858         // must be skinned for renderSkin()
01859         nlassert(skeleton);
01860 
01861 
01862         // Profiling
01863         //===========
01864         H_AUTO_USE( NL3D_MeshMRMGeom_RenderShadow );
01865 
01866 
01867         // Skinning.
01868         //===========
01869 
01870         // skinning with normal, but no tangent space
01871         applyArrayShadowSkin(&_ShadowSkinVertices[0], (CVector*)vbDest, skeleton, numVerts);
01872 
01873 
01874         // How many vertices are added to the VBuffer ???
01875         return numVerts;
01876 }

void NL3D::CMeshMRMSkinnedGeom::renderShadowSkinPrimitives CMeshMRMSkinnedInstance mi,
CMaterial castMat,
IDriver drv,
uint  baseVertex
 

Get the num of shadow skin vertices.

Definition at line 1879 of file mesh_mrm_skinned.cpp.

References H_AUTO_USE, min, nlassert, NL3D::IDriver::renderTriangles(), src, uint, and uint32.

Referenced by NL3D::CMeshMRMSkinnedInstance::renderShadowSkinPrimitives().

01880 {
01881         nlassert(drv);
01882 
01883         if(_ShadowSkinTriangles.empty())
01884                 return;
01885 
01886         // Profiling
01887         //===========
01888         H_AUTO_USE( NL3D_MeshMRMGeom_RenderShadow );
01889 
01890         // NB: the skeleton matrix has already been setuped by CSkeletonModel
01891         // NB: the normalize flag has already been setuped by CSkeletonModel
01892 
01893         // TODO_SHADOW: optim: Special triangle cache for shadow!
01894         static  vector<uint32>          shiftedTris;
01895         if(shiftedTris.size()<_ShadowSkinTriangles.size())
01896         {
01897                 shiftedTris.resize(_ShadowSkinTriangles.size());
01898         }
01899         uint32  *src= &_ShadowSkinTriangles[0];
01900         uint32  *dst= &shiftedTris[0];
01901         for(uint n= _ShadowSkinTriangles.size();n>0;n--, src++, dst++)
01902         {
01903                 *dst= *src + baseVertex;
01904         }
01905 
01906         // Render Triangles with cache
01907         //===========
01908 
01909         uint    numTris= _ShadowSkinTriangles.size()/3;
01910 
01911         // This speed up 4 ms for 80K polys.
01912         uint    memToCache= numTris*12;
01913         memToCache= min(memToCache, 4096U);
01914         CFastMem::precache(&shiftedTris[0], memToCache);
01915 
01916         // Render with the Materials of the MeshInstance.
01917         drv->renderTriangles(castMat, &shiftedTris[0], numTris);
01918 }

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

render() this mesh as a skin

Implements NL3D::IMeshGeom.

Definition at line 714 of file mesh_mrm_skinned.cpp.

Referenced by NL3D::CMeshMRMSkinnedInstance::renderSkin().

00715 {
00716 }

sint NL3D::CMeshMRMSkinnedGeom::renderSkinGroupGeom CMeshMRMSkinnedInstance mi,
float  alphaMRM,
uint  remainingVertices,
uint8 vbDest
 

Definition at line 726 of file mesh_mrm_skinned.cpp.

References NL3D::CMeshMRMSkinnedInstance::_RawSkinCache, applyRawSkinWithNormal(), chooseLod(), NL3D::CRawSkinnedNormalCache::Geomorphs, NL3D::CRenderTrav::getDriver(), NL3D::CTransform::getOwnerScene(), NL3D::CScene::getRenderTrav(), NL3D::CTransform::getSkeletonModel(), H_AUTO, NL3D::CTransform::isSkinned(), nlassert, NL3D::CMeshMRMSkinnedGeom::CLod::NWedges, NL3D::CMeshMRMSkinnedGeom::CLod::RdrPass, sint, NL3D::CRawSkinnedNormalCache::TotalHardVertices, NL3D::CRawSkinnedNormalCache::TotalSoftVertices, uint, uint8, and updateRawSkinNormal().

Referenced by NL3D::CMeshMRMSkinnedInstance::renderSkinGroupGeom().

00727 {
00728         H_AUTO( NL3D_MeshMRMGeom_rdrSkinGrpGeom )
00729 
00730         // get a ptr on scene
00731         CScene                          *ownerScene= mi->getOwnerScene();
00732         // get a ptr on renderTrav
00733         CRenderTrav                     *renderTrav= &ownerScene->getRenderTrav();
00734         // get a ptr on the driver
00735         IDriver                         *drv= renderTrav->getDriver();
00736         nlassert(drv);
00737 
00738 
00739         // choose the lod.
00740         float   alphaLod;
00741         sint    numLod= chooseLod(alphaMRM, alphaLod);
00742         _LastLodComputed= numLod;
00743 
00744 
00745         // Render the choosen Lod.
00746         CLod    &lod= _Lods[numLod];
00747         if(lod.RdrPass.size()==0)
00748                 // return no vertices added
00749                 return 0;
00750 
00751         // If the Lod is too big to render in the VBufferHard
00752         if(lod.NWedges>remainingVertices)
00753                 // return Failure
00754                 return -1;
00755 
00756         // get the skeleton model to which I am skinned
00757         CSkeletonModel *skeleton;
00758         skeleton = mi->getSkeletonModel();
00759         // must be skinned for renderSkin()
00760         nlassert(mi->isSkinned() && skeleton);
00761 
00762 
00763         // Profiling
00764         //===========
00765         H_AUTO( NL3D_MeshMRMGeom_rdrSkinGrpGeom_go );
00766 
00767 
00768         // Skinning.
00769         //===========
00770 
00771         // Use RawSkin if possible: only if no morph, and only Vertex/Normal
00772         updateRawSkinNormal(true, mi, numLod);
00773 
00774         // NB: the skeleton matrix has already been setuped by CSkeletonModel
00775         // NB: the normalize flag has already been setuped by CSkeletonModel
00776 
00777         // applySkin with RawSkin.
00778         //--------
00779         nlassert(mi->_RawSkinCache);
00780 
00781         H_AUTO( NL3D_RawSkinning );
00782         
00783         // RawSkin do all the job in optimized way: Skinning, copy to VBHard and Geomorph.
00784 
00785         // skinning with normal, but no tangent space
00786         applyRawSkinWithNormal (lod, *(mi->_RawSkinCache), skeleton, vbDest, alphaLod);
00787 
00788         // Vertices are packed in RawSkin mode (ie no holes due to MRM!)
00789         return  mi->_RawSkinCache->Geomorphs.size() + 
00790                         mi->_RawSkinCache->TotalSoftVertices + 
00791                         mi->_RawSkinCache->TotalHardVertices;
00792 }

void NL3D::CMeshMRMSkinnedGeom::renderSkinGroupPrimitives CMeshMRMSkinnedInstance mi,
uint  baseVertex,
std::vector< CSkinSpecularRdrPass > &  specularRdrPasses,
uint  skinIndex
 

Definition at line 795 of file mesh_mrm_skinned.cpp.

References NL3D::CMeshMRMSkinnedInstance::_ShiftedTriangleCache, NL3D::CRenderTrav::getDriver(), NL3D::CTransform::getOwnerScene(), NL3D::CScene::getRenderTrav(), NL3D::CMaterial::getShader(), NL3D::CMaterial::getTexture(), NL3D::IDriver::getTextureHandle(), H_AUTO, NL3D::CMeshMRMSkinnedGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, min, nlassert, NL3D::CShiftedTriangleCache::CRdrPass::NumTriangles, NL3D::CShiftedTriangleCache::RdrPass, NL3D::CMeshMRMSkinnedGeom::CLod::RdrPass, NL3D::CSkinSpecularRdrPass::RdrPassIndex, NL3D::IDriver::renderTriangles(), NL3D::CSkinSpecularRdrPass::SkinIndex, NL3D::CSkinSpecularRdrPass::SpecId, NL3D::CShiftedTriangleCache::CRdrPass::Triangles, uint, and updateShiftedTriangleCache().

Referenced by NL3D::CMeshMRMSkinnedInstance::renderSkinGroupPrimitives().

00796 {
00797         H_AUTO( NL3D_MeshMRMGeom_rdrSkinGrpPrimitives );
00798         
00799         // get a ptr on scene
00800         CScene                          *ownerScene= mi->getOwnerScene();
00801         // get a ptr on renderTrav
00802         CRenderTrav                     *renderTrav= &ownerScene->getRenderTrav();
00803         // get a ptr on the driver
00804         IDriver                         *drv= renderTrav->getDriver();
00805         nlassert(drv);
00806 
00807         // Get the lod choosen in renderSkinGroupGeom()
00808         CLod    &lod= _Lods[_LastLodComputed];
00809 
00810 
00811         // must update primitive cache
00812         updateShiftedTriangleCache(mi, _LastLodComputed, baseVertex);
00813         nlassert(mi->_ShiftedTriangleCache);
00814 
00815 
00816         // Render Triangles with cache
00817         //===========
00818         for(uint i=0;i<lod.RdrPass.size();i++)
00819         {
00820                 CRdrPass        &rdrPass= lod.RdrPass[i];
00821 
00822                 // CMaterial Ref
00823                 CMaterial &material=mi->Materials[rdrPass.MaterialId];
00824 
00825                 // TestYoyo. Material Speed Test
00826                 /*if( material.getDiffuse()!=CRGBA(250, 251, 252) )
00827                 {
00828                         material.setDiffuse(CRGBA(250, 251, 252));
00829                         // Set all texture the same.
00830                         static CSmartPtr<ITexture>      pTexFile= new CTextureFile("fy_hom_visage_c1_fy_e1.tga");
00831                         material.setTexture(0, pTexFile );
00832                         // Remove Specular.
00833                         if(material.getShader()==CMaterial::Specular)
00834                         {
00835                                 CSmartPtr<ITexture>     tex= material.getTexture(0);
00836                                 material.setShader(CMaterial::Normal);
00837                                 material.setTexture(0, tex );
00838                         }
00839                         // Remove MakeUp
00840                         material.setTexture(1, NULL);
00841                 }*/
00842 
00843                 // If the material is a specular material, don't render it now!
00844                 if(material.getShader()==CMaterial::Specular)
00845                 {
00846                         // Add it to the rdrPass to sort!
00847                         CSkinSpecularRdrPass    specRdrPass;
00848                         specRdrPass.SkinIndex= skinIndex;
00849                         specRdrPass.RdrPassIndex= i;
00850                         // Get the handle of the specular Map as the sort Key
00851                         ITexture        *specTex= material.getTexture(1);
00852                         if(!specTex)
00853                                 specRdrPass.SpecId= 0;
00854                         else
00855                                 specRdrPass.SpecId= drv->getTextureHandle( *specTex );
00856                         // Append it to the list
00857                         specularRdrPasses.push_back(specRdrPass);
00858                 }
00859                 else
00860                 {
00861                         // Get the shifted triangles.
00862                         CShiftedTriangleCache::CRdrPass         &shiftedRdrPass= mi->_ShiftedTriangleCache->RdrPass[i];
00863 
00864                         // This speed up 4 ms for 80K polys.
00865                         uint    memToCache= shiftedRdrPass.NumTriangles*12;
00866                         memToCache= min(memToCache, 4096U);
00867                         CFastMem::precache(shiftedRdrPass.Triangles, memToCache);
00868 
00869                         // Render with the Materials of the MeshInstance.
00870                         drv->renderTriangles(material, shiftedRdrPass.Triangles, shiftedRdrPass.NumTriangles);
00871                 }
00872         }
00873 }

void NL3D::CMeshMRMSkinnedGeom::renderSkinGroupSpecularRdrPass CMeshMRMSkinnedInstance mi,
uint  rdrPassId
 

Definition at line 877 of file mesh_mrm_skinned.cpp.

References NL3D::CMeshMRMSkinnedInstance::_ShiftedTriangleCache, NL3D::CRenderTrav::getDriver(), NL3D::CTransform::getOwnerScene(), NL3D::CScene::getRenderTrav(), H_AUTO, NL3D::CMeshMRMSkinnedGeom::CRdrPass::MaterialId, NL3D::CMeshBaseInstance::Materials, min, nlassert, NL3D::CShiftedTriangleCache::CRdrPass::NumTriangles, NL3D::CShiftedTriangleCache::RdrPass, NL3D::CMeshMRMSkinnedGeom::CLod::RdrPass, NL3D::IDriver::renderTriangles(), NL3D::CShiftedTriangleCache::CRdrPass::Triangles, and uint.

Referenced by NL3D::CMeshMRMSkinnedInstance::renderSkinGroupSpecularRdrPass().

00878 {
00879         H_AUTO( NL3D_MeshMRMGeom_rdrSkinGrpSpecularRdrPass );
00880         
00881         // get a ptr on scene
00882         CScene                          *ownerScene= mi->getOwnerScene();
00883         // get a ptr on renderTrav
00884         CRenderTrav                     *renderTrav= &ownerScene->getRenderTrav();
00885         // get a ptr on the driver
00886         IDriver                         *drv= renderTrav->getDriver();
00887         nlassert(drv);
00888 
00889         // Get the lod choosen in renderSkinGroupGeom()
00890         CLod    &lod= _Lods[_LastLodComputed];
00891 
00892 
00893         // _ShiftedTriangleCache must have been computed in renderSkinGroupPrimitives
00894         nlassert(mi->_ShiftedTriangleCache);
00895 
00896 
00897         // Render Triangles with cache
00898         //===========
00899         CRdrPass        &rdrPass= lod.RdrPass[rdrPassId];
00900 
00901         // CMaterial Ref
00902         CMaterial &material=mi->Materials[rdrPass.MaterialId];
00903 
00904         // Get the shifted triangles.
00905         CShiftedTriangleCache::CRdrPass         &shiftedRdrPass= mi->_ShiftedTriangleCache->RdrPass[rdrPassId];
00906 
00907         // This speed up 4 ms for 80K polys.
00908         uint    memToCache= shiftedRdrPass.NumTriangles*12;
00909         memToCache= min(memToCache, 4096U);
00910         CFastMem::precache(shiftedRdrPass.Triangles, memToCache);
00911 
00912         // Render with the Materials of the MeshInstance.
00913         drv->renderTriangles(material, shiftedRdrPass.Triangles, shiftedRdrPass.NumTriangles);
00914 }

void NL3D::CMeshMRMSkinnedGeom::serial NLMISC::IStream f  )  [virtual]
 

serial this meshGeom.

Implements NLMISC::IStreamable.

Definition at line 991 of file mesh_mrm_skinned.cpp.

References compileRunTime(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::contReset(), dirtMeshDataId(), NL3D::CMRMLevelDetail::DistanceCoarsest, NL3D::CMRMLevelDetail::DistanceFinest, NL3D::CMRMLevelDetail::DistanceMiddle, NL3D::CMRMLevelDetail::DistancePow, NLMISC::IStream::isReading(), NL3D::CMRMLevelDetail::MaxFaceUsed, NL3D::CMRMLevelDetail::MinFaceUsed, NL3D::CMRMLevelDetail::OODistanceDelta, NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::serial(), NLMISC::IStream::serial(), NLMISC::IStream::serialCont(), NLMISC::IStream::serialVersion(), and sint.

Referenced by NL3D::CMeshMRMSkinned::serial().

00992 {
00993         // because of complexity, serial is separated in save / load.
00994 
00995         /*
00996         Version 0:
00997                 - base version.
00998         */
00999         sint    ver= f.serialVersion(0);
01000 
01001 
01002         // serial bones names
01003         f.serialCont (_BonesName);
01004 
01005         if (f.isReading())
01006         {
01007                 // Bones index are in skeleton model id list
01008                 _BoneIdComputed = false;
01009 
01010                 // Must always recompute usage of parents of bones used.
01011                 _BoneIdExtended = false;
01012         }
01013 
01014         // serial Basic info.
01015         // ==================
01016         f.serial(_BBox);
01017         f.serial(_LevelDetail.MaxFaceUsed);
01018         f.serial(_LevelDetail.MinFaceUsed);
01019         f.serial(_LevelDetail.DistanceFinest);
01020         f.serial(_LevelDetail.DistanceMiddle);
01021         f.serial(_LevelDetail.DistanceCoarsest);
01022         f.serial(_LevelDetail.OODistanceDelta);
01023         f.serial(_LevelDetail.DistancePow);
01024 
01025         // Prepare the VBuffer.
01026         if (f.isReading())
01027                 _VBufferFinal.contReset();
01028         _VBufferFinal.serial(f);
01029 
01030         // serial Shadow Skin Information
01031         f.serialCont (_ShadowSkinVertices);
01032         f.serialCont (_ShadowSkinTriangles);
01033 
01034         // resest the Lod arrays. NB: each Lod is empty, and ready to receive Lod data.
01035         // ==================
01036         if (f.isReading())
01037         {
01038                 contReset(_Lods);
01039         }
01040 
01041         f.serialCont (_Lods);
01042 
01043         if (f.isReading())
01044         {
01045                 // Inform that the mesh data has changed
01046                 dirtMeshDataId();
01047 
01048                 // Some runtime not serialized compilation
01049                 compileRunTime();
01050         }
01051 }

void NL3D::CMeshMRMSkinnedGeom::setShadowMesh const std::vector< CShadowVertex > &  shadowVertices,
const std::vector< uint32 > &  triangles
 

Setup the ShadowMesh.

Definition at line 1826 of file mesh_mrm_skinned.cpp.

References NL3D_SHADOW_MESH_SKIN_MANAGER_MAXVERTICES, and NL3D_SHADOW_MESH_SKIN_MANAGER_VERTEXFORMAT.

01827 {
01828         _ShadowSkinVertices= shadowVertices;
01829         _ShadowSkinTriangles= triangles;
01830         // update flag. Support Shadow SkinGrouping if Shadow setuped, and if not too many vertices.
01831         _SupportShadowSkinGrouping= !_ShadowSkinVertices.empty() &&
01832                 NL3D_SHADOW_MESH_SKIN_MANAGER_VERTEXFORMAT==CVertexBuffer::PositionFlag &&
01833                 _ShadowSkinVertices.size() <= NL3D_SHADOW_MESH_SKIN_MANAGER_MAXVERTICES;
01834 }

virtual bool NL3D::CMeshMRMSkinnedGeom::sortPerMaterial  )  const [inline, virtual]
 

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

Implements NL3D::IMeshGeom.

Definition at line 229 of file mesh_mrm_skinned.h.

00229 { return false; };

bool NL3D::CMeshMRMSkinnedGeom::supportMeshBlockRendering  )  const [virtual]
 

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

Implements NL3D::IMeshGeom.

Definition at line 1339 of file mesh_mrm_skinned.cpp.

01340 {
01341         /*
01342                 Yoyo: Don't Support It for MRM because too Slow!!
01343                 The problem is that lock() unlock() on each instance, on the same VBHeap IS AS SLOWER AS
01344                 VB switching.
01345 
01346                 TODO_OPTIMIZE: find a way to optimize MRM.
01347         */
01348         return false;
01349 }

bool NL3D::CMeshMRMSkinnedGeom::supportShadowSkinGrouping  )  const [inline]
 

Render the ShadowSkin (SkinGroup like).

Definition at line 291 of file mesh_mrm_skinned.h.

Referenced by NL3D::CMeshMRMSkinnedInstance::supportShadowSkinGrouping().

bool NL3D::CMeshMRMSkinnedGeom::supportSkinGrouping  )  const
 

Definition at line 720 of file mesh_mrm_skinned.cpp.

Referenced by NL3D::CMeshMRMSkinnedInstance::supportSkinGrouping().

00721 {
00722         return true;
00723 }

void NL3D::CMeshMRMSkinnedGeom::updateRawSkinNormal bool  enabled,
CMeshMRMSkinnedInstance mi,
sint  curLodId
[private]
 

compute RawSkin info in the MRMInstance according to current skin setup.

Definition at line 1568 of file mesh_mrm_skinned.cpp.

References NL3D::CMeshMRMSkinnedInstance::_RawSkinCache, NL3D::CRawSkinnedNormalCache::clearArrays(), NL3D::CMeshMRMSkinnedInstance::clearRawSkinCache(), NL3D::CRawSkinnedNormalCache::Geomorphs, NL3D::CMeshMRMSkinnedGeom::CLod::Geomorphs, NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::getNormal(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getNumVertices(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getPackedVertices(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::getPos(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::getU(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::getV(), NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::getWeight(), H_AUTO, NL3D::CRawSkinnedNormalCache::HardVertices, NL3D::CMeshMRMSkinnedGeom::CLod::InfluencedVertices, NL3D::CRawSkinnedNormalCache::LodId, NL3D::CMeshMRMSkinnedGeom::CPackedVertexBuffer::CPackedVertex::Matrices, NL3D::CRawSkinnedNormalCache::MeshDataId, NL3D_MESH_SKINNING_MAX_MATRIX, nlassert, NL3D::CMeshMRMSkinnedGeom::CLod::RdrPass, NL3D::CRawSkinnedNormalCache::RdrPass, NLMISC::CObjectVector< CRawVertexNormalSkinned4, false >::resize(), NLMISC::CObjectVector< CRawVertexNormalSkinned3, false >::resize(), NLMISC::CObjectVector< CRawVertexNormalSkinned2, false >::resize(), NLMISC::CObjectVector< CRawVertexNormalSkinned1, false >::resize(), sint, NLMISC::CObjectVector< CRawVertexNormalSkinned4, false >::size(), NLMISC::CObjectVector< CRawVertexNormalSkinned3, false >::size(), NLMISC::CObjectVector< CRawVertexNormalSkinned2, false >::size(), NLMISC::CObjectVector< CRawVertexNormalSkinned1, false >::size(), NL3D::CRawSkinnedNormalCache::SoftVertices, NL3D::CRawSkinnedNormalCache::TotalHardVertices, NL3D::CRawSkinnedNormalCache::TotalSoftVertices, uint, uint16, uint32, NL3D::CRawSkinnedNormalCache::Vertices1, NL3D::CRawSkinnedNormalCache::Vertices2, NL3D::CRawSkinnedNormalCache::Vertices3, and NL3D::CRawSkinnedNormalCache::Vertices4.

Referenced by renderSkinGroupGeom().

01569 {
01570         if(!enabled)
01571         {
01572                 // if the instance cache is not cleared, must clear.
01573                 mi->clearRawSkinCache();
01574         }
01575         else
01576         {
01577                 // If the instance has no RawSkin, or has a too old RawSkin cache, must delete it, and recreate
01578                 if ((mi->_RawSkinCache == NULL) || (mi->_RawSkinCache->MeshDataId!=_MeshDataId))
01579                 {
01580                         // first delete if too old.
01581                         mi->clearRawSkinCache();
01582 
01583                         // Then recreate, and use _MeshDataId to verify that the instance works with same data.
01584                         mi->_RawSkinCache= new CRawSkinnedNormalCache;
01585                         mi->_RawSkinCache->MeshDataId= _MeshDataId;
01586                         mi->_RawSkinCache->LodId= -1;
01587                 }
01588 
01589 
01590                 /* If the instance rawSkin has a different Lod (or if -1), then must recreate it.
01591                         NB: The lod may change each frame per instance, but suppose not so many change, so we can cache those data.
01592                 */
01593                 if( mi->_RawSkinCache->LodId != curLodId )
01594                 {
01595                         H_AUTO( NL3D_CMeshMRMGeom_updateRawSkinNormal );
01596 
01597                         CRawSkinnedNormalCache  &skinLod= *mi->_RawSkinCache;
01598                         CLod                            &lod= _Lods[curLodId];
01599                         uint                            i;
01600                         sint                            rawIdx;
01601 
01602                         // Clear the raw skin mesh.
01603                         skinLod.clearArrays();
01604 
01605                         // Cache this lod
01606                         mi->_RawSkinCache->LodId= curLodId;
01607 
01608                         // For each matrix influence.
01609                         nlassert(NL3D_MESH_SKINNING_MAX_MATRIX==4);
01610 
01611                         // For each vertex, acknowledge if it is a src for geomorph.
01612                         static  vector<uint8>   softVertices;
01613                         softVertices.clear();
01614                         softVertices.resize( _VBufferFinal.getNumVertices(), 0 );
01615                         for(i=0;i<lod.Geomorphs.size();i++)
01616                         {
01617                                 softVertices[lod.Geomorphs[i].Start]= 1;
01618                                 softVertices[lod.Geomorphs[i].End]= 1;
01619                         }
01620 
01621                         // The remap from old index in _VBufferFinal to RawSkin vertices (without Geomorphs).
01622                         static  vector<uint32>  vertexRemap;
01623                         vertexRemap.resize( _VBufferFinal.getNumVertices() );
01624                         sint    softSize[4];
01625                         sint    hardSize[4];
01626                         sint    softStart[4];
01627                         sint    hardStart[4];
01628                         // count vertices
01629                         skinLod.TotalSoftVertices= 0;
01630                         skinLod.TotalHardVertices= 0;
01631                         for(i=0;i<4;i++)
01632                         {
01633                                 softSize[i]= 0;
01634                                 hardSize[i]= 0;
01635                                 // Count.
01636                                 for(uint j=0;j<lod.InfluencedVertices[i].size();j++)
01637                                 {
01638                                         uint    vid= lod.InfluencedVertices[i][j];
01639                                         if(softVertices[vid])
01640                                                 softSize[i]++;
01641                                         else
01642                                                 hardSize[i]++;
01643                                 }
01644                                 skinLod.TotalSoftVertices+= softSize[i];
01645                                 skinLod.TotalHardVertices+= hardSize[i];
01646                                 skinLod.SoftVertices[i]= softSize[i];
01647                                 skinLod.HardVertices[i]= hardSize[i];
01648                         }
01649                         // compute offsets
01650                         softStart[0]= 0;
01651                         hardStart[0]= skinLod.TotalSoftVertices;
01652                         for(i=1;i<4;i++)
01653                         {
01654                                 softStart[i]= softStart[i-1]+softSize[i-1];
01655                                 hardStart[i]= hardStart[i-1]+hardSize[i-1];
01656                         }
01657                         // compute remap
01658                         for(i=0;i<4;i++)
01659                         {
01660                                 uint    softIdx= softStart[i];
01661                                 uint    hardIdx= hardStart[i];
01662                                 for(uint j=0;j<lod.InfluencedVertices[i].size();j++)
01663                                 {
01664                                         uint    vid= lod.InfluencedVertices[i][j];
01665                                         if(softVertices[vid])
01666                                                 vertexRemap[vid]= softIdx++;
01667                                         else
01668                                                 vertexRemap[vid]= hardIdx++;
01669                                 }
01670                         }
01671 
01672 
01673                         // Resize the dest array.
01674                         skinLod.Vertices1.resize(lod.InfluencedVertices[0].size());
01675                         skinLod.Vertices2.resize(lod.InfluencedVertices[1].size());
01676                         skinLod.Vertices3.resize(lod.InfluencedVertices[2].size());
01677                         skinLod.Vertices4.resize(lod.InfluencedVertices[3].size());
01678 
01679                         // Vertex buffer pointers
01680                         const CPackedVertexBuffer::CPackedVertex *vertices = _VBufferFinal.getPackedVertices();
01681 
01682                         // 1 Matrix skinning.
01683                         //========
01684                         for(i=0;i<skinLod.Vertices1.size();i++)
01685                         {
01686                                 // get the dest vertex.
01687                                 uint    vid= lod.InfluencedVertices[0][i];
01688                                 // where to store?
01689                                 rawIdx= vertexRemap[vid];
01690                                 if(softVertices[vid])
01691                                         rawIdx-= softStart[0];
01692                                 else
01693                                         rawIdx+= softSize[0]-hardStart[0];
01694 
01695                                 // fill raw struct
01696                                 const CPackedVertexBuffer::CPackedVertex &vertex = vertices[vid];
01697                                 skinLod.Vertices1[rawIdx].MatrixId[0]= vertex.Matrices[0];
01698                                 _VBufferFinal.getPos (skinLod.Vertices1[rawIdx].Vertex, vertex);
01699                                 vertex.getNormal (skinLod.Vertices1[rawIdx].Normal);
01700                                 vertex.getU (skinLod.Vertices1[rawIdx].UV.U);
01701                                 vertex.getV (skinLod.Vertices1[rawIdx].UV.V);
01702                         }
01703 
01704                         // 2 Matrix skinning.
01705                         //========
01706                         for(i=0;i<skinLod.Vertices2.size();i++)
01707                         {
01708                                 // get the dest vertex.
01709                                 uint    vid= lod.InfluencedVertices[1][i];
01710                                 // where to store?
01711                                 rawIdx= vertexRemap[vid];
01712                                 if(softVertices[vid])
01713                                         rawIdx-= softStart[1];
01714                                 else
01715                                         rawIdx+= softSize[1]-hardStart[1];
01716                                 // fill raw struct
01717                                 const CPackedVertexBuffer::CPackedVertex &vertex = vertices[vid];
01718                                 skinLod.Vertices2[rawIdx].MatrixId[0]= vertex.Matrices[0];
01719                                 skinLod.Vertices2[rawIdx].MatrixId[1]= vertex.Matrices[1];
01720                                 _VBufferFinal.getPos (skinLod.Vertices2[rawIdx].Vertex, vertex);
01721                                 vertex.getWeight (skinLod.Vertices2[rawIdx].Weights[0], 0);
01722                                 vertex.getWeight (skinLod.Vertices2[rawIdx].Weights[1], 1);
01723                                 vertex.getNormal (skinLod.Vertices2[rawIdx].Normal);
01724                                 vertex.getU (skinLod.Vertices2[rawIdx].UV.U);
01725                                 vertex.getV (skinLod.Vertices2[rawIdx].UV.V);
01726                         }
01727 
01728                         // 3 Matrix skinning.
01729                         //========
01730                         for(i=0;i<skinLod.Vertices3.size();i++)
01731                         {
01732                                 // get the dest vertex.
01733                                 uint    vid= lod.InfluencedVertices[2][i];
01734                                 // where to store?
01735                                 rawIdx= vertexRemap[vid];
01736                                 if(softVertices[vid])
01737                                         rawIdx-= softStart[2];
01738                                 else
01739                                         rawIdx+= softSize[2]-hardStart[2];
01740                                 // fill raw struct
01741                                 const CPackedVertexBuffer::CPackedVertex &vertex = vertices[vid];
01742                                 skinLod.Vertices3[rawIdx].MatrixId[0]= vertex.Matrices[0];
01743                                 skinLod.Vertices3[rawIdx].MatrixId[1]= vertex.Matrices[1];
01744                                 skinLod.Vertices3[rawIdx].MatrixId[2]= vertex.Matrices[2];
01745                                 _VBufferFinal.getPos (skinLod.Vertices3[rawIdx].Vertex, vertex);
01746                                 vertex.getWeight (skinLod.Vertices3[rawIdx].Weights[0], 0);
01747                                 vertex.getWeight (skinLod.Vertices3[rawIdx].Weights[1], 1);
01748                                 vertex.getWeight (skinLod.Vertices3[rawIdx].Weights[2], 2);
01749                                 vertex.getNormal (skinLod.Vertices3[rawIdx].Normal);
01750                                 vertex.getU (skinLod.Vertices3[rawIdx].UV.U);
01751                                 vertex.getV (skinLod.Vertices3[rawIdx].UV.V);
01752                         }
01753 
01754                         // 4 Matrix skinning.
01755                         //========
01756                         for(i=0;i<skinLod.Vertices4.size();i++)
01757                         {
01758                                 // get the dest vertex.
01759                                 uint    vid= lod.InfluencedVertices[3][i];
01760                                 // where to store?
01761                                 rawIdx= vertexRemap[vid];
01762                                 if(softVertices[vid])
01763                                         rawIdx-= softStart[3];
01764                                 else
01765                                         rawIdx+= softSize[3]-hardStart[3];
01766                                 // fill raw struct
01767                                 const CPackedVertexBuffer::CPackedVertex &vertex = vertices[vid];
01768                                 skinLod.Vertices4[rawIdx].MatrixId[0]= vertex.Matrices[0];
01769                                 skinLod.Vertices4[rawIdx].MatrixId[1]= vertex.Matrices[1];
01770                                 skinLod.Vertices4[rawIdx].MatrixId[2]= vertex.Matrices[2];
01771                                 skinLod.Vertices4[rawIdx].MatrixId[3]= vertex.Matrices[3];
01772                                 _VBufferFinal.getPos (skinLod.Vertices4[rawIdx].Vertex, vertex);
01773                                 vertex.getWeight (skinLod.Vertices4[rawIdx].Weights[0], 0);
01774                                 vertex.getWeight (skinLod.Vertices4[rawIdx].Weights[1], 1);
01775                                 vertex.getWeight (skinLod.Vertices4[rawIdx].Weights[2], 2);
01776                                 vertex.getWeight (skinLod.Vertices4[rawIdx].Weights[3], 3);
01777                                 vertex.getNormal (skinLod.Vertices4[rawIdx].Normal);
01778                                 vertex.getU (skinLod.Vertices4[rawIdx].UV.U);
01779                                 vertex.getV (skinLod.Vertices4[rawIdx].UV.V);
01780                         }
01781 
01782                         // Remap Geomorphs.
01783                         //========
01784                         uint    numGeoms= lod.Geomorphs.size();
01785                         skinLod.Geomorphs.resize( numGeoms );
01786                         for(i=0;i<numGeoms;i++)
01787                         {
01788                                 // NB: don't add "numGeoms" to the index because RawSkin look in a TempArray in RAM, wich start at 0...
01789                                 skinLod.Geomorphs[i].Start= vertexRemap[lod.Geomorphs[i].Start];
01790                                 skinLod.Geomorphs[i].End= vertexRemap[lod.Geomorphs[i].End];
01791                         }
01792 
01793                         // Remap RdrPass.
01794                         //========
01795                         skinLod.RdrPass.resize(lod.RdrPass.size());
01796                         for(i=0;i<skinLod.RdrPass.size();i++)
01797                         {
01798                                 // remap tris.
01799                                 skinLod.RdrPass[i].setNumTri(lod.RdrPass[i].getNumTriangle());
01800                                 uint16  *srcTriPtr= &(lod.RdrPass[i].PBlock[0]);
01801                                 uint32  *dstTriPtr= skinLod.RdrPass[i].getTriPointer();
01802                                 uint32  numIndices= lod.RdrPass[i].PBlock.size();
01803                                 for(uint j=0;j<numIndices;j++, srcTriPtr++, dstTriPtr++)
01804                                 {
01805                                         uint    vid= (uint)*srcTriPtr;
01806                                         // If this index refers to a Geomorphed vertex, don't modify!
01807                                         if(vid<numGeoms)
01808                                                 *dstTriPtr= vid;
01809                                         else
01810                                                 *dstTriPtr= vertexRemap[vid] + numGeoms;
01811                                 }
01812                         }
01813                 }
01814         }
01815 }

void NL3D::CMeshMRMSkinnedGeom::updateShiftedTriangleCache CMeshMRMSkinnedInstance mi,
sint  curLodId,
uint  baseVertex
[private]
 

Definition at line 918 of file mesh_mrm_skinned.cpp.

References NL3D::CMeshMRMSkinnedInstance::_RawSkinCache, NL3D::CMeshMRMSkinnedInstance::_ShiftedTriangleCache, NL3D::CShiftedTriangleCache::BaseVertex, NL3D::CMeshMRMSkinnedInstance::clearShiftedTriangleCache(), NLMISC::CObjectVector< uint32, false >::getPtr(), NL3D::CShiftedTriangleCache::LodId, NL3D::CShiftedTriangleCache::MeshDataId, nlassert, NL3D::CShiftedTriangleCache::CRdrPass::NumTriangles, NL3D::CShiftedTriangleCache::RawIndices, NL3D::CShiftedTriangleCache::RdrPass, NL3D::CRawSkinnedNormalCache::RdrPass, NLMISC::CObjectVector< uint32, false >::resize(), NLMISC::CObjectVector< CRdrPass, false >::resize(), sint, NL3D::CShiftedTriangleCache::CRdrPass::Triangles, uint, and uint32.

Referenced by renderSkinGroupPrimitives().

00919 {
00920         // if the instance has a cache, but not sync to us, delete it.
00921         if( mi->_ShiftedTriangleCache && (
00922                 mi->_ShiftedTriangleCache->MeshDataId != _MeshDataId ||
00923                 mi->_ShiftedTriangleCache->LodId != curLodId ||
00924                 mi->_ShiftedTriangleCache->BaseVertex != baseVertex) )
00925         {
00926                 mi->clearShiftedTriangleCache();
00927         }
00928 
00929         // If the instance has not a valid cache, must create it.
00930         if( !mi->_ShiftedTriangleCache )
00931         {
00932                 mi->_ShiftedTriangleCache= new CShiftedTriangleCache;
00933                 // Fill the cache Key.
00934                 mi->_ShiftedTriangleCache->MeshDataId= _MeshDataId;
00935                 mi->_ShiftedTriangleCache->LodId= curLodId;
00936                 mi->_ShiftedTriangleCache->BaseVertex= baseVertex;
00937 
00938                 // Build list of PBlock. From Lod, or from RawSkin cache.
00939                 static  vector<CPrimitiveBlock*>        pbList;
00940                 pbList.clear();
00941                 nlassert(mi->_RawSkinCache);
00942                 pbList.resize(mi->_RawSkinCache->RdrPass.size());
00943                 for(uint i=0;i<pbList.size();i++)
00944                 {
00945                         pbList[i]= &mi->_RawSkinCache->RdrPass[i];
00946                 }
00947 
00948                 // Build RdrPass
00949                 mi->_ShiftedTriangleCache->RdrPass.resize(pbList.size());
00950 
00951                 // First pass, count number of triangles, and fill header info
00952                 uint    totalTri= 0;
00953                 uint    i;
00954                 for(i=0;i<pbList.size();i++)
00955                 {
00956                         mi->_ShiftedTriangleCache->RdrPass[i].NumTriangles= pbList[i]->getNumTri();
00957                         totalTri+= pbList[i]->getNumTri();
00958                 }
00959 
00960                 // Allocate triangles indices.
00961                 mi->_ShiftedTriangleCache->RawIndices.resize(totalTri*3);
00962                 uint32          *rawPtr= mi->_ShiftedTriangleCache->RawIndices.getPtr();
00963 
00964                 // Second pass, fill ptrs, and fill Arrays
00965                 uint    indexTri= 0;
00966                 for(i=0;i<pbList.size();i++)
00967                 {
00968                         CShiftedTriangleCache::CRdrPass &dstRdrPass= mi->_ShiftedTriangleCache->RdrPass[i];
00969                         dstRdrPass.Triangles= rawPtr + indexTri*3;
00970 
00971                         // Fill the array
00972                         uint    numTris= pbList[i]->getNumTri();
00973                         if(numTris)
00974                         {
00975                                 uint    nIds= numTris*3;
00976                                 // index, and fill
00977                                 uint32  *pSrcTri= pbList[i]->getTriPointer();
00978                                 uint32  *pDstTri= dstRdrPass.Triangles;
00979                                 for(;nIds>0;nIds--,pSrcTri++,pDstTri++)
00980                                         *pDstTri= *pSrcTri + baseVertex;
00981                         }
00982 
00983                         // Next
00984                         indexTri+= dstRdrPass.NumTriangles;
00985                 }
00986         }
00987 }

void NL3D::CMeshMRMSkinnedGeom::updateSkeletonUsage CSkeletonModel sm,
bool  increment
 

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

Definition at line 1254 of file mesh_mrm_skinned.cpp.

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

Referenced by NL3D::CMeshMRMSkinned::updateSkeletonUsage().

01255 {
01256         // For all Bones used.
01257         for(uint i=0; i<_BonesIdExt.size();i++)
01258         {
01259                 uint    boneId= _BonesIdExt[i];
01260                 // Some explicit Error.
01261                 if(boneId>=sm->Bones.size())
01262                         nlerror(" Skin is incompatible with Skeleton: tries to use bone %d", boneId);
01263                 // increment or decrement not Forced, because CMeshGeom use getActiveBoneSkinMatrix().
01264                 if(increment)
01265                         sm->incBoneUsage(boneId, CSkeletonModel::UsageNormal);
01266                 else
01267                         sm->decBoneUsage(boneId, CSkeletonModel::UsageNormal);
01268         }
01269 }


Friends And Related Function Documentation

friend class CLod [friend]
 

Definition at line 383 of file mesh_mrm_skinned.h.

friend class CMRMBuilder [friend]
 

Definition at line 299 of file mesh_mrm_skinned.h.


Field Documentation

NLMISC::CAABBoxExt NL3D::CMeshMRMSkinnedGeom::_BBox [private]
 

For clipping. this is the BB of all vertices of all Lods.

Definition at line 552 of file mesh_mrm_skinned.h.

bool NL3D::CMeshMRMSkinnedGeom::_BoneIdComputed [private]
 

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

Definition at line 533 of file mesh_mrm_skinned.h.

bool NL3D::CMeshMRMSkinnedGeom::_BoneIdExtended [private]
 

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

Definition at line 535 of file mesh_mrm_skinned.h.

std::vector<sint32> NL3D::CMeshMRMSkinnedGeom::_BonesId [private]
 

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

Definition at line 543 of file mesh_mrm_skinned.h.

std::vector<sint32> NL3D::CMeshMRMSkinnedGeom::_BonesIdExt [private]
 

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

Definition at line 545 of file mesh_mrm_skinned.h.

std::vector<std::string> NL3D::CMeshMRMSkinnedGeom::_BonesName [private]
 

This array give the name of the local bones.

Definition at line 541 of file mesh_mrm_skinned.h.

std::vector<NLMISC::CBSphere> NL3D::CMeshMRMSkinnedGeom::_BonesSphere [private]
 

see CTransform::getSkinBoneSphere() doc for the meaning of this value

Definition at line 547 of file mesh_mrm_skinned.h.

uint8 NL3D::CMeshMRMSkinnedGeom::_LastLodComputed [private]
 

Last lod rendered. used with renderSkinGroup*() only.

Definition at line 538 of file mesh_mrm_skinned.h.

CMRMLevelDetail NL3D::CMeshMRMSkinnedGeom::_LevelDetail [private]
 

Definition at line 557 of file mesh_mrm_skinned.h.

std::vector<CLod> NL3D::CMeshMRMSkinnedGeom::_Lods [private]
 

List of Lods.

Definition at line 550 of file mesh_mrm_skinned.h.

uint NL3D::CMeshMRMSkinnedGeom::_MeshDataId [private]
 

Each time the mesh is loaded/built, this increment.

Definition at line 614 of file mesh_mrm_skinned.h.

bool NL3D::CMeshMRMSkinnedGeom::_PreciseClipping [private]
 

NB: HERE FOR PACKING ONLY. For clipping. Estimate if we must do a Precise clipping (ie with bboxes).

Definition at line 565 of file mesh_mrm_skinned.h.

std::vector<uint32> NL3D::CMeshMRMSkinnedGeom::_ShadowSkinTriangles [private]
 

Definition at line 575 of file mesh_mrm_skinned.h.

std::vector<CShadowVertex> NL3D::CMeshMRMSkinnedGeom::_ShadowSkinVertices [private]
 

Definition at line 574 of file mesh_mrm_skinned.h.

bool NL3D::CMeshMRMSkinnedGeom::_SupportShadowSkinGrouping [private]
 

Definition at line 576 of file mesh_mrm_skinned.h.

CPackedVertexBuffer NL3D::CMeshMRMSkinnedGeom::_VBufferFinal [private]
 

Definition at line 530 of file mesh_mrm_skinned.h.

uint NL3D::CMeshMRMSkinnedGeom::NumCacheVertexNormal1 = NL_BlockByteL1 / sizeof(CRawVertexNormalSkinned1) [static]
 

Definition at line 2324 of file mesh_mrm_skinned.cpp.

uint NL3D::CMeshMRMSkinnedGeom::NumCacheVertexNormal2 = NL_BlockByteL1 / sizeof(CRawVertexNormalSkinned2) [static]
 

Definition at line 2326 of file mesh_mrm_skinned.cpp.

uint NL3D::CMeshMRMSkinnedGeom::NumCacheVertexNormal3 = NL_BlockByteL1 / sizeof(CRawVertexNormalSkinned3) [static]
 

Definition at line 2328 of file mesh_mrm_skinned.cpp.

uint NL3D::CMeshMRMSkinnedGeom::NumCacheVertexNormal4 = NL_BlockByteL1 / sizeof(CRawVertexNormalSkinned4) [static]
 

Definition at line 2330 of file mesh_mrm_skinned.cpp.

uint NL3D::CMeshMRMSkinnedGeom::NumCacheVertexShadow = NL_BlockByteL1 / sizeof(CMeshMRMSkinnedGeom::CShadowVertex) [static]
 

Definition at line 2333 of file mesh_mrm_skinned.cpp.


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 06:54:20 2004 for NeL by doxygen 1.3.6