#include <lod_character_shape.h>
Nevrax France
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 CPixelInfo * | getTextureInfoPtr () |
| get TextureInfo | |
| uint | getTextureInfoWidth () const |
| void | serial (NLMISC::IStream &f) |
| serial | |
Data Fields | |
| std::vector< std::string > | BonesNames |
| std::vector< CVector > | Normals |
| std::vector< CMesh::CSkinWeight > | SkinWeights |
| std::vector< uint32 > | TriangleIndices |
| std::vector< CUV > | UVs |
| std::vector< CVector > | Vertices |
Private Attributes | |
| uint32 | _Height |
| std::vector< CPixelInfo > | _TextureInfo |
| uint32 | _Width |
|
|
Definition at line 58 of file lod_character_shape.cpp.
|
|
||||||||||||
|
compile the lod: compute Texture Information.
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 }
|
|
|
Definition at line 111 of file lod_character_shape.h. References uint.
00111 {return _Height;}
|
|
|
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 }
|
|
|
Definition at line 110 of file lod_character_shape.h. References uint.
00110 {return _Width;}
|
|
|
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 }
|
|
|
Definition at line 117 of file lod_character_shape.h. |
|
|
Definition at line 116 of file lod_character_shape.h. Referenced by compile(), getTextureInfoPtr(), and serial(). |
|
|
Definition at line 117 of file lod_character_shape.h. |
|
|
Definition at line 89 of file lod_character_shape.h. Referenced by NL3D::CLodCharacterShape::buildMesh(), and serial(). |
|
|
Definition at line 86 of file lod_character_shape.h. Referenced by NL3D::CLodCharacterShape::buildMesh(), compile(), and serial(). |
|
|
Definition at line 80 of file lod_character_shape.h. Referenced by NL3D::CLodCharacterBuilder::applySkin(), NL3D::CLodCharacterShape::buildMesh(), and serial(). |
|
|
Definition at line 92 of file lod_character_shape.h. Referenced by NL3D::CLodCharacterShape::buildMesh(), compile(), and serial(). |
|
|
Definition at line 83 of file lod_character_shape.h. Referenced by NL3D::CLodCharacterShape::buildMesh(), compile(), and serial(). |
|
|
Definition at line 77 of file lod_character_shape.h. Referenced by NL3D::CLodCharacterBuilder::applySkin(), and NL3D::CLodCharacterShape::buildMesh(). |
1.3.6