123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990 |
- /* Copyright (c) 2002-2012 Croteam Ltd.
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as published by
- the Free Software Foundation
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
- #include "stdh.h"
- #include "Mesh.h"
- #define MESH_VERSION 12
- #define MESH_ID "MESH"
- #include <Engine/Base/Stream.h>
- #include <Engine/Base/Console.h>
- #include <Engine/Ska/StringTable.h>
- #include <Engine/Math/Projection.h>
- #include <Engine/Graphics/DrawPort.h>
- #include <Engine/Graphics/Shader.h>
- #include <Engine/Templates/StaticArray.h>
- #include <Engine/Templates/StaticArray.cpp>
- #include <Engine/Templates/Stock_CShader.h>
- INDEX AreVerticesDiferent(INDEX iCurentIndex, INDEX iLastIndex);
- struct VertexLocator
- {
- INDEX vl_iIndex;
- INDEX vl_iSubIndex;
- };
- struct SortArray
- {
- INDEX sa_iNewIndex;
- INDEX sa_iSurfaceIndex;
- CStaticArray<struct VertexLocator> sa_aWeightMapList;
- CStaticArray<struct VertexLocator> sa_aMorphMapList;
- };
- CStaticArray <struct SortArray> _aSortArray;
- CStaticArray <INDEX> _aiOptimizedIndex;
- CStaticArray <INDEX> _aiSortedIndex;
- MeshLOD *pMeshLOD;// curent mesh lod (for quick sort)
- MeshLOD mshOptimized;
- CMesh::CMesh()
- {
- }
- CMesh::~CMesh()
- {
- }
- // release old shader and obtain new shader for mesh surface (expand ShaderParams if needed)
- void ChangeSurfaceShader_t(MeshSurface &msrf,CTString fnNewShader)
- {
- CShader *pShaderNew = _pShaderStock->Obtain_t(fnNewShader);
- ASSERT(pShaderNew!=NULL);
- if(msrf.msrf_pShader!=NULL) _pShaderStock->Release(msrf.msrf_pShader);
- msrf.msrf_pShader = pShaderNew;
- // get new shader description
- ShaderDesc shDesc;
- msrf.msrf_pShader->GetShaderDesc(shDesc);
- // if needed expand size of arrays for new shader
- // reset new values!!!!
- INDEX ctOldTextureIDs = msrf.msrf_ShadingParams.sp_aiTextureIDs.Count();
- INDEX ctNewTextureIDs = shDesc.sd_astrTextureNames.Count();
- INDEX ctOldUVMaps = msrf.msrf_ShadingParams.sp_aiTexCoordsIndex.Count();
- INDEX ctNewUVMaps = shDesc.sd_astrTexCoordNames.Count();
- INDEX ctOldColors = msrf.msrf_ShadingParams.sp_acolColors.Count();
- INDEX ctNewColors = shDesc.sd_astrColorNames.Count();
- INDEX ctOldFloats = msrf.msrf_ShadingParams.sp_afFloats.Count();
- INDEX ctNewFloats = shDesc.sd_astrFloatNames.Count();
- if(ctOldTextureIDs<ctNewTextureIDs) {
- // expand texture IDs array
- msrf.msrf_ShadingParams.sp_aiTextureIDs.Expand(ctNewTextureIDs);
- // set new texture IDs to 0
- for(INDEX itx=ctOldTextureIDs;itx<ctNewTextureIDs;itx++) {
- msrf.msrf_ShadingParams.sp_aiTextureIDs[itx] = -1;
- }
- }
- // expand array of uvmaps if needed
- if(ctOldUVMaps<ctNewUVMaps) {
- // expand uvmaps IDs array
- msrf.msrf_ShadingParams.sp_aiTexCoordsIndex.Expand(ctNewUVMaps);
- // set new uvmaps indices to 0
- for(INDEX itxc=ctOldUVMaps;itxc<ctNewUVMaps;itxc++) {
- msrf.msrf_ShadingParams.sp_aiTexCoordsIndex[itxc] = 0;
- }
- }
- // expand array of colors if needed
- if(ctOldColors<ctNewColors) {
- // expand color array
- msrf.msrf_ShadingParams.sp_acolColors.Expand(ctNewColors);
- // set new colors indices white
- for(INDEX icol=ctOldUVMaps;icol<ctNewColors;icol++) {
- msrf.msrf_ShadingParams.sp_acolColors[icol] = 0xFFFFFFFF;
- }
- }
- // expand array of floats if needed
- if(ctOldFloats<ctNewFloats) {
- // expand float array
- msrf.msrf_ShadingParams.sp_afFloats.Expand(ctNewFloats);
- // set new floats to 0
- for(INDEX ifl=ctOldFloats;ifl<ctNewFloats;ifl++) {
- msrf.msrf_ShadingParams.sp_afFloats[ifl] = 1;
- }
- }
- }
- // quck sort func for comparing vertices
- static int qsort_CompareArray(const void *pVx1, const void *pVx2)
- {
- INDEX *n1 = ((INDEX*)pVx1);
- INDEX *n2 = ((INDEX*)pVx2);
- return AreVerticesDiferent(*n1,*n2);
- }
- // clear array of sort vertices
- void ClearSortArray(INDEX ctOldVertices)
- {
- for(int iv=0;iv<ctOldVertices;iv++)
- {
- _aSortArray[iv].sa_aWeightMapList.Clear();
- _aSortArray[iv].sa_aMorphMapList.Clear();
- }
- _aiOptimizedIndex.Clear();
- _aiSortedIndex.Clear();
- _aSortArray.Clear();
- }
- // optimize mesh
- void CMesh::Optimize(void)
- {
- INDEX ctmshlods = msh_aMeshLODs.Count();
- for(int imshlod=0;imshlod<ctmshlods;imshlod++)
- {
- // optimize each lod in mesh
- OptimizeLod(msh_aMeshLODs[imshlod]);
- }
- }
- // optimize lod of mesh
- void CMesh::OptimizeLod(MeshLOD &mLod)
- {
- INDEX ctVertices = mLod.mlod_aVertices.Count();
- INDEX ctSurfaces = mLod.mlod_aSurfaces.Count();
- INDEX ctUVMaps = mLod.mlod_aUVMaps.Count();
- INDEX ctWeightMaps = mLod.mlod_aWeightMaps.Count();
- INDEX ctMorphMaps = mLod.mlod_aMorphMaps.Count();
- if(ctVertices<=0) return;
-
- // create array for sorting
- _aSortArray.New(ctVertices);
- _aiSortedIndex.New(ctVertices);
- _aiOptimizedIndex.New(ctVertices);
- // put original vertex indices in SortArray
- for(int iv=0;iv<ctVertices;iv++)
- {
- _aiSortedIndex[iv] = iv;
- }
- // loop each surface and expand SurfaceList in SortArray
- int is=0;
- for(;is<ctSurfaces;is++)
- {
- INDEX ctts=mLod.mlod_aSurfaces[is].msrf_aTriangles.Count();
- for(int its=0;its<ctts;its++)
- {
- MeshTriangle &mtTriangle = mLod.mlod_aSurfaces[is].msrf_aTriangles[its];
- _aSortArray[mtTriangle.iVertex[0]].sa_iSurfaceIndex = is;
- _aSortArray[mtTriangle.iVertex[1]].sa_iSurfaceIndex = is;
- _aSortArray[mtTriangle.iVertex[2]].sa_iSurfaceIndex = is;
- }
- }
- // loop each weightmap and expand sa_aWeightMapList in SortArray
- for(INDEX iw=0;iw<ctWeightMaps;iw++)
- {
- // loop each wertex weight array in weight map array
- INDEX ctwm = mLod.mlod_aWeightMaps[iw].mwm_aVertexWeight.Count();
- for(INDEX iwm=0;iwm<ctwm;iwm++)
- {
- MeshVertexWeight &mwwWeight = mLod.mlod_aWeightMaps[iw].mwm_aVertexWeight[iwm];
- // get curent list num of weightmaps
- INDEX ctWeightMapList = _aSortArray[mwwWeight.mww_iVertex].sa_aWeightMapList.Count();
- // expand array of sufrace lists for 1
- _aSortArray[mwwWeight.mww_iVertex].sa_aWeightMapList.Expand(ctWeightMapList+1);
- // set vl_iIndex to index of surface
- // set vl_iSubIndex to index in triangle set
- VertexLocator &vxLoc = _aSortArray[mwwWeight.mww_iVertex].sa_aWeightMapList[ctWeightMapList];
- vxLoc.vl_iIndex = iw;
- vxLoc.vl_iSubIndex = iwm;
- }
- }
- // loop each morphmap and expand sa_aMorphMapList in SortArray
- for(INDEX im=0;im<ctMorphMaps;im++)
- {
- // loop each morph map in array
- INDEX ctmm = mLod.mlod_aMorphMaps[im].mmp_aMorphMap.Count();
- for(INDEX imm=0;imm<ctmm;imm++)
- {
- MeshVertexMorph &mwmMorph = mLod.mlod_aMorphMaps[im].mmp_aMorphMap[imm];
- // get curent list num of morphmaps
- INDEX ctMorphMapList = _aSortArray[mwmMorph.mwm_iVxIndex].sa_aMorphMapList.Count();
- // expand array of sufrace lists for 1
- _aSortArray[mwmMorph.mwm_iVxIndex].sa_aMorphMapList.Expand(ctMorphMapList+1);
- // set vl_iIndex to index of surface
- // set vl_iSubIndex to index in triangle set
- VertexLocator &vxLoc = _aSortArray[mwmMorph.mwm_iVxIndex].sa_aMorphMapList[ctMorphMapList];
- vxLoc.vl_iIndex = im;
- vxLoc.vl_iSubIndex = imm;
- }
- }
- // set global pMeshLOD pointer used by quicksort
- pMeshLOD = &mLod;
- // sort array
- qsort(&_aiSortedIndex[0],ctVertices,sizeof(&_aiSortedIndex[0]),qsort_CompareArray);
-
- // compare vertices
- INDEX iDiferentVertices = 1;
- INDEX iLastIndex = _aiSortedIndex[0];
- _aSortArray[iLastIndex].sa_iNewIndex = 0;
- _aiOptimizedIndex[0] = iLastIndex;
-
- for(INDEX isa=1;isa<ctVertices;isa++)
- {
- INDEX iCurentIndex = _aiSortedIndex[isa];
- // check if vertices are diferent
- if(AreVerticesDiferent(iLastIndex,iCurentIndex))
- {
- // add Curent index to Optimized index array
- _aiOptimizedIndex[iDiferentVertices] = iCurentIndex;
- iDiferentVertices++;
- iLastIndex = iCurentIndex;
- }
- _aSortArray[iCurentIndex].sa_iNewIndex = iDiferentVertices-1;
- }
- // create new mesh
- INDEX ctNewVertices = iDiferentVertices;
- mshOptimized.mlod_aVertices.New(ctNewVertices);
- mshOptimized.mlod_aNormals.New(ctNewVertices);
- mshOptimized.mlod_aUVMaps.New(ctUVMaps);
- for(INDEX iuvm=0;iuvm<ctUVMaps;iuvm++)
- {
- mshOptimized.mlod_aUVMaps[iuvm].muv_aTexCoords.New(ctNewVertices);
- }
- // add new vertices and normals to mshOptimized
- for(INDEX iNewVx=0;iNewVx<ctNewVertices;iNewVx++)
- {
- mshOptimized.mlod_aVertices[iNewVx] = mLod.mlod_aVertices[_aiOptimizedIndex[iNewVx]];
- mshOptimized.mlod_aNormals[iNewVx] = mLod.mlod_aNormals[_aiOptimizedIndex[iNewVx]];
- for(INDEX iuvm=0;iuvm<ctUVMaps;iuvm++)
- {
- //???
- mshOptimized.mlod_aUVMaps[iuvm].muv_iID = mLod.mlod_aUVMaps[iuvm].muv_iID;
- mshOptimized.mlod_aUVMaps[iuvm].muv_aTexCoords[iNewVx] = mLod.mlod_aUVMaps[iuvm].muv_aTexCoords[_aiOptimizedIndex[iNewVx]];
- }
- }
- // remap surface triangles
- for(is=0;is<ctSurfaces;is++)
- {
- MeshSurface &msrf = mLod.mlod_aSurfaces[is];
- INDEX iMinIndex = ctNewVertices+1;
- INDEX iMaxIndex = -1;
- INDEX ctts=msrf.msrf_aTriangles.Count();
- // for each triangle in this surface
- INDEX its=0;
- for(;its<ctts;its++)
- {
- MeshTriangle &mtTriangle = msrf.msrf_aTriangles[its];
- // for each vertex in triangle
- for(INDEX iv=0;iv<3;iv++)
- {
- mtTriangle.iVertex[iv] = _aSortArray[mtTriangle.iVertex[iv]].sa_iNewIndex;
- // find first index in this surface
- if(mtTriangle.iVertex[iv]<iMinIndex) iMinIndex = mtTriangle.iVertex[iv];
- // find last index in this surface
- if(mtTriangle.iVertex[iv]>iMaxIndex) iMaxIndex = mtTriangle.iVertex[iv];
- }
- }
- // remember first index in vertices array
- msrf.msrf_iFirstVertex = iMinIndex;
- // remember vertices count
- msrf.msrf_ctVertices = iMaxIndex-iMinIndex+1;
- // for each triangle in surface
- for(its=0;its<ctts;its++)
- {
- MeshTriangle &mtTriangle = msrf.msrf_aTriangles[its];
- // for each vertex in triangle
- for(INDEX iv=0;iv<3;iv++)
- {
- // substract vertex index in triangle with first vertex in surface
- mtTriangle.iVertex[iv] -= msrf.msrf_iFirstVertex;
- ASSERT(mtTriangle.iVertex[iv]<msrf.msrf_ctVertices);
- }
- }
- }
- // remap weightmaps
- mshOptimized.mlod_aWeightMaps.New(ctWeightMaps);
- // expand wertex veights array for each vertex
- INDEX ivx=0;
- for(;ivx<ctNewVertices;ivx++)
- {
- INDEX ioptVx = _aiOptimizedIndex[ivx];
- for(INDEX iwl=0;iwl<_aSortArray[ioptVx].sa_aWeightMapList.Count();iwl++)
- {
- VertexLocator &wml = _aSortArray[ioptVx].sa_aWeightMapList[iwl];
- INDEX wmIndex = wml.vl_iIndex;
- INDEX wwIndex = wml.vl_iSubIndex;
- INDEX ctww = mshOptimized.mlod_aWeightMaps[wmIndex].mwm_aVertexWeight.Count();
- MeshWeightMap &mwm = mshOptimized.mlod_aWeightMaps[wmIndex];
- MeshVertexWeight &mww = mLod.mlod_aWeightMaps[wmIndex].mwm_aVertexWeight[wwIndex];
- mwm.mwm_iID = mLod.mlod_aWeightMaps[wmIndex].mwm_iID;
- mwm.mwm_aVertexWeight.Expand(ctww+1);
- mwm.mwm_aVertexWeight[ctww].mww_fWeight = mww.mww_fWeight;
- mwm.mwm_aVertexWeight[ctww].mww_iVertex = ivx;
- }
- }
- // remap morphmaps
- mshOptimized.mlod_aMorphMaps.New(ctMorphMaps);
- // expand morph maps array for each vertex
- for(ivx=0;ivx<ctNewVertices;ivx++)
- {
- INDEX ioptVx = _aiOptimizedIndex[ivx];
- for(INDEX iml=0;iml<_aSortArray[ioptVx].sa_aMorphMapList.Count();iml++)
- {
- VertexLocator &mml = _aSortArray[ioptVx].sa_aMorphMapList[iml];
- INDEX mmIndex = mml.vl_iIndex;
- INDEX mwmIndex = mml.vl_iSubIndex;
- INDEX ctmwm = mshOptimized.mlod_aMorphMaps[mmIndex].mmp_aMorphMap.Count();
- MeshMorphMap &mmm = mshOptimized.mlod_aMorphMaps[mmIndex];
- MeshVertexMorph &mwm = mLod.mlod_aMorphMaps[mmIndex].mmp_aMorphMap[mwmIndex];
- mmm.mmp_iID = mLod.mlod_aMorphMaps[mmIndex].mmp_iID;
- mmm.mmp_bRelative = mLod.mlod_aMorphMaps[mmIndex].mmp_bRelative;
- mmm.mmp_aMorphMap.Expand(ctmwm+1);
- mmm.mmp_aMorphMap[ctmwm].mwm_iVxIndex = ivx;
- mmm.mmp_aMorphMap[ctmwm].mwm_x = mwm.mwm_x;
- mmm.mmp_aMorphMap[ctmwm].mwm_y = mwm.mwm_y;
- mmm.mmp_aMorphMap[ctmwm].mwm_z = mwm.mwm_z;
- mmm.mmp_aMorphMap[ctmwm].mwm_nx = mwm.mwm_nx;
- mmm.mmp_aMorphMap[ctmwm].mwm_ny = mwm.mwm_ny;
- mmm.mmp_aMorphMap[ctmwm].mwm_nz = mwm.mwm_nz;
- }
- }
- mLod.mlod_aVertices.CopyArray(mshOptimized.mlod_aVertices);
- mLod.mlod_aNormals.CopyArray(mshOptimized.mlod_aNormals);
- mLod.mlod_aMorphMaps.CopyArray(mshOptimized.mlod_aMorphMaps);
- mLod.mlod_aWeightMaps.CopyArray(mshOptimized.mlod_aWeightMaps);
- mLod.mlod_aUVMaps.CopyArray(mshOptimized.mlod_aUVMaps);
- // clear memory
- ClearSortArray(ctVertices);
- mshOptimized.mlod_aVertices.Clear();
- mshOptimized.mlod_aNormals.Clear();
- mshOptimized.mlod_aWeightMaps.Clear();
- mshOptimized.mlod_aMorphMaps.Clear();
- mshOptimized.mlod_aUVMaps.Clear();
- }
- INDEX AreVerticesDiferent(INDEX iCurentIndex, INDEX iLastIndex)
- {
- #define CHECK(x,y) if(((x)-(y))!=0) return ((x)-(y))
- #define CHECKF(x,y) if(((x)-(y))!=0) return Sgn((x)-(y))
-
- // check surfaces
- CHECK(_aSortArray[iCurentIndex].sa_iSurfaceIndex,_aSortArray[iLastIndex].sa_iSurfaceIndex);
- // check vertices
- CHECKF(pMeshLOD->mlod_aVertices[iCurentIndex].y,pMeshLOD->mlod_aVertices[iLastIndex].y);
- CHECKF(pMeshLOD->mlod_aVertices[iCurentIndex].x,pMeshLOD->mlod_aVertices[iLastIndex].x);
- CHECKF(pMeshLOD->mlod_aVertices[iCurentIndex].z,pMeshLOD->mlod_aVertices[iLastIndex].z);
- // check normals
- CHECKF(pMeshLOD->mlod_aNormals[iCurentIndex].ny,pMeshLOD->mlod_aNormals[iLastIndex].ny);
- CHECKF(pMeshLOD->mlod_aNormals[iCurentIndex].nx,pMeshLOD->mlod_aNormals[iLastIndex].nx);
- CHECKF(pMeshLOD->mlod_aNormals[iCurentIndex].nz,pMeshLOD->mlod_aNormals[iLastIndex].nz);
- // check uvmaps
- INDEX ctUVMaps = pMeshLOD->mlod_aUVMaps.Count();
- for(INDEX iuvm=0;iuvm<ctUVMaps;iuvm++)
- {
- CHECKF(pMeshLOD->mlod_aUVMaps[iuvm].muv_aTexCoords[iCurentIndex].u,pMeshLOD->mlod_aUVMaps[iuvm].muv_aTexCoords[iLastIndex].u);
- CHECKF(pMeshLOD->mlod_aUVMaps[iuvm].muv_aTexCoords[iCurentIndex].v,pMeshLOD->mlod_aUVMaps[iuvm].muv_aTexCoords[iLastIndex].v);
- }
- // count weight and morph maps
- INDEX ctwmCurent = _aSortArray[iCurentIndex].sa_aWeightMapList.Count();
- INDEX ctwmLast = _aSortArray[iLastIndex].sa_aWeightMapList.Count();
- INDEX ctmmCurent = _aSortArray[iCurentIndex].sa_aMorphMapList.Count();
- INDEX ctmmLast = _aSortArray[iLastIndex].sa_aMorphMapList.Count();
- // check if vertices have same weight and morph maps count
- CHECK(ctwmCurent,ctwmLast);
- CHECK(ctmmCurent,ctmmLast);
- // check if vertices have same weight map factors
- for(INDEX iwm=0;iwm<ctwmCurent;iwm++)
- {
- // get weight map indices
- INDEX iwmCurent = _aSortArray[iCurentIndex].sa_aWeightMapList[iwm].vl_iIndex;
- INDEX iwmLast = _aSortArray[iLastIndex].sa_aWeightMapList[iwm].vl_iIndex;
- // get wertex weight indices
- INDEX iwwCurent = _aSortArray[iCurentIndex].sa_aWeightMapList[iwm].vl_iSubIndex;
- INDEX iwwLast = _aSortArray[iLastIndex].sa_aWeightMapList[iwm].vl_iSubIndex;
- // if weight map factors are diferent
- CHECKF(pMeshLOD->mlod_aWeightMaps[iwmCurent].mwm_aVertexWeight[iwwCurent].mww_fWeight,pMeshLOD->mlod_aWeightMaps[iwmLast].mwm_aVertexWeight[iwwLast].mww_fWeight);
- }
- // check if vertices have same morph map factors
- for(INDEX imm=0;imm<ctmmCurent;imm++)
- {
- // get morph map indices
- INDEX immCurent = _aSortArray[iCurentIndex].sa_aMorphMapList[imm].vl_iIndex;
- INDEX immLast = _aSortArray[iLastIndex].sa_aMorphMapList[imm].vl_iIndex;
- // get mesh vertex morph indices
- INDEX imwmCurent = _aSortArray[iCurentIndex].sa_aMorphMapList[imm].vl_iSubIndex;
- INDEX imwmLast = _aSortArray[iLastIndex].sa_aMorphMapList[imm].vl_iSubIndex;
-
- // if mesh morph map params are diferent return
- CHECKF(pMeshLOD->mlod_aMorphMaps[immCurent].mmp_aMorphMap[imwmCurent].mwm_x,
- pMeshLOD->mlod_aMorphMaps[immLast].mmp_aMorphMap[imwmLast].mwm_x);
- CHECKF(pMeshLOD->mlod_aMorphMaps[immCurent].mmp_aMorphMap[imwmCurent].mwm_y,
- pMeshLOD->mlod_aMorphMaps[immLast].mmp_aMorphMap[imwmLast].mwm_y);
- CHECKF(pMeshLOD->mlod_aMorphMaps[immCurent].mmp_aMorphMap[imwmCurent].mwm_z,
- pMeshLOD->mlod_aMorphMaps[immLast].mmp_aMorphMap[imwmLast].mwm_z);
- CHECKF(pMeshLOD->mlod_aMorphMaps[immCurent].mmp_aMorphMap[imwmCurent].mwm_nx,
- pMeshLOD->mlod_aMorphMaps[immLast].mmp_aMorphMap[imwmLast].mwm_nx);
- CHECKF(pMeshLOD->mlod_aMorphMaps[immCurent].mmp_aMorphMap[imwmCurent].mwm_ny,
- pMeshLOD->mlod_aMorphMaps[immLast].mmp_aMorphMap[imwmLast].mwm_ny);
- CHECKF(pMeshLOD->mlod_aMorphMaps[immCurent].mmp_aMorphMap[imwmCurent].mwm_nz,
- pMeshLOD->mlod_aMorphMaps[immLast].mmp_aMorphMap[imwmLast].mwm_nz);
- }
- return 0;
- }
- // normalize weights in mlod
- void CMesh::NormalizeWeightsInLod(MeshLOD &mlod)
- {
- CStaticArray<float> aWeightFactors;
- int ctvtx = mlod.mlod_aVertices.Count();
- int ctwm = mlod.mlod_aWeightMaps.Count();
- // create array for weights
- aWeightFactors.New(ctvtx);
- memset(&aWeightFactors[0],0,sizeof(aWeightFactors[0])*ctvtx);
- int iwm=0;
- for(;iwm<ctwm;iwm++)
- {
- MeshWeightMap &mwm = mlod.mlod_aWeightMaps[iwm];
- for(int iww=0;iww<mwm.mwm_aVertexWeight.Count();iww++)
- {
- MeshVertexWeight &mwh = mwm.mwm_aVertexWeight[iww];
- aWeightFactors[mwh.mww_iVertex] += mwh.mww_fWeight;
- }
- }
- for(iwm=0;iwm<ctwm;iwm++)
- {
- MeshWeightMap &mwm = mlod.mlod_aWeightMaps[iwm];
- for(int iww=0;iww<mwm.mwm_aVertexWeight.Count();iww++)
- {
- MeshVertexWeight &mwh = mwm.mwm_aVertexWeight[iww];
- mwh.mww_fWeight /= aWeightFactors[mwh.mww_iVertex];
- }
- }
- // clear weight array
- aWeightFactors.Clear();
- }
- // normalize weights in mesh
- void CMesh::NormalizeWeights()
- {
- INDEX ctmlods = msh_aMeshLODs.Count();
- for(INDEX imlod=0;imlod<ctmlods;imlod++)
- {
- // normalize each lod
- NormalizeWeightsInLod(msh_aMeshLODs[imlod]);
- }
- }
- // add new mesh lod to mesh
- void CMesh::AddMeshLod(MeshLOD &mlod)
- {
- INDEX ctmlods = msh_aMeshLODs.Count();
- msh_aMeshLODs.Expand(ctmlods+1);
- msh_aMeshLODs[ctmlods] = mlod;
- }
- // remove mesh lod from mesh
- void CMesh::RemoveMeshLod(MeshLOD *pmlodRemove)
- {
- INDEX ctmlod = msh_aMeshLODs.Count();
- // create temp space for skeleton lods
- CStaticArray<struct MeshLOD> aTempMLODs;
- aTempMLODs.New(ctmlod-1);
- INDEX iIndexSrc=0;
- // for each skeleton lod in skeleton
- for(INDEX imlod=0;imlod<ctmlod;imlod++)
- {
- MeshLOD *pmlod = &msh_aMeshLODs[imlod];
- // copy all skeleton lods except the selected one
- if(pmlod != pmlodRemove)
- {
- aTempMLODs[iIndexSrc] = *pmlod;
- iIndexSrc++;
- }
- }
- // copy temp array of skeleton lods back in skeleton
- msh_aMeshLODs.CopyArray(aTempMLODs);
- // clear temp skleletons lods array
- aTempMLODs.Clear();
- }
- // write to stream
- void CMesh::Write_t(CTStream *ostrFile)
- {
- INDEX ctmlods = msh_aMeshLODs.Count();
- // write id
- ostrFile->WriteID_t(CChunkID(MESH_ID));
- // write version
- (*ostrFile)<<(INDEX)MESH_VERSION;
- // write mlod count
- (*ostrFile)<<ctmlods;
- // for each lod in mesh
- for(INDEX imlod=0;imlod<ctmlods;imlod++) {
- MeshLOD &mLod = msh_aMeshLODs[imlod];
- INDEX ctVx = mLod.mlod_aVertices.Count(); // vertex count
- INDEX ctUV = mLod.mlod_aUVMaps.Count(); // uvmaps count
- INDEX ctSf = mLod.mlod_aSurfaces.Count(); // surfaces count
- INDEX ctWM = mLod.mlod_aWeightMaps.Count(); // weight maps count
- INDEX ctMM = mLod.mlod_aMorphMaps.Count(); // morph maps count
- // write source file name
- (*ostrFile)<<mLod.mlod_fnSourceFile;
- // write max distance
- (*ostrFile)<<mLod.mlod_fMaxDistance;
- // write flags
- (*ostrFile)<<mLod.mlod_ulFlags;
- // write wertex count
- (*ostrFile)<<ctVx;
- // write wertices
- ostrFile->Write_t(&mLod.mlod_aVertices[0],sizeof(MeshVertex)*ctVx);
- // write normals
- ostrFile->Write_t(&mLod.mlod_aNormals[0],sizeof(MeshNormal)*ctVx);
- // write uvmaps count
- (*ostrFile)<<ctUV;
- // write uvmaps
- for(int iuv=0;iuv<ctUV;iuv++) {
- // write uvmap ID
- CTString strNameID = ska_GetStringFromTable(mLod.mlod_aUVMaps[iuv].muv_iID);
- (*ostrFile)<<strNameID;
- // write uvmaps texcordinates
- ostrFile->Write_t(&mLod.mlod_aUVMaps[iuv].muv_aTexCoords[0],sizeof(MeshTexCoord)*ctVx);
- }
- // write surfaces count
- ostrFile->Write_t(&ctSf,sizeof(INDEX));
- // write surfaces
- for(INDEX isf=0;isf<ctSf;isf++) {
- MeshSurface &msrf = mLod.mlod_aSurfaces[isf];
- INDEX ctTris = msrf.msrf_aTriangles.Count();
- CTString strSurfaceID = ska_GetStringFromTable(msrf.msrf_iSurfaceID);
- // write surface ID
- (*ostrFile)<<strSurfaceID;
- // write first vertex
- (*ostrFile)<<msrf.msrf_iFirstVertex;
- // write vertices count
- (*ostrFile)<<msrf.msrf_ctVertices;
- // write tris count
- (*ostrFile)<<ctTris;
- // write triangles
- ostrFile->Write_t(&mLod.mlod_aSurfaces[isf].msrf_aTriangles[0],sizeof(MeshTriangle)*ctTris);
- // write bool that this surface has a shader
- INDEX bShaderExists = (msrf.msrf_pShader!=NULL);
- (*ostrFile)<<bShaderExists;
- if(bShaderExists) {
- // get shader decription
- ShaderDesc shDesc;
- msrf.msrf_pShader->GetShaderDesc(shDesc);
- INDEX cttx=shDesc.sd_astrTextureNames.Count();
- INDEX cttc=shDesc.sd_astrTexCoordNames.Count();
- INDEX ctcol=shDesc.sd_astrColorNames.Count();
- INDEX ctfl=shDesc.sd_astrFloatNames.Count();
- // data count must be at same as size defined in shader or higher
- ASSERT(cttx<=msrf.msrf_ShadingParams.sp_aiTextureIDs.Count());
- ASSERT(cttc<=msrf.msrf_ShadingParams.sp_aiTexCoordsIndex.Count());
- ASSERT(ctcol<=msrf.msrf_ShadingParams.sp_acolColors.Count());
- ASSERT(ctfl<=msrf.msrf_ShadingParams.sp_afFloats.Count());
- ASSERT(msrf.msrf_pShader->GetShaderDesc!=NULL);
- // write texture count
- (*ostrFile)<<cttx;
- // write texture coords count
- (*ostrFile)<<cttc;
- // write color count
- (*ostrFile)<<ctcol;
- // write float count
- (*ostrFile)<<ctfl;
- ASSERT(msrf.msrf_pShader!=NULL);
- // write shader name
- CTString strShaderName;
- strShaderName = msrf.msrf_pShader->GetName();
- (*ostrFile)<<strShaderName;
- // write shader texture IDs
- for(INDEX itx=0;itx<cttx;itx++)
- {
- INDEX iTexID = msrf.msrf_ShadingParams.sp_aiTextureIDs[itx];
- (*ostrFile)<<ska_GetStringFromTable(iTexID);
- }
- // write shader texture coords indices
- for(INDEX itc=0;itc<cttc;itc++)
- {
- INDEX iTexCoorsIndex = msrf.msrf_ShadingParams.sp_aiTexCoordsIndex[itc];
- (*ostrFile)<<iTexCoorsIndex;
- }
- // write shader colors
- for(INDEX icol=0;icol<ctcol;icol++)
- {
- COLOR colColor = msrf.msrf_ShadingParams.sp_acolColors[icol];
- (*ostrFile)<<colColor;
- }
- // write shader floats
- for(INDEX ifl=0;ifl<ctfl;ifl++)
- {
- FLOAT fFloat = msrf.msrf_ShadingParams.sp_afFloats[ifl];
- (*ostrFile)<<fFloat;
- }
- // write shader flags
- ULONG ulFlags = msrf.msrf_ShadingParams.sp_ulFlags;
- (*ostrFile)<<ulFlags;
- }
- }
- // write weightmaps count
- (*ostrFile)<<ctWM;
- // for each weightmap in array
- for(INDEX iwm=0;iwm<ctWM;iwm++)
- {
- INDEX ctWw = mLod.mlod_aWeightMaps[iwm].mwm_aVertexWeight.Count();
- // write wertex weight map ID
- CTString pstrNameID = ska_GetStringFromTable(mLod.mlod_aWeightMaps[iwm].mwm_iID);
- (*ostrFile)<<pstrNameID;
- // write wertex weights count
- (*ostrFile)<<ctWw;
- // write wertex weights
- ostrFile->Write_t(&mLod.mlod_aWeightMaps[iwm].mwm_aVertexWeight[0],sizeof(MeshVertexWeight)*ctWw);
- }
- // write morphmaps count
- (*ostrFile)<<ctMM;
- for(INDEX imm=0;imm<ctMM;imm++)
- {
- INDEX ctms = mLod.mlod_aMorphMaps[imm].mmp_aMorphMap.Count();
- // write ID
- CTString pstrNameID = ska_GetStringFromTable(mLod.mlod_aMorphMaps[imm].mmp_iID);
- (*ostrFile)<<pstrNameID;
- // write bRelative
- (*ostrFile)<<mLod.mlod_aMorphMaps[imm].mmp_bRelative;
- //ostrFile->Write_t(&mLod.mlod_aMorphMaps[imm].mmp_bRelative,sizeof(BOOL));
- // write morph sets count
- ostrFile->Write_t(&ctms,sizeof(INDEX));
- // write morph sets
- ostrFile->Write_t(&mLod.mlod_aMorphMaps[imm].mmp_aMorphMap[0],sizeof(MeshVertexMorph)*ctms);
- }
- }
- }
- //read from stream
- void CMesh::Read_t(CTStream *istrFile)
- {
- INDEX ctmlods;
- INDEX iFileVersion;
- // read chunk id
- istrFile->ExpectID_t(CChunkID(MESH_ID));
- // check file version
- (*istrFile)>>iFileVersion;
-
- // if file version is not 11 nor 12
- if(iFileVersion != 11 && iFileVersion!=12) {
- ThrowF_t(TRANS("File '%s'.\nInvalid Mesh file version.\nExpected Ver \"%d\" but found \"%d\"\n"),
- (const char*)istrFile->GetDescription(),MESH_VERSION,iFileVersion);
- return;
- }
- // read mlod count
- (*istrFile)>>ctmlods;
- // for each lod in mesh
- for(INDEX imlod=0;imlod<ctmlods;imlod++) {
- // expand mlod count for one
- INDEX ctMeshLODs = msh_aMeshLODs.Count();
- msh_aMeshLODs.Expand(ctMeshLODs+1);
- MeshLOD &mLod = msh_aMeshLODs[ctMeshLODs];
- INDEX ctVx; // vertex count
- INDEX ctUV; // uvmaps count
- INDEX ctSf; // surfaces count
- INDEX ctWM; // weight maps count
- INDEX ctMM; // morph maps count
-
- // read source file name
- (*istrFile)>>mLod.mlod_fnSourceFile;
- // read max distance
- (*istrFile)>>mLod.mlod_fMaxDistance;
- // read flags
- (*istrFile)>>mLod.mlod_ulFlags;
- // :)
- if(iFileVersion<=11) {
- mLod.mlod_ulFlags = 0;
- }
- if(mLod.mlod_ulFlags==0xCDCDCDCD) {
- mLod.mlod_ulFlags = 0;
- }
- // read vertex count
- (*istrFile)>>ctVx;
- // create vertex and normal arrays
- mLod.mlod_aVertices.New(ctVx);
- mLod.mlod_aNormals.New(ctVx);
- // read wertices
- istrFile->Read_t(&mLod.mlod_aVertices[0],sizeof(MeshVertex)*ctVx);
- // read normals
- istrFile->Read_t(&mLod.mlod_aNormals[0],sizeof(MeshNormal)*ctVx);
- // read uvmaps count
- (*istrFile)>>ctUV;
- // create array for uvmaps
- mLod.mlod_aUVMaps.New(ctUV);
- // read uvmaps
- for(int iuv=0;iuv<ctUV;iuv++) {
- // read uvmap ID
- CTString strNameID;
- (*istrFile)>>strNameID;
- mLod.mlod_aUVMaps[iuv].muv_iID = ska_GetIDFromStringTable(strNameID);
- // create array for uvmaps texcordinates
- mLod.mlod_aUVMaps[iuv].muv_aTexCoords.New(ctVx);
- // read uvmap texcordinates
- istrFile->Read_t(&mLod.mlod_aUVMaps[iuv].muv_aTexCoords[0],sizeof(MeshTexCoord)*ctVx);
- }
- // read surfaces count
- (*istrFile)>>ctSf;
- // create array for surfaces
- mLod.mlod_aSurfaces.New(ctSf);
- // read surfaces
- for(INDEX isf=0;isf<ctSf;isf++) {
- INDEX ctTris;
- MeshSurface &msrf = mLod.mlod_aSurfaces[isf];
- // read surface ID
- CTString strSurfaceID;
- (*istrFile)>>strSurfaceID;
- msrf.msrf_iSurfaceID = ska_GetIDFromStringTable(strSurfaceID);
- // read first vertex
- (*istrFile)>>msrf.msrf_iFirstVertex;
- // read vertices count
- (*istrFile)>>msrf.msrf_ctVertices;
- // read tris count
- (*istrFile)>>ctTris;
- // create triangles array
- mLod.mlod_aSurfaces[isf].msrf_aTriangles.New(ctTris);
- // read triangles
- istrFile->Read_t(&mLod.mlod_aSurfaces[isf].msrf_aTriangles[0],sizeof(MeshTriangle)*ctTris);
- // read bool that this surface has a shader
- INDEX bShaderExists;
- (*istrFile)>>bShaderExists;
- // if shader exists read its params
- if(bShaderExists) {
- INDEX cttx,cttc,ctcol,ctfl;
- // read texture count
- (*istrFile)>>cttx;
- // read texture coords count
- (*istrFile)>>cttc;
- // read color count
- (*istrFile)>>ctcol;
- // read float count
- (*istrFile)>>ctfl;
- CShader *pshMeshShader = NULL;
- ShaderParams *pshpShaderParams = NULL;
- CShader shDummyShader; // dummy shader if shader is not found
- ShaderParams shpDummyShaderParams;// dummy shader params if shader is not found
- // read shader name
- CTString strShaderName;
- (*istrFile)>>strShaderName;
- // try to load shader
- try{
- msrf.msrf_pShader = _pShaderStock->Obtain_t(strShaderName);
- pshMeshShader = msrf.msrf_pShader;
- pshpShaderParams = &msrf.msrf_ShadingParams;
- } catch(char *strErr) {
- CPrintF("%s\n",strErr);
- msrf.msrf_pShader = NULL;
- pshMeshShader = &shDummyShader;
- pshpShaderParams = &shpDummyShaderParams;
- }
- // if mesh shader exisits
- if(msrf.msrf_pShader!=NULL) {
- // get shader description
- ShaderDesc shDesc;
- msrf.msrf_pShader->GetShaderDesc(shDesc);
- // check if saved params count match shader params count
- if(shDesc.sd_astrTextureNames.Count() != cttx) ThrowF_t("File '%s'\nWrong texture count %d",(const char*)GetName(),cttx);
- if(shDesc.sd_astrTexCoordNames.Count() != cttc) ThrowF_t("File '%s'\nWrong uvmaps count %d",(const char*)GetName(),cttc);
- if(shDesc.sd_astrColorNames.Count() != ctcol) ThrowF_t("File '%s'\nWrong colors count %d",(const char*)GetName(),ctcol);
- if(shDesc.sd_astrFloatNames.Count() != ctfl) ThrowF_t("File '%s'\nWrong floats count %d",(const char*)GetName(),ctfl);
- }
- // create arrays for shader params
- pshpShaderParams->sp_aiTextureIDs.New(cttx);
- pshpShaderParams->sp_aiTexCoordsIndex.New(cttc);
- pshpShaderParams->sp_acolColors.New(ctcol);
- pshpShaderParams->sp_afFloats.New(ctfl);
- // read shader texture IDs
- for(INDEX itx=0;itx<cttx;itx++) {
- CTString strTexID;
- (*istrFile)>>strTexID;
- INDEX iTexID = ska_GetIDFromStringTable(strTexID);
- pshpShaderParams->sp_aiTextureIDs[itx] = iTexID;
- }
- // read shader texture coords indices
- for(INDEX itc=0;itc<cttc;itc++) {
- INDEX iTexCoorsIndex;
- (*istrFile)>>iTexCoorsIndex;
- pshpShaderParams->sp_aiTexCoordsIndex[itc] = iTexCoorsIndex;
- }
- // read shader colors
- for(INDEX icol=0;icol<ctcol;icol++) {
- COLOR colColor;
- (*istrFile)>>colColor;
- pshpShaderParams->sp_acolColors[icol] = colColor;
- }
- // read shader floats
- for(INDEX ifl=0;ifl<ctfl;ifl++) {
- FLOAT fFloat;
- (*istrFile)>>fFloat;
- pshpShaderParams->sp_afFloats[ifl] = fFloat;
- }
- // there were no flags in shader before ver 12
- if(iFileVersion>11) {
- ULONG ulFlags;
- (*istrFile)>>ulFlags;
- pshpShaderParams->sp_ulFlags = ulFlags;
- } else {
- pshpShaderParams->sp_ulFlags = 0;
- }
- } else {
- // this surface does not have shader
- msrf.msrf_pShader=NULL;
- }
- }
- // read weightmaps count
- (*istrFile)>>ctWM;
- // create weightmap array
- mLod.mlod_aWeightMaps.New(ctWM);
- // read each weightmap
- for(INDEX iwm=0;iwm<ctWM;iwm++) {
- // read weightmap ID
- CTString pstrNameID;
- (*istrFile)>>pstrNameID;
- mLod.mlod_aWeightMaps[iwm].mwm_iID = ska_GetIDFromStringTable(pstrNameID);
- // read wertex weight count
- INDEX ctWw;
- (*istrFile)>>ctWw;
- // create wertex weight array
- mLod.mlod_aWeightMaps[iwm].mwm_aVertexWeight.New(ctWw);
- // read wertex weights
- istrFile->Read_t(&mLod.mlod_aWeightMaps[iwm].mwm_aVertexWeight[0],sizeof(MeshVertexWeight)*ctWw);
- }
- // read morphmap count
- (*istrFile)>>ctMM;
- // create morphmaps array
- mLod.mlod_aMorphMaps.New(ctMM);
- // read morphmaps
- for(INDEX imm=0;imm<ctMM;imm++) {
- // read morphmap ID
- CTString pstrNameID;
- (*istrFile)>>pstrNameID;
- mLod.mlod_aMorphMaps[imm].mmp_iID = ska_GetIDFromStringTable(pstrNameID);
- // read bRelative
- (*istrFile)>>mLod.mlod_aMorphMaps[imm].mmp_bRelative;
- // read morph sets count
- INDEX ctms;
- (*istrFile)>>ctms;
- // create morps sets array
- mLod.mlod_aMorphMaps[imm].mmp_aMorphMap.New(ctms);
- // read morph sets
- istrFile->Read_t(&mLod.mlod_aMorphMaps[imm].mmp_aMorphMap[0],sizeof(MeshVertexMorph)*ctms);
- }
- }
- }
- // clear mesh
- void CMesh::Clear(void)
- {
- // for each LOD
- INDEX ctmlod = msh_aMeshLODs.Count();
- for (INDEX imlod=0; imlod<ctmlod; imlod++)
- {
- // for each surface, clear the triangles list
- MeshLOD &mlod = msh_aMeshLODs[imlod];
- INDEX ctsrf = mlod.mlod_aSurfaces.Count();
- for (INDEX isrf=0;isrf<ctsrf;isrf++)
- {
- MeshSurface &msrf = mlod.mlod_aSurfaces[isrf];
- msrf.msrf_aTriangles.Clear();
- // release shader form stock
- if(msrf.msrf_pShader!=NULL) _pShaderStock->Release(msrf.msrf_pShader);
- msrf.msrf_pShader = NULL;
- }
- // clear the surfaces array
- mlod.mlod_aSurfaces.Clear();
- // for each uvmap, clear the texcord list
- INDEX ctuvm = mlod.mlod_aUVMaps.Count();
- for (INDEX iuvm=0;iuvm<ctuvm;iuvm++)
- {
- mlod.mlod_aUVMaps[iuvm].muv_aTexCoords.Clear();
- }
- // clear the uvmaps array
- mlod.mlod_aUVMaps.Clear();
- // clear the vertices array
- mlod.mlod_aVertices.Clear();
- // clear the normals array
- mlod.mlod_aNormals.Clear();
- }
- // in the end, clear all LODs
- msh_aMeshLODs.Clear();
- }
- // Count used memory
- SLONG CMesh::GetUsedMemory(void)
- {
- SLONG slMemoryUsed = sizeof(*this);
- INDEX ctmlods = msh_aMeshLODs.Count();
- for(INDEX imlod=0;imlod<ctmlods;imlod++) {
- MeshLOD &mlod = msh_aMeshLODs[imlod];
- slMemoryUsed+=sizeof(mlod);
- slMemoryUsed+=mlod.mlod_aVertices.Count() * sizeof(MeshVertex);
- slMemoryUsed+=mlod.mlod_aNormals.Count() * sizeof(MeshNormal);
- // for each uvmap
- INDEX ctuvmaps = mlod.mlod_aUVMaps.Count();
- for(INDEX iuvm=0;iuvm<ctuvmaps;iuvm++) {
- MeshUVMap &uvmap = mlod.mlod_aUVMaps[iuvm];
- slMemoryUsed+=sizeof(uvmap);
- slMemoryUsed+=uvmap.muv_aTexCoords.Count() * sizeof(MeshTexCoord);
- }
- // for each surface
- INDEX ctmsrf = mlod.mlod_aSurfaces.Count();
- for(INDEX imsrf=0;imsrf<ctmsrf;imsrf++) {
- MeshSurface &msrf = mlod.mlod_aSurfaces[imsrf];
- slMemoryUsed+=sizeof(msrf);
- slMemoryUsed+=msrf.msrf_aTriangles.Count() * sizeof(MeshTriangle);
- slMemoryUsed+=sizeof(ShaderParams);
- slMemoryUsed+=sizeof(INDEX) * msrf.msrf_ShadingParams.sp_aiTextureIDs.Count();
- slMemoryUsed+=sizeof(INDEX) * msrf.msrf_ShadingParams.sp_aiTexCoordsIndex.Count();
- slMemoryUsed+=sizeof(COLOR) * msrf.msrf_ShadingParams.sp_acolColors.Count();
- slMemoryUsed+=sizeof(FLOAT) * msrf.msrf_ShadingParams.sp_afFloats.Count();
- }
- // for each weight map
- INDEX ctwm = mlod.mlod_aWeightMaps.Count();
- for(INDEX iwm=0;iwm<ctwm;iwm++) {
- MeshWeightMap &mwm = mlod.mlod_aWeightMaps[iwm];
- slMemoryUsed+=sizeof(mwm);
- slMemoryUsed+=mwm.mwm_aVertexWeight.Count() * sizeof(MeshVertexWeight);
- }
- // for each morphmap
- INDEX ctmm = mlod.mlod_aMorphMaps.Count();
- for(INDEX imm=0;imm<ctmm;imm++) {
- MeshMorphMap &mmm = mlod.mlod_aMorphMaps[imm];
- slMemoryUsed+=sizeof(mmm);
- slMemoryUsed+=mmm.mmp_aMorphMap.Count() * sizeof(MeshVertexMorph);
- }
- }
- return slMemoryUsed;
- }
|