#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(). |