NL3D::CLodCharacterShapeBuild Class Reference

#include <lod_character_shape.h>


Detailed Description

A build structure information for building a CLodCharacterShape This is the structure exported from the 3D editor
Author:
Lionel Berenguier

Nevrax France

Date:
2002

Definition at line 46 of file lod_character_shape.h.

Public Member Functions

 CLodCharacterShapeBuild ()
void compile (const std::vector< bool > &triangleSelection, uint textureOverSample=25)
uint getTextureInfoHeight () const
const CPixelInfogetTextureInfoPtr ()
 get TextureInfo

uint getTextureInfoWidth () const
void serial (NLMISC::IStream &f)
 serial


Data Fields

std::vector< std::string > BonesNames
std::vector< CVectorNormals
std::vector< CMesh::CSkinWeightSkinWeights
std::vector< uint32TriangleIndices
std::vector< CUVUVs
std::vector< CVectorVertices

Private Attributes

uint32 _Height
std::vector< CPixelInfo_TextureInfo
uint32 _Width


Constructor & Destructor Documentation

NL3D::CLodCharacterShapeBuild::CLodCharacterShapeBuild  ) 
 

Definition at line 58 of file lod_character_shape.cpp.

00059 {
00060         _Width= 0;
00061         _Height= 0;
00062 }


Member Function Documentation

void NL3D::CLodCharacterShapeBuild::compile const std::vector< bool > &  triangleSelection,
uint  textureOverSample = 25
 

compile the lod: compute Texture Information.

Parameters:
triangleSelection. If not same size as triangles, not used. Else texture info is filled only with triangles whose their triangleSelection[triId]==true
textureOverSample is rounded to the best square (4,9,...). Prefer a srq(oddVal): 1,9,25,49 etc... NB: overSamples are not averaged, but the nearest sample to the texel center is taken.

Definition at line 66 of file lod_character_shape.cpp.

References _TextureInfo, NLMISC::CPolygon2D::computeBorders(), NLMISC::CTriangle::computeGradient(), min, NL3D_CLOD_TEXT_HEIGHT, NL3D_CLOD_TEXT_WIDTH, nlassert, NL3D::CLodCharacterShapeBuild::CPixelInfo::Normal, NLMISC::CVector::normalize(), Normals, NL3D::CLodCharacterShapeBuild::CPixelInfo::Pos, sint, NLMISC::sqr(), NLMISC::CPolygon2D::TRasterVect, TriangleIndices, uint, UVs, v, NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, NLMISC::CTriangle::V2, NLMISC::CPolygon2D::Vertices, x, NLMISC::CVector::x, y, NLMISC::CVector::y, and NLMISC::CVector::z.

00067 {
00068         nlassert(UVs.size()==Vertices.size());
00069         nlassert(Normals.size()==Vertices.size());
00070 
00071         // take the sqrtf.
00072         textureOverSample= (uint)sqrtf((float)textureOverSample);
00073         textureOverSample= max(textureOverSample, 1U);
00074 
00075         _Width= NL3D_CLOD_TEXT_WIDTH;
00076         _Height= NL3D_CLOD_TEXT_HEIGHT;
00077 
00078         uint    wOver= _Width*textureOverSample;
00079         uint    hOver= _Height*textureOverSample;
00080         std::vector<CPixelInfo>         overTextureInfo;
00081 
00082         // do some tri selection?
00083         bool    triSelectOk= triangleSelection.size()==TriangleIndices.size()/3;
00084 
00085 
00086         // **** reset the texture and init with "empty" pixel (ie normal.x==1000, which is not possible because normal.norm()==1)
00087         _TextureInfo.resize(_Width*_Height);
00088         fill(_TextureInfo.begin(), _TextureInfo.end(), CPixelInfo::EmptyPixel);
00089         // do it to the oversampled texture
00090         overTextureInfo.resize(wOver*hOver, CPixelInfo::EmptyPixel);
00091 
00092 
00093         // **** For each triangle in the shape, polyfill this triangle from a texture view, in the overSampledTexture
00094         CPolygon2D      poly;
00095         poly.Vertices.resize(3);
00096         for(uint i=0; i<TriangleIndices.size();i+=3)
00097         {
00098                 // if selection OK, and the tri is not selected, skip
00099                 if(triSelectOk && !triangleSelection[i/3])
00100                         continue;
00101 
00102                 // Setup triangle.
00103                 // -----------
00104                 uint    idx[3];
00105                 idx[0]= TriangleIndices[i+0];
00106                 idx[1]= TriangleIndices[i+1];
00107                 idx[2]= TriangleIndices[i+2];
00108                 // compute corners UVs, in texel size
00109                 CTriangle               triangleUV;
00110                 triangleUV.V0= CVector(UVs[idx[0]].U*wOver, UVs[idx[0]].V*hOver, 0);
00111                 triangleUV.V1= CVector(UVs[idx[1]].U*wOver, UVs[idx[1]].V*hOver, 0);
00112                 triangleUV.V2= CVector(UVs[idx[2]].U*wOver, UVs[idx[2]].V*hOver, 0);
00113                 // compute corners pixelInfos 
00114                 CPixelInfo              pInf[3];
00115                 for(uint corner=0; corner<3; corner++)
00116                 {
00117                         pInf[corner].Pos= Vertices[idx[corner]];
00118                         pInf[corner].Normal= Normals[idx[corner]];
00119                 }
00120                 // Compute Gradients
00121                 CVector         GradPosX, GradPosY, GradPosZ;
00122                 CVector         GradNormalX, GradNormalY, GradNormalZ;
00123                 triangleUV.computeGradient(pInf[0].Pos.x, pInf[1].Pos.x, pInf[2].Pos.x, GradPosX);
00124                 triangleUV.computeGradient(pInf[0].Pos.y, pInf[1].Pos.y, pInf[2].Pos.y, GradPosY);
00125                 triangleUV.computeGradient(pInf[0].Pos.z, pInf[1].Pos.z, pInf[2].Pos.z, GradPosZ);
00126                 triangleUV.computeGradient(pInf[0].Normal.x, pInf[1].Normal.x, pInf[2].Normal.x, GradNormalX);
00127                 triangleUV.computeGradient(pInf[0].Normal.y, pInf[1].Normal.y, pInf[2].Normal.y, GradNormalY);
00128                 triangleUV.computeGradient(pInf[0].Normal.z, pInf[1].Normal.z, pInf[2].Normal.z, GradNormalZ);
00129                 // Compute Gradients offset
00130                 float           OffPosX, OffPosY, OffPosZ;
00131                 float           OffNormalX, OffNormalY, OffNormalZ;
00132                 OffPosX= pInf[0].Pos.x - GradPosX*triangleUV.V0;
00133                 OffPosY= pInf[0].Pos.y - GradPosY*triangleUV.V0;
00134                 OffPosZ= pInf[0].Pos.z - GradPosZ*triangleUV.V0;
00135                 OffNormalX= pInf[0].Normal.x - GradNormalX*triangleUV.V0;
00136                 OffNormalY= pInf[0].Normal.y - GradNormalY*triangleUV.V0;
00137                 OffNormalZ= pInf[0].Normal.z - GradNormalZ*triangleUV.V0;
00138 
00139 
00140                 // PolyFiller
00141                 // -----------
00142                 CVector2f       dCenter(0.5f, 0.5f);
00143                 // select texels if their centers is in the triangle
00144                 poly.Vertices[0]= triangleUV.V0-dCenter;
00145                 poly.Vertices[1]= triangleUV.V1-dCenter;
00146                 poly.Vertices[2]= triangleUV.V2-dCenter;
00147                 // polyFiller
00148                 CPolygon2D::TRasterVect rasters;
00149                 sint    minY;
00150                 poly.computeBorders(rasters, minY);
00151                 for(sint y=0;y<(sint)rasters.size();y++)
00152                 {
00153                         sint x0= rasters[y].first;
00154                         sint x1= rasters[y].second;
00155                         CVector v;
00156                         // get the center coord of this texel
00157                         v.y= y+minY+0.5f;
00158                         v.z= 0;
00159                         for(sint x=x0;x<=x1;x++)
00160                         {
00161                                 // get the center coord of this texel
00162                                 v.x= x+0.5f;
00163                                 // Compute Pos/Normal on this texel.
00164                                 CPixelInfo      texelInf;
00165                                 texelInf.Pos.x= OffPosX + GradPosX * v;
00166                                 texelInf.Pos.y= OffPosY + GradPosY * v;
00167                                 texelInf.Pos.z= OffPosZ + GradPosZ * v;
00168                                 texelInf.Normal.x= OffNormalX + GradNormalX * v;
00169                                 texelInf.Normal.y= OffNormalY + GradNormalY * v;
00170                                 texelInf.Normal.z= OffNormalZ + GradNormalZ * v;
00171                                 // normalize.
00172                                 texelInf.Normal.normalize();
00173                                 // Store (NB: overwrite any pixel)
00174                                 sint    texX= ((uint)x)%wOver;
00175                                 sint    texY= ((uint)y+minY)%hOver;
00176                                 overTextureInfo[texY*wOver+texX]= texelInf;
00177                         }
00178                 }
00179 
00180         }
00181 
00182 
00183         // **** Down sample the overSampled texture.
00184         sint    x,y;
00185         if(textureOverSample==1)
00186         {
00187                 _TextureInfo= overTextureInfo;
00188         }
00189         else
00190         {
00191                 // eg: 3 gives 1. delta ranges from -1 to 1.
00192                 float   middle= (textureOverSample-1)/2.f;
00193 
00194                 // for all pixels.
00195                 for(y=0;y<(sint)_Height;y++)
00196                 {
00197                         for(x=0;x<(sint)_Width;x++)
00198                         {
00199                                 // for all samples, take the best one.
00200                                 sint            xo, yo;
00201                                 float           bestDist= FLT_MAX;
00202                                 CPixelInfo      bestPixel= CPixelInfo::EmptyPixel;
00203                                 for(yo=0;yo<(sint)textureOverSample;yo++)
00204                                 {
00205                                         for(xo=0;xo<(sint)textureOverSample;xo++)
00206                                         {
00207                                                 // compute distance to the pixel center.
00208                                                 float   dist= sqr(yo-middle)+sqr(xo-middle);
00209                                                 const CPixelInfo        &overPixel= overTextureInfo[(y*textureOverSample+yo)*wOver+(x*textureOverSample+xo)];
00210                                                 // if the overPixel is not empty.
00211                                                 if( !(overPixel==CPixelInfo::EmptyPixel) )
00212                                                 {
00213                                                         // take it if the best: nearest to the pixel center.
00214                                                         if(dist<bestDist)
00215                                                         {
00216                                                                 bestDist= dist;
00217                                                                 bestPixel= overPixel;
00218                                                         }
00219                                                 }
00220                                         }
00221                                 }
00222 
00223                                 // fill textureInfo
00224                                 _TextureInfo[y*_Width+x]= bestPixel;
00225                         }
00226                 }
00227         }
00228 
00229 
00230         // **** Dilate texture 1 time: each empty pixel info get neighbor full pixel (8box)
00231         // copy the non dilated texture
00232         std::vector<CPixelInfo>         tmpTextureInfo= _TextureInfo;
00233         // process all pixels
00234         for(y=0;y<(sint)_Height;y++)
00235         {
00236                 sint    y0=y-1, y1=y+1;
00237                 y0= max(y0, 0);
00238                 y1= min(y1, (sint)_Height-1);
00239                 for(x=0;x<(sint)_Width;x++)
00240                 {
00241                         CPixelInfo      &texelInf= _TextureInfo[y*_Width+x];
00242                         // if an empty pixel.
00243                         if(texelInf==CPixelInfo::EmptyPixel)
00244                         {
00245                                 // dilate: look around for non empty pixel.
00246                                 sint    x0=x-1, x1=x+1;
00247                                 x0= max(x0, 0);
00248                                 x1= min(x1, (sint)_Width-1);
00249                                 // For the 8 possible pixels (nb: look us too, but doesn't matter since we are an empty pixel)
00250                                 for(sint yb= y0; yb<=y1;yb++)
00251                                 {
00252                                         for(sint xb= x0; xb<=x1;xb++)
00253                                         {
00254                                                 // if the neighbor is not an empty pixel. NB: avoid override problems using not Dilated texture
00255                                                 CPixelInfo      &nbTexelInf= tmpTextureInfo[yb*_Width+xb];
00256                                                 if( !(nbTexelInf==CPixelInfo::EmptyPixel) )
00257                                                 {
00258                                                         // write it in the center pixel, and skip the search
00259                                                         texelInf= nbTexelInf;
00260                                                         yb= y1+1;
00261                                                         break;
00262                                                 }
00263                                         }
00264                                 }
00265                         }
00266                 }
00267         }
00268 
00269 }

uint NL3D::CLodCharacterShapeBuild::getTextureInfoHeight  )  const [inline]
 

Definition at line 111 of file lod_character_shape.h.

References uint.

00111 {return _Height;}

const CLodCharacterShapeBuild::CPixelInfo * NL3D::CLodCharacterShapeBuild::getTextureInfoPtr  ) 
 

get TextureInfo

Definition at line 313 of file lod_character_shape.cpp.

References _TextureInfo.

00314 {
00315         if(_TextureInfo.empty())
00316                 return NULL;
00317         else
00318                 return &_TextureInfo[0];
00319 }

uint NL3D::CLodCharacterShapeBuild::getTextureInfoWidth  )  const [inline]
 

Definition at line 110 of file lod_character_shape.h.

References uint.

00110 {return _Width;}

void NL3D::CLodCharacterShapeBuild::serial NLMISC::IStream f  ) 
 

serial

Definition at line 273 of file lod_character_shape.cpp.

References _TextureInfo, BonesNames, NL3D_CLOD_TEXT_HEIGHT, NL3D_CLOD_TEXT_WIDTH, Normals, NLMISC::IStream::serial(), NLMISC::IStream::serialCheck(), NLMISC::IStream::serialCont(), NLMISC::IStream::serialVersion(), sint, SkinWeights, TriangleIndices, uint32, and UVs.

00274 {
00275         // NEL_CLODBULD
00276         f.serialCheck((uint32)'_LEN');
00277         f.serialCheck((uint32)'DOLC');
00278         f.serialCheck((uint32)'DLUB');
00279 
00280         /*
00281         Version 1:
00282                 - UVs and Normals + texture info
00283         */
00284         sint    ver= f.serialVersion(1);
00285 
00286         f.serialCont(Vertices);
00287         f.serialCont(SkinWeights);
00288         f.serialCont(BonesNames);
00289         f.serialCont(TriangleIndices);
00290 
00291         if(ver>=1)
00292         {
00293                 f.serialCont(UVs);
00294                 f.serialCont(Normals);
00295                 f.serial(_Width, _Height);
00296                 f.serialCont(_TextureInfo);
00297         }
00298         else
00299         {
00300                 // Must init dummy UVs/normals
00301                 UVs.resize(Vertices.size(), CUV(0,0));
00302                 Normals.resize(Vertices.size(), CVector::K);
00303                 // Must init dummy texture
00304                 _Width= NL3D_CLOD_TEXT_WIDTH;
00305                 _Height= NL3D_CLOD_TEXT_HEIGHT;
00306                 _TextureInfo.resize(_Width*_Height, CPixelInfo::EmptyPixel);
00307         }
00308 
00309 }


Field Documentation

uint32 NL3D::CLodCharacterShapeBuild::_Height [private]
 

Definition at line 117 of file lod_character_shape.h.

std::vector<CPixelInfo> NL3D::CLodCharacterShapeBuild::_TextureInfo [private]
 

Definition at line 116 of file lod_character_shape.h.

Referenced by compile(), getTextureInfoPtr(), and serial().

uint32 NL3D::CLodCharacterShapeBuild::_Width [private]
 

Definition at line 117 of file lod_character_shape.h.

std::vector<std::string> NL3D::CLodCharacterShapeBuild::BonesNames
 

Definition at line 89 of file lod_character_shape.h.

Referenced by NL3D::CLodCharacterShape::buildMesh(), and serial().

std::vector<CVector> NL3D::CLodCharacterShapeBuild::Normals
 

Definition at line 86 of file lod_character_shape.h.

Referenced by NL3D::CLodCharacterShape::buildMesh(), compile(), and serial().

std::vector<CMesh::CSkinWeight> NL3D::CLodCharacterShapeBuild::SkinWeights
 

Definition at line 80 of file lod_character_shape.h.

Referenced by NL3D::CLodCharacterBuilder::applySkin(), NL3D::CLodCharacterShape::buildMesh(), and serial().

std::vector<uint32> NL3D::CLodCharacterShapeBuild::TriangleIndices
 

Definition at line 92 of file lod_character_shape.h.

Referenced by NL3D::CLodCharacterShape::buildMesh(), compile(), and serial().

std::vector<CUV> NL3D::CLodCharacterShapeBuild::UVs
 

Definition at line 83 of file lod_character_shape.h.

Referenced by NL3D::CLodCharacterShape::buildMesh(), compile(), and serial().

std::vector<CVector> NL3D::CLodCharacterShapeBuild::Vertices
 

Definition at line 77 of file lod_character_shape.h.

Referenced by NL3D::CLodCharacterBuilder::applySkin(), and NL3D::CLodCharacterShape::buildMesh().


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