From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/lod__character__shape_8cpp-source.html | 761 +++++++++++++++++++++ 1 file changed, 761 insertions(+) create mode 100644 docs/doxygen/nel/lod__character__shape_8cpp-source.html (limited to 'docs/doxygen/nel/lod__character__shape_8cpp-source.html') diff --git a/docs/doxygen/nel/lod__character__shape_8cpp-source.html b/docs/doxygen/nel/lod__character__shape_8cpp-source.html new file mode 100644 index 00000000..88474992 --- /dev/null +++ b/docs/doxygen/nel/lod__character__shape_8cpp-source.html @@ -0,0 +1,761 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

lod_character_shape.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000-2002 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 #include "std3d.h"
+00027 
+00028 #include "3d/lod_character_shape.h"
+00029 #include "nel/misc/vectord.h"
+00030 #include "3d/fast_floor.h"
+00031 #include "3d/lod_character_texture.h"
+00032 #include "nel/misc/triangle.h"
+00033 #include "nel/misc/polygon.h"
+00034 
+00035 
+00036 using namespace std;
+00037 using namespace NLMISC;
+00038 
+00039 
+00040 namespace NL3D 
+00041 {
+00042 
+00043 
+00044 // ***************************************************************************
+00045 // ***************************************************************************
+00046 // CLodCharacterShape
+00047 // ***************************************************************************
+00048 // ***************************************************************************
+00049 
+00050 
+00051 // ***************************************************************************
+00052 const CLodCharacterShapeBuild::CPixelInfo               CLodCharacterShapeBuild::CPixelInfo::EmptyPixel(
+00053                 CVector::Null, CVector(1000,0,0));
+00054 
+00055 
+00056 // ***************************************************************************
+00057 CLodCharacterShapeBuild::CLodCharacterShapeBuild()
+00058 {
+00059         _Width= 0;
+00060         _Height= 0;
+00061 }
+00062 
+00063 
+00064 // ***************************************************************************
+00065 void    CLodCharacterShapeBuild::compile(const std::vector<bool> &triangleSelection, uint textureOverSample)
+00066 {
+00067         nlassert(UVs.size()==Vertices.size());
+00068         nlassert(Normals.size()==Vertices.size());
+00069 
+00070         // take the sqrtf.
+00071         textureOverSample= (uint)sqrtf((float)textureOverSample);
+00072         textureOverSample= max(textureOverSample, 1U);
+00073 
+00074         _Width= NL3D_CLOD_TEXT_WIDTH;
+00075         _Height= NL3D_CLOD_TEXT_HEIGHT;
+00076 
+00077         uint    wOver= _Width*textureOverSample;
+00078         uint    hOver= _Height*textureOverSample;
+00079         std::vector<CPixelInfo>         overTextureInfo;
+00080 
+00081         // do some tri selection?
+00082         bool    triSelectOk= triangleSelection.size()==TriangleIndices.size()/3;
+00083 
+00084 
+00085         // **** reset the texture and init with "empty" pixel (ie normal.x==1000, which is not possible because normal.norm()==1)
+00086         _TextureInfo.resize(_Width*_Height);
+00087         fill(_TextureInfo.begin(), _TextureInfo.end(), CPixelInfo::EmptyPixel);
+00088         // do it to the oversampled texture
+00089         overTextureInfo.resize(wOver*hOver, CPixelInfo::EmptyPixel);
+00090 
+00091 
+00092         // **** For each triangle in the shape, polyfill this triangle from a texture view, in the overSampledTexture
+00093         CPolygon2D      poly;
+00094         poly.Vertices.resize(3);
+00095         for(uint i=0; i<TriangleIndices.size();i+=3)
+00096         {
+00097                 // if selection OK, and the tri is not selected, skip
+00098                 if(triSelectOk && !triangleSelection[i/3])
+00099                         continue;
+00100 
+00101                 // Setup triangle.
+00102                 // -----------
+00103                 uint    idx[3];
+00104                 idx[0]= TriangleIndices[i+0];
+00105                 idx[1]= TriangleIndices[i+1];
+00106                 idx[2]= TriangleIndices[i+2];
+00107                 // compute corners UVs, in texel size
+00108                 CTriangle               triangleUV;
+00109                 triangleUV.V0= CVector(UVs[idx[0]].U*wOver, UVs[idx[0]].V*hOver, 0);
+00110                 triangleUV.V1= CVector(UVs[idx[1]].U*wOver, UVs[idx[1]].V*hOver, 0);
+00111                 triangleUV.V2= CVector(UVs[idx[2]].U*wOver, UVs[idx[2]].V*hOver, 0);
+00112                 // compute corners pixelInfos 
+00113                 CPixelInfo              pInf[3];
+00114                 for(uint corner=0; corner<3; corner++)
+00115                 {
+00116                         pInf[corner].Pos= Vertices[idx[corner]];
+00117                         pInf[corner].Normal= Normals[idx[corner]];
+00118                 }
+00119                 // Compute Gradients
+00120                 CVector         GradPosX, GradPosY, GradPosZ;
+00121                 CVector         GradNormalX, GradNormalY, GradNormalZ;
+00122                 triangleUV.computeGradient(pInf[0].Pos.x, pInf[1].Pos.x, pInf[2].Pos.x, GradPosX);
+00123                 triangleUV.computeGradient(pInf[0].Pos.y, pInf[1].Pos.y, pInf[2].Pos.y, GradPosY);
+00124                 triangleUV.computeGradient(pInf[0].Pos.z, pInf[1].Pos.z, pInf[2].Pos.z, GradPosZ);
+00125                 triangleUV.computeGradient(pInf[0].Normal.x, pInf[1].Normal.x, pInf[2].Normal.x, GradNormalX);
+00126                 triangleUV.computeGradient(pInf[0].Normal.y, pInf[1].Normal.y, pInf[2].Normal.y, GradNormalY);
+00127                 triangleUV.computeGradient(pInf[0].Normal.z, pInf[1].Normal.z, pInf[2].Normal.z, GradNormalZ);
+00128                 // Compute Gradients offset
+00129                 float           OffPosX, OffPosY, OffPosZ;
+00130                 float           OffNormalX, OffNormalY, OffNormalZ;
+00131                 OffPosX= pInf[0].Pos.x - GradPosX*triangleUV.V0;
+00132                 OffPosY= pInf[0].Pos.y - GradPosY*triangleUV.V0;
+00133                 OffPosZ= pInf[0].Pos.z - GradPosZ*triangleUV.V0;
+00134                 OffNormalX= pInf[0].Normal.x - GradNormalX*triangleUV.V0;
+00135                 OffNormalY= pInf[0].Normal.y - GradNormalY*triangleUV.V0;
+00136                 OffNormalZ= pInf[0].Normal.z - GradNormalZ*triangleUV.V0;
+00137 
+00138 
+00139                 // PolyFiller
+00140                 // -----------
+00141                 CVector2f       dCenter(0.5f, 0.5f);
+00142                 // select texels if their centers is in the triangle
+00143                 poly.Vertices[0]= triangleUV.V0-dCenter;
+00144                 poly.Vertices[1]= triangleUV.V1-dCenter;
+00145                 poly.Vertices[2]= triangleUV.V2-dCenter;
+00146                 // polyFiller
+00147                 CPolygon2D::TRasterVect rasters;
+00148                 sint    minY;
+00149                 poly.computeBorders(rasters, minY);
+00150                 for(sint y=0;y<(sint)rasters.size();y++)
+00151                 {
+00152                         sint x0= rasters[y].first;
+00153                         sint x1= rasters[y].second;
+00154                         CVector v;
+00155                         // get the center coord of this texel
+00156                         v.y= y+minY+0.5f;
+00157                         v.z= 0;
+00158                         for(sint x=x0;x<=x1;x++)
+00159                         {
+00160                                 // get the center coord of this texel
+00161                                 v.x= x+0.5f;
+00162                                 // Compute Pos/Normal on this texel.
+00163                                 CPixelInfo      texelInf;
+00164                                 texelInf.Pos.x= OffPosX + GradPosX * v;
+00165                                 texelInf.Pos.y= OffPosY + GradPosY * v;
+00166                                 texelInf.Pos.z= OffPosZ + GradPosZ * v;
+00167                                 texelInf.Normal.x= OffNormalX + GradNormalX * v;
+00168                                 texelInf.Normal.y= OffNormalY + GradNormalY * v;
+00169                                 texelInf.Normal.z= OffNormalZ + GradNormalZ * v;
+00170                                 // normalize.
+00171                                 texelInf.Normal.normalize();
+00172                                 // Store (NB: overwrite any pixel)
+00173                                 sint    texX= ((uint)x)%wOver;
+00174                                 sint    texY= ((uint)y+minY)%hOver;
+00175                                 overTextureInfo[texY*wOver+texX]= texelInf;
+00176                         }
+00177                 }
+00178 
+00179         }
+00180 
+00181 
+00182         // **** Down sample the overSampled texture.
+00183         sint    x,y;
+00184         if(textureOverSample==1)
+00185         {
+00186                 _TextureInfo= overTextureInfo;
+00187         }
+00188         else
+00189         {
+00190                 // eg: 3 gives 1. delta ranges from -1 to 1.
+00191                 float   middle= (textureOverSample-1)/2.f;
+00192 
+00193                 // for all pixels.
+00194                 for(y=0;y<(sint)_Height;y++)
+00195                 {
+00196                         for(x=0;x<(sint)_Width;x++)
+00197                         {
+00198                                 // for all samples, take the best one.
+00199                                 sint            xo, yo;
+00200                                 float           bestDist= FLT_MAX;
+00201                                 CPixelInfo      bestPixel= CPixelInfo::EmptyPixel;
+00202                                 for(yo=0;yo<(sint)textureOverSample;yo++)
+00203                                 {
+00204                                         for(xo=0;xo<(sint)textureOverSample;xo++)
+00205                                         {
+00206                                                 // compute distance to the pixel center.
+00207                                                 float   dist= sqr(yo-middle)+sqr(xo-middle);
+00208                                                 const CPixelInfo        &overPixel= overTextureInfo[(y*textureOverSample+yo)*wOver+(x*textureOverSample+xo)];
+00209                                                 // if the overPixel is not empty.
+00210                                                 if( !(overPixel==CPixelInfo::EmptyPixel) )
+00211                                                 {
+00212                                                         // take it if the best: nearest to the pixel center.
+00213                                                         if(dist<bestDist)
+00214                                                         {
+00215                                                                 bestDist= dist;
+00216                                                                 bestPixel= overPixel;
+00217                                                         }
+00218                                                 }
+00219                                         }
+00220                                 }
+00221 
+00222                                 // fill textureInfo
+00223                                 _TextureInfo[y*_Width+x]= bestPixel;
+00224                         }
+00225                 }
+00226         }
+00227 
+00228 
+00229         // **** Dilate texture 1 time: each empty pixel info get neighbor full pixel (8box)
+00230         // copy the non dilated texture
+00231         std::vector<CPixelInfo>         tmpTextureInfo= _TextureInfo;
+00232         // process all pixels
+00233         for(y=0;y<(sint)_Height;y++)
+00234         {
+00235                 sint    y0=y-1, y1=y+1;
+00236                 y0= max(y0, 0);
+00237                 y1= min(y1, (sint)_Height-1);
+00238                 for(x=0;x<(sint)_Width;x++)
+00239                 {
+00240                         CPixelInfo      &texelInf= _TextureInfo[y*_Width+x];
+00241                         // if an empty pixel.
+00242                         if(texelInf==CPixelInfo::EmptyPixel)
+00243                         {
+00244                                 // dilate: look around for non empty pixel.
+00245                                 sint    x0=x-1, x1=x+1;
+00246                                 x0= max(x0, 0);
+00247                                 x1= min(x1, (sint)_Width-1);
+00248                                 // For the 8 possible pixels (nb: look us too, but doesn't matter since we are an empty pixel)
+00249                                 for(sint yb= y0; yb<=y1;yb++)
+00250                                 {
+00251                                         for(sint xb= x0; xb<=x1;xb++)
+00252                                         {
+00253                                                 // if the neighbor is not an empty pixel. NB: avoid override problems using not Dilated texture
+00254                                                 CPixelInfo      &nbTexelInf= tmpTextureInfo[yb*_Width+xb];
+00255                                                 if( !(nbTexelInf==CPixelInfo::EmptyPixel) )
+00256                                                 {
+00257                                                         // write it in the center pixel, and skip the search
+00258                                                         texelInf= nbTexelInf;
+00259                                                         yb= y1+1;
+00260                                                         break;
+00261                                                 }
+00262                                         }
+00263                                 }
+00264                         }
+00265                 }
+00266         }
+00267 
+00268 }
+00269 
+00270 
+00271 // ***************************************************************************
+00272 void    CLodCharacterShapeBuild::serial(NLMISC::IStream &f)
+00273 {
+00274         // NEL_CLODBULD
+00275         f.serialCheck((uint32)'_LEN');
+00276         f.serialCheck((uint32)'DOLC');
+00277         f.serialCheck((uint32)'DLUB');
+00278 
+00279         /*
+00280         Version 1:
+00281                 - UVs and Normals + texture info
+00282         */
+00283         sint    ver= f.serialVersion(1);
+00284 
+00285         f.serialCont(Vertices);
+00286         f.serialCont(SkinWeights);
+00287         f.serialCont(BonesNames);
+00288         f.serialCont(TriangleIndices);
+00289 
+00290         if(ver>=1)
+00291         {
+00292                 f.serialCont(UVs);
+00293                 f.serialCont(Normals);
+00294                 f.serial(_Width, _Height);
+00295                 f.serialCont(_TextureInfo);
+00296         }
+00297         else
+00298         {
+00299                 // Must init dummy UVs/normals
+00300                 UVs.resize(Vertices.size(), CUV(0,0));
+00301                 Normals.resize(Vertices.size(), CVector::K);
+00302                 // Must init dummy texture
+00303                 _Width= NL3D_CLOD_TEXT_WIDTH;
+00304                 _Height= NL3D_CLOD_TEXT_HEIGHT;
+00305                 _TextureInfo.resize(_Width*_Height, CPixelInfo::EmptyPixel);
+00306         }
+00307 
+00308 }
+00309 
+00310 
+00311 // ***************************************************************************
+00312 const CLodCharacterShapeBuild::CPixelInfo       *CLodCharacterShapeBuild::getTextureInfoPtr()
+00313 {
+00314         if(_TextureInfo.empty())
+00315                 return NULL;
+00316         else
+00317                 return &_TextureInfo[0];
+00318 }
+00319 
+00320 
+00321 // ***************************************************************************
+00322 // ***************************************************************************
+00323 // CLodCharacterShape
+00324 // ***************************************************************************
+00325 // ***************************************************************************
+00326 
+00327 
+00328 // ***************************************************************************
+00329 CLodCharacterShape::CLodCharacterShape()
+00330 {
+00331         _NumVertices= 0;
+00332         _NumTriangles= 0;
+00333 }
+00334 
+00335 // ***************************************************************************
+00336 void                    CLodCharacterShape::buildMesh(const std::string &name, const CLodCharacterShapeBuild &lodBuild)
+00337 {
+00338         uint    numVertices= lodBuild.Vertices.size();
+00339         const vector<uint32>                            &triangleIndices= lodBuild.TriangleIndices;
+00340         const vector<CMesh::CSkinWeight>        &skinWeights= lodBuild.SkinWeights;
+00341         const vector<CUV>                                       &uvs= lodBuild.UVs;
+00342         const vector<CVector>                           &normals= lodBuild.Normals;
+00343 
+00344         nlassert(numVertices>0);
+00345         nlassert(triangleIndices.size()>0);
+00346         nlassert((triangleIndices.size()%3)==0);
+00347         nlassert(skinWeights.size() == numVertices);
+00348         nlassert(uvs.size() == numVertices);
+00349         nlassert(normals.size() == numVertices);
+00350 
+00351         // reset data
+00352         contReset(_Anims);
+00353         contReset(_AnimMap);
+00354         contReset(_Bones);
+00355         contReset(_BoneMap);
+00356         contReset(_TriangleIndices);
+00357         contReset(_UVs);
+00358         contReset(_Normals);
+00359 
+00360         // Copy data.
+00361         _Name= name;
+00362         _NumVertices= numVertices;
+00363         _NumTriangles= triangleIndices.size()/3;
+00364         _TriangleIndices= triangleIndices;
+00365         _UVs= uvs;
+00366         _Normals= normals;
+00367 
+00368         // check indices.
+00369         uint    i;
+00370         for(i=0;i<triangleIndices.size();i++)
+00371         {
+00372                 nlassert(triangleIndices[i]<_NumVertices);
+00373         }
+00374 
+00375         // Copy bone names, and compute bone Map
+00376         _Bones.resize(lodBuild.BonesNames.size());
+00377         for(i=0; i<_Bones.size(); i++)
+00378         {
+00379                 _Bones[i].Name= lodBuild.BonesNames[i];
+00380                 _BoneMap.insert( make_pair(_Bones[i].Name, i) );
+00381         }
+00382 
+00383         // "Normalize" SkinWeights for CLodCharacterShape
+00384         for(i=0;i<skinWeights.size();i++)
+00385         {
+00386                 nlassert(skinWeights[i].Weights[0]>0);
+00387                 // for all slots not 0
+00388                 for(uint j=0;j<NL3D_MESH_SKINNING_MAX_MATRIX;j++)
+00389                 {
+00390                         // if this this slot is used.
+00391                         if(skinWeights[i].Weights[j]>0)
+00392                         {
+00393                                 uint boneId= skinWeights[i].MatrixId[j];
+00394                                 nlassert(boneId < _Bones.size());
+00395                                 // init the vInf data
+00396                                 CVertexInf      vInf;
+00397                                 vInf.VertexId= i;
+00398                                 vInf.Influence= skinWeights[i].Weights[j];
+00399                                 // Insert this vertex influence in the bone.
+00400                                 _Bones[boneId].InfVertices.push_back(vInf);
+00401                         }
+00402                         else
+00403                                 // stop for this vertex.
+00404                                 break;
+00405                 }
+00406         }
+00407 }
+00408 
+00409 // ***************************************************************************
+00410 bool                    CLodCharacterShape::addAnim(const CAnimBuild &animBuild)
+00411 {
+00412         // first, verify don't exist.
+00413         if(getAnimIdByName(animBuild.Name)!=-1)
+00414                 return false;
+00415 
+00416         // build basics of the animation
+00417         CAnim   dstAnim;
+00418         dstAnim.Name= animBuild.Name;
+00419         dstAnim.AnimLength= animBuild.AnimLength;
+00420         // Possible to have an Anim with just one key. setup an epsilon for animLength if 0.
+00421         if(dstAnim.AnimLength<=0)
+00422                 dstAnim.AnimLength= 0.001f;
+00423         dstAnim.OOAnimLength= 1.0f / animBuild.AnimLength;
+00424         dstAnim.NumKeys= animBuild.NumKeys;
+00425         // verify size of the array
+00426         nlassert(dstAnim.NumKeys>0);
+00427         nlassert(dstAnim.NumKeys * _NumVertices == animBuild.Keys.size());
+00428         // resize dest array
+00429         dstAnim.Keys.resize(animBuild.Keys.size());
+00430 
+00431 
+00432         // Pack animation. 1st pass: compute max size over the animation vertices
+00433         uint    i;
+00434         // minimum shape size is , say, 1 cm :)
+00435         CVector         maxSize(0.01f, 0.01f, 0.01f);
+00436         for(i=0;i<animBuild.Keys.size();i++)
+00437         {
+00438                 // take the maxSize of the abs values
+00439                 maxSize.maxof(maxSize, -animBuild.Keys[i]);
+00440                 maxSize.maxof(maxSize, animBuild.Keys[i]);
+00441         }
+00442 
+00443         // compute the UnPackScaleFactor ie maxSize, to be multiplied by max Abs value of a sint16
+00444         dstAnim.UnPackScaleFactor= maxSize * (1.0f/32767);
+00445 
+00446         // Pack animation. 2st pass: pack.
+00447         CVectorD                packScaleFactor;
+00448         packScaleFactor.x= 1.0 / dstAnim.UnPackScaleFactor.x;
+00449         packScaleFactor.y= 1.0 / dstAnim.UnPackScaleFactor.y;
+00450         packScaleFactor.z= 1.0 / dstAnim.UnPackScaleFactor.z;
+00451         // For all key vertices
+00452         for(i=0;i<animBuild.Keys.size();i++)
+00453         {
+00454                 CVector         v= animBuild.Keys[i];
+00455                 CVector3s       &dstV= dstAnim.Keys[i];
+00456 
+00457                 // compress
+00458                 v.x= float(v.x*packScaleFactor.x);
+00459                 v.y= float(v.y*packScaleFactor.y);
+00460                 v.z= float(v.z*packScaleFactor.z);
+00461                 // clamp to sint16 limits (for float precision problems).
+00462                 clamp(v.x, -32767, 32767);
+00463                 clamp(v.y, -32767, 32767);
+00464                 clamp(v.z, -32767, 32767);
+00465                 // get into the vector3s
+00466                 dstV.x= (sint16)floor(v.x);
+00467                 dstV.y= (sint16)floor(v.y);
+00468                 dstV.z= (sint16)floor(v.z);
+00469         }
+00470 
+00471 
+00472         // Add the anim to the array, and add an entry to the map
+00473         _Anims.push_back(dstAnim);
+00474         _AnimMap.insert(make_pair(dstAnim.Name, _Anims.size()-1));
+00475 
+00476         return true;
+00477 }
+00478 
+00479 // ***************************************************************************
+00480 void                    CLodCharacterShape::CAnim::serial(NLMISC::IStream &f)
+00481 {
+00482         (void)f.serialVersion(0);
+00483 
+00484         f.serial(Name);
+00485         f.serial(NumKeys);
+00486         f.serial(AnimLength);
+00487         f.serial(OOAnimLength);
+00488         f.serial(UnPackScaleFactor);
+00489         f.serialCont(Keys);
+00490 }
+00491 
+00492 
+00493 // ***************************************************************************
+00494 void                    CLodCharacterShape::CBoneInfluence::serial(NLMISC::IStream &f)
+00495 {
+00496         (void)f.serialVersion(0);
+00497 
+00498         f.serial(Name);
+00499         f.serialCont(InfVertices);
+00500 }
+00501 
+00502 
+00503 // ***************************************************************************
+00504 void                    CLodCharacterShape::serial(NLMISC::IStream &f)
+00505 {
+00506         // NEL_CLODSHAP
+00507         f.serialCheck((uint32)'_LEN');
+00508         f.serialCheck((uint32)'DOLC');
+00509         f.serialCheck((uint32)'PAHS');
+00510 
+00511         /*
+00512         Version 1:
+00513                 - UVs and Normals.
+00514         */
+00515         sint ver= f.serialVersion(1);
+00516 
+00517         f.serial(_Name);
+00518         f.serial(_NumVertices);
+00519         f.serial(_NumTriangles);
+00520         f.serialCont(_Bones);
+00521         f.serialCont(_BoneMap);
+00522         f.serialCont(_TriangleIndices);
+00523         f.serialCont(_Anims);
+00524         f.serialCont(_AnimMap);
+00525 
+00526         if(ver>=1)
+00527         {
+00528                 f.serialCont(_UVs);
+00529                 f.serialCont(_Normals);
+00530         }
+00531         else
+00532         {
+00533                 // Must init dummy UVs/normals
+00534                 _UVs.resize(_NumVertices, CUV(0,0));
+00535                 _Normals.resize(_NumVertices, CVector::K);
+00536         }
+00537 }
+00538 
+00539 // ***************************************************************************
+00540 sint                    CLodCharacterShape::getAnimIdByName(const std::string &name) const
+00541 {
+00542         CstItStrIdMap   it= _AnimMap.find(name);
+00543         if(it == _AnimMap.end())
+00544                 return -1;
+00545         else
+00546                 return it->second;
+00547 }
+00548 
+00549 
+00550 // ***************************************************************************
+00551 sint                    CLodCharacterShape::getBoneIdByName(const std::string &name) const
+00552 {
+00553         CstItStrIdMap   it= _BoneMap.find(name);
+00554         if(it == _BoneMap.end())
+00555                 return -1;
+00556         else
+00557                 return it->second;
+00558 }
+00559 
+00560 
+00561 // ***************************************************************************
+00562 const uint32    *CLodCharacterShape::getTriangleArray() const
+00563 {
+00564         if(_NumTriangles)
+00565                 return &_TriangleIndices[0];
+00566         else
+00567                 return NULL;
+00568 }
+00569 
+00570 // ***************************************************************************
+00571 const CLodCharacterShape::CVector3s     *CLodCharacterShape::getAnimKey(uint animId, TGlobalAnimationTime time, bool wrapMode, CVector &unPackScaleFactor) const
+00572 {
+00573         float   localTime;
+00574 
+00575         if(animId>=_Anims.size())
+00576                 return NULL;
+00577 
+00578         // get the anim.
+00579         const CAnim &anim= _Anims[animId];
+00580 
+00581         // scale info
+00582         unPackScaleFactor= anim.UnPackScaleFactor;
+00583 
+00584         // Loop mgt.
+00585         if(wrapMode)
+00586                 localTime= (float)fmod(time, anim.AnimLength);
+00587         else
+00588                 localTime= (float)time;
+00589 
+00590         // Clamp to the range.
+00591         clamp(localTime, 0, anim.AnimLength);
+00592 
+00593         // get the key.
+00594         sint    keyId= (sint)floor( (localTime*anim.OOAnimLength) * anim.NumKeys );
+00595         clamp(keyId, 0, sint(anim.NumKeys-1));
+00596 
+00597         // return the key.
+00598         return &anim.Keys[keyId * _NumVertices];
+00599 }
+00600 
+00601 // ***************************************************************************
+00602 const CUV               *CLodCharacterShape::getUVs() const
+00603 {
+00604         if(_NumVertices==0)
+00605                 return NULL;
+00606 
+00607         return &_UVs[0];
+00608 }
+00609 
+00610 // ***************************************************************************
+00611 const CVector   *CLodCharacterShape::getNormals() const
+00612 {
+00613         if(_NumVertices==0)
+00614                 return NULL;
+00615 
+00616         return &_Normals[0];
+00617 }
+00618 
+00619 
+00620 
+00621 // ***************************************************************************
+00622 // ***************************************************************************
+00623 // Bone coloring
+00624 // ***************************************************************************
+00625 // ***************************************************************************
+00626 
+00627 
+00628 // ***************************************************************************
+00629 void                    CLodCharacterShape::startBoneColor(std::vector<NLMISC::CRGBAF>  &tmpColors) const
+00630 {
+00631         // alocate
+00632         tmpColors.resize(getNumVertices());
+00633         // fill with black (in Alpha too)
+00634         CRGBAF  black(0,0,0,0);
+00635         fill(tmpColors.begin(), tmpColors.end(), black);
+00636 }
+00637 
+00638 // ***************************************************************************
+00639 void                    CLodCharacterShape::addBoneColor(uint boneId, CRGBA     color, std::vector<NLMISC::CRGBAF> &tmpColors) const
+00640 {
+00641         // Yoyo: This is an error to not have the same skeleton that the one stored in the lod shape. But must not crash
+00642         if(boneId>=_Bones.size())
+00643                 return;
+00644         const CBoneInfluence    &bone= _Bones[boneId];
+00645 
+00646         // for all vertices influenced by this bone, must influence the color
+00647         for(uint i=0; i<bone.InfVertices.size(); i++)
+00648         {
+00649                 const CVertexInf        &vInf= bone.InfVertices[i];
+00650                 // Add the color, modulated by the vertex weight
+00651                 tmpColors[vInf.VertexId].R+= color.R * vInf.Influence;
+00652                 tmpColors[vInf.VertexId].G+= color.G * vInf.Influence;
+00653                 tmpColors[vInf.VertexId].B+= color.B * vInf.Influence;
+00654                 // Add the weight in alpha channel
+00655                 tmpColors[vInf.VertexId].A+= vInf.Influence;
+00656         }
+00657 }
+00658 
+00659 // ***************************************************************************
+00660 void                    CLodCharacterShape::endBoneColor(const std::vector<NLMISC::CRGBAF> &tmpColors, std::vector<NLMISC::CRGBA>       &dstColors) const
+00661 {
+00662         // The default value if vertex is not influenced at all
+00663         CRGBA   defaultColor(128,128,128,0);
+00664 
+00665         // resize dstColors
+00666         nlassert(tmpColors.size() == getNumVertices());
+00667         dstColors.resize(getNumVertices());
+00668 
+00669         // For all vertices
+00670         for(uint i=0; i<dstColors.size(); i++)
+00671         {
+00672                 // If the vertex is not influenced, set transparent
+00673                 if(tmpColors[i].A==0)
+00674                         dstColors[i]= defaultColor;
+00675                 else
+00676                 {
+00677                         // Average the color.
+00678                         float   R= tmpColors[i].R / tmpColors[i].A;
+00679                         float   G= tmpColors[i].G / tmpColors[i].A;
+00680                         float   B= tmpColors[i].B / tmpColors[i].A;
+00681                         // store.
+00682                         dstColors[i].R= (uint8)OptFastFloor(R);
+00683                         dstColors[i].G= (uint8)OptFastFloor(G);
+00684                         dstColors[i].B= (uint8)OptFastFloor(B);
+00685                         dstColors[i].A= 255;
+00686                 }
+00687         }
+00688 }
+00689 
+00690 
+00691 
+00692 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1