Blender V2.61 - r43446
|
00001 00004 /****************************************************************************** 00005 * 00006 * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method 00007 * Copyright 2003-2006 Nils Thuerey 00008 * 00009 * A simple box object 00010 * 00011 *****************************************************************************/ 00012 00013 #include "ntl_geometrymodel.h" 00014 #include "ntl_ray.h" 00015 #include "ntl_world.h" 00016 #include "zlib.h" 00017 00018 #ifdef WIN32 00019 #ifndef strncasecmp 00020 #define strncasecmp(a,b,c) strcmp(a,b) 00021 #endif 00022 #endif // WIN32 00023 00024 00025 /****************************************************************************** 00026 * Default Constructor 00027 *****************************************************************************/ 00028 ntlGeometryObjModel::ntlGeometryObjModel( void ) : 00029 ntlGeometryObject(), 00030 mvStart( 0.0 ), mvEnd( 1.0 ), 00031 mLoaded( false ), 00032 mTriangles(), mVertices(), mNormals(), 00033 mcAniVerts(), mcAniNorms(), 00034 mcAniTimes(), mAniTimeScale(1.), mAniTimeOffset(0.) 00035 { 00036 } 00037 00038 /****************************************************************************** 00039 * Destructor 00040 *****************************************************************************/ 00041 ntlGeometryObjModel::~ntlGeometryObjModel() 00042 { 00043 if(!mLoaded) { 00044 errMsg("ntlGeometryObjModel","delete obj..."); 00045 } 00046 } 00047 00048 00050 bool ntlGeometryObjModel::getMeshAnimated() { 00051 const bool ret = (mcAniVerts.getSize()>1); 00052 //errMsg("getMeshAnimated","ret="<<ret<<", size="<<mcAniVerts.getSize() ); 00053 return ret; 00054 } 00055 00057 void ntlGeometryObjModel::getExtends(ntlVec3Gfx &sstart, ntlVec3Gfx &send) { 00058 bool ini=false; 00059 ntlVec3Gfx start(0.),end(0.); 00060 for(int s=0; s<=(int)mcAniVerts.accessValues().size(); s++) { 00061 vector<ntlVec3f> *sverts; 00062 if(mcAniVerts.accessValues().size()>0) { 00063 if(s==(int)mcAniVerts.accessValues().size()) continue; 00064 sverts = &(mcAniVerts.accessValues()[s].mVerts); 00065 } else sverts = &mVertices; 00066 00067 for(int i=0; i<(int)sverts->size(); i++) { 00068 00069 if(!ini) { 00070 start=(*sverts)[i]; 00071 end=(*sverts)[i]; 00072 //errMsg("getExtends","ini "<<s<<","<<i<<" "<<start<<","<<end); 00073 ini=true; 00074 } else { 00075 for(int j=0; j<3; j++) { 00076 if(start[j] > (*sverts)[i][j]) { start[j]= (*sverts)[i][j]; } 00077 if(end[j] < (*sverts)[i][j]) { end[j] = (*sverts)[i][j]; } 00078 } 00079 //errMsg("getExtends","check "<<s<<","<<i<<" "<<start<<","<<end<<" "<< (*sverts)[i]); 00080 } 00081 00082 } 00083 } 00084 sstart=start; 00085 send=end; 00086 } 00087 00088 00089 /*****************************************************************************/ 00090 /* Init attributes etc. of this object */ 00091 /*****************************************************************************/ 00092 void ntlGeometryObjModel::initialize(ntlRenderGlobals *glob) 00093 { 00094 // perhaps the model is already inited from initModel below? 00095 if(mLoaded==1) { 00096 // init default material 00097 searchMaterial( glob->getMaterials() ); 00098 return; 00099 } 00100 00101 ntlGeometryObject::initialize(glob); 00102 mFilename = mpAttrs->readString("filename", mFilename,"ntlGeometryObjModel", "mFilename", true); 00103 00104 if(mFilename == "") { 00105 errMsg("ntlGeometryObjModel::initialize","Filename not given!"); 00106 return; 00107 } 00108 00109 const char *suffix = strrchr(mFilename.c_str(), '.'); 00110 if (suffix) { 00111 if (!strncasecmp(suffix, ".obj", 4)) { 00112 errMsg("ntlGeometryObjModel::initialize",".obj files not supported!"); 00113 return; 00114 } else if (!strncasecmp(suffix, ".gz", 3)) { 00115 //mType = 1; // assume its .bobj.gz 00116 } else if (!strncasecmp(suffix, ".bobj", 5)) { 00117 //mType = 1; 00118 } 00119 } 00120 00121 if(getAttributeList()->exists("ani_times") || (!mcAniTimes.isInited()) ) { 00122 mcAniTimes = mpAttrs->readChannelFloat("ani_times"); 00123 } 00124 mAniTimeScale = mpAttrs->readFloat("ani_timescale", mAniTimeScale,"ntlGeometryObjModel", "mAniTimeScale", false); 00125 mAniTimeOffset = mpAttrs->readFloat("ani_timeoffset", mAniTimeOffset,"ntlGeometryObjModel", "mAniTimeOffset", false); 00126 00127 // continue with standard obj 00128 if(loadBobjModel(mFilename)==0) mLoaded=1; 00129 if(!mLoaded) { 00130 debMsgStd("ntlGeometryObjModel",DM_WARNING,"Unable to load object file '"<<mFilename<<"' !", 0); 00131 } 00132 if(getMeshAnimated()) { 00133 this->mIsAnimated = true; 00134 } 00135 } 00136 00137 /****************************************************************************** 00138 * init model from given vertex and triangle arrays 00139 *****************************************************************************/ 00140 00141 int ntlGeometryObjModel::initModel(int numVertices, float *vertices, int numTriangles, int *triangles, 00142 int channelSize, float *channelVertices) 00143 { 00144 mVertices.clear(); 00145 mVertices.resize( numVertices ); 00146 mNormals.resize( numVertices ); 00147 for(int i=0; i<numVertices; i++) { 00148 mVertices[i] = ntlVec3Gfx(vertices[i*3+0],vertices[i*3+1],vertices[i*3+2]); 00149 mNormals[i] = ntlVec3Gfx(1.0); // unused, set to !=0.0 00150 } 00151 00152 mTriangles.clear(); 00153 mTriangles.resize( 3*numTriangles ); 00154 int triangleErrs=0; 00155 for(int i=0; i<numTriangles; i++) { 00156 for(int j=0;j<3;j++) { 00157 mTriangles[3*i+j] = triangles[i*3+j]; 00158 if(mTriangles[3*i+j]<0) { mTriangles[3*i+j]=0; triangleErrs++; } 00159 if(mTriangles[3*i+j]>=numVertices) { mTriangles[3*i+j]=0; triangleErrs++; } 00160 } 00161 } 00162 if(triangleErrs>0) { 00163 errMsg("ntlGeometryObjModel::initModel","Triangle errors occurred ("<<triangleErrs<<")!"); 00164 } 00165 00166 //fprintf(stderr,"initModel DEBUG %d \n",channelSize); 00167 debMsgStd("ntlGeometryObjModel::initModel",DM_MSG, "Csize:"<<channelSize<<", Cvert:"<<(long)(channelVertices) ,10); 00168 if(channelVertices && (channelSize>0)) { 00169 vector<ntlSetVec3f> aniverts; 00170 vector<ntlSetVec3f> aninorms; 00171 vector<double> anitimes; 00172 aniverts.clear(); 00173 aninorms.clear(); 00174 anitimes.clear(); 00175 for(int frame=0; frame<channelSize; frame++) { 00176 ntlSetVec3f averts; averts.mVerts.clear(); 00177 ntlSetVec3f anorms; averts.mVerts.clear(); 00178 int setsize = (3*numVertices+1); 00179 00180 ntlVec3Gfx p(0.),n(1.); 00181 for(int i=0; i<numVertices; i++) { 00182 for(int j=0; j<3; j++) p[j] = channelVertices[frame*setsize+ 3*i +j]; 00183 averts.mVerts.push_back(p); 00184 anorms.mVerts.push_back(p); 00185 //debMsgStd("ntlGeometryObjModel::initModel",DM_MSG, "Frame:"<<frame<<",i:"<<i<<" "<<p,10); 00186 } 00187 if( ((int)averts.mVerts.size()==numVertices) && 00188 ((int)anorms.mVerts.size()==numVertices) ) { 00189 aniverts.push_back(averts); 00190 aninorms.push_back(anorms); 00191 double time = (double)channelVertices[frame*setsize+ setsize-1]; 00192 anitimes.push_back(time); 00193 } else { 00194 errMsg("ntlGeometryObjModel::initModel","Invalid mesh, obj="<<this->getName()<<" frame="<<frame<<" verts="<<averts.mVerts.size()<<"/"<<numVertices<<". Skipping..."); 00195 } 00196 //debMsgStd("ntlGeometryObjModel::initModel",DM_MSG, "Frame:"<<frame<<" at t="<<time,10); 00197 } 00198 00199 mcAniVerts = AnimChannel<ntlSetVec3f>(aniverts,anitimes); 00200 mcAniNorms = AnimChannel<ntlSetVec3f>(aninorms,anitimes); 00201 debMsgStd("ntlGeometryObjModel::initModel",DM_MSG, "Ani sets inited: "<< mcAniVerts.accessValues().size() <<","<<mcAniNorms.accessValues().size() <<" ", 1 ); 00202 } 00203 if(getMeshAnimated()) { 00204 this->mIsAnimated = true; 00205 } 00206 00207 // inited, no need to parse attribs etc. 00208 mLoaded = 1; 00209 return 0; 00210 } 00211 00213 void ntlGeometryObjModel::calcTriangleDivs(vector<ntlVec3Gfx> &verts, vector<ntlTriangle> &tris, gfxReal fsTri) { 00214 // warning - copied from geomobj calc! 00215 errMsg("ntlGeometryObjModel","calcTriangleDivs special!"); 00216 mTriangleDivs1.resize( tris.size() ); 00217 mTriangleDivs2.resize( tris.size() ); 00218 mTriangleDivs3.resize( tris.size() ); 00219 for(size_t i=0; i<tris.size(); i++) { 00220 ntlVec3Gfx p0 = verts[ tris[i].getPoints()[0] ]; 00221 ntlVec3Gfx p1 = verts[ tris[i].getPoints()[1] ]; 00222 ntlVec3Gfx p2 = verts[ tris[i].getPoints()[2] ]; 00223 ntlVec3Gfx side1 = p1 - p0; 00224 ntlVec3Gfx side2 = p2 - p0; 00225 ntlVec3Gfx side3 = p1 - p2; 00226 int divs1=0, divs2=0, divs3=0; 00227 if(normNoSqrt(side1) > fsTri*fsTri) { divs1 = (int)(norm(side1)/fsTri); } 00228 if(normNoSqrt(side2) > fsTri*fsTri) { divs2 = (int)(norm(side2)/fsTri); } 00229 //if(normNoSqrt(side3) > fsTri*fsTri) { divs3 = (int)(norm(side3)/fsTri); } 00230 00231 // special handling 00232 // warning, requires objmodel triangle treatment (no verts dups) 00233 if(getMeshAnimated()) { 00234 vector<ntlSetVec3f> &sverts = mcAniVerts.accessValues(); 00235 for(int s=0; s<(int)sverts.size(); s++) { 00236 p0 = sverts[s].mVerts[ tris[i].getPoints()[0] ]; 00237 p1 = sverts[s].mVerts[ tris[i].getPoints()[1] ]; 00238 p2 = sverts[s].mVerts[ tris[i].getPoints()[2] ]; 00239 side1 = p1 - p0; side2 = p2 - p0; side3 = p1 - p2; 00240 int tdivs1=0, tdivs2=0, tdivs3=0; 00241 if(normNoSqrt(side1) > fsTri*fsTri) { tdivs1 = (int)(norm(side1)/fsTri); } 00242 if(normNoSqrt(side2) > fsTri*fsTri) { tdivs2 = (int)(norm(side2)/fsTri); } 00243 if(tdivs1>divs1) divs1=tdivs1; 00244 if(tdivs2>divs2) divs2=tdivs2; 00245 if(tdivs3>divs3) divs3=tdivs3; 00246 } 00247 } // */ 00248 mTriangleDivs1[i] = divs1; 00249 mTriangleDivs2[i] = divs2; 00250 mTriangleDivs3[i] = divs3; 00251 } 00252 } 00253 00254 00255 /****************************************************************************** 00256 * load model from .obj file 00257 *****************************************************************************/ 00258 00259 int ntlGeometryObjModel::loadBobjModel(string filename) 00260 { 00261 bool haveAniSets=false; 00262 vector<ntlSetVec3f> aniverts; 00263 vector<ntlSetVec3f> aninorms; 00264 vector<double> anitimes; 00265 00266 const bool debugPrint=false; 00267 const bool debugPrintFull=false; 00268 gzFile gzf; 00269 gzf = gzopen(filename.c_str(), "rb"); 00270 if (!gzf) { 00271 errFatal("ntlGeometryObjModel::loadBobjModel","Reading GZ_BOBJ, Unable to open '"<< filename <<"'...\n", SIMWORLD_INITERROR ); 00272 return 1; 00273 } 00274 00275 int numVerts; 00276 if(sizeof(numVerts)!=4) { // paranoia check 00277 errMsg("Reading GZ_BOBJ"," Invalid int size, check compiler settings: int has to be 4 byte long"); 00278 goto gzreaderror; 00279 } 00280 gzread(gzf, &numVerts, sizeof(numVerts) ); 00281 if(numVerts<0 || numVerts>1e9) { 00282 errMsg("Reading GZ_BOBJ"," invalid num vertices "<< numVerts); 00283 goto gzreaderror; 00284 } 00285 mVertices.clear(); 00286 mVertices.resize( numVerts ); 00287 for(int i=0; i<numVerts; i++) { 00288 float x[3]; 00289 for(int j=0; j<3; j++) { 00290 gzread(gzf, &(x[j]), sizeof( (x[j]) ) ); 00291 } 00292 mVertices[i] = ntlVec3Gfx(x[0],x[1],x[2]); 00293 if(debugPrintFull) errMsg("FULLV"," "<<i<<" "<< mVertices[i] ); 00294 } 00295 if(debugPrint) errMsg("NV"," "<<numVerts<<" "<< mVertices.size() ); 00296 00297 // should be the same as Vertices.size 00298 gzread(gzf, &numVerts, sizeof(numVerts) ); 00299 if(numVerts<0 || numVerts>1e9) { 00300 errMsg("Reading GZ_BOBJ","invalid num normals "<< numVerts); 00301 goto gzreaderror; 00302 } 00303 mNormals.clear(); 00304 mNormals.resize( numVerts ); 00305 for(int i=0; i<numVerts; i++) { 00306 float n[3]; 00307 for(int j=0; j<3; j++) { 00308 gzread(gzf, &(n[j]), sizeof( (n[j]) ) ); 00309 } 00310 mNormals[i] = ntlVec3Gfx(n[0],n[1],n[2]); 00311 if(debugPrintFull) errMsg("FULLN"," "<<i<<" "<< mNormals[i] ); 00312 } 00313 if(debugPrint) errMsg("NN"," "<<numVerts<<" "<< mNormals.size() ); 00314 00315 int numTris; 00316 gzread(gzf, &numTris, sizeof(numTris) ); 00317 if(numTris<0 || numTris>1e9) { 00318 errMsg("Reading GZ_BOBJ","invalid num normals "<< numTris); 00319 goto gzreaderror; 00320 } 00321 mTriangles.resize( 3*numTris ); 00322 for(int i=0; i<numTris; i++) { 00323 int tri[3]; 00324 for(int j=0; j<3; j++) { 00325 gzread(gzf, &(tri[j]), sizeof( (tri[j]) ) ); 00326 } 00327 mTriangles[3*i+0] = tri[0]; 00328 mTriangles[3*i+1] = tri[1]; 00329 mTriangles[3*i+2] = tri[2]; 00330 } 00331 if(debugPrint) errMsg("NT"," "<<numTris<<" "<< mTriangles.size() ); 00332 00333 debMsgStd("ntlGeometryObjModel::loadBobjModel",DM_MSG, "File '"<<filename<<"' loaded, #Vertices: "<<mVertices.size()<<", #Normals: "<<mNormals.size()<<", #Triangles: "<<(mTriangles.size()/3)<<" ", 1 ); 00334 00335 // try to load animated mesh 00336 aniverts.clear(); 00337 aninorms.clear(); 00338 anitimes.clear(); 00339 while(1) { 00340 //ntlVec3Gfx check; 00341 float x[3]; 00342 float frameTime=0.; 00343 int bytesRead = 0; 00344 int numNorms2=-1, numVerts2=-1; 00345 //for(int j=0; j<3; j++) { 00346 //x[j] = 0.; 00347 //bytesRead += gzread(gzf, &(x[j]), sizeof(float) ); 00348 //} 00349 //check = ntlVec3Gfx(x[0],x[1],x[2]); 00350 //if(debugPrint) errMsg("ANI_NV1"," "<<check<<" "<<" bytes:"<<bytesRead ); 00351 bytesRead += gzread(gzf, &frameTime, sizeof(frameTime) ); 00352 //if(bytesRead!=3*sizeof(float)) { 00353 if(bytesRead!=sizeof(float)) { 00354 debMsgStd("ntlGeometryObjModel::loadBobjModel",DM_MSG, "File '"<<filename<<"' end of gzfile. ", 10 ); 00355 if(anitimes.size()>0) { 00356 // finally init channels and stop reading file 00357 mcAniVerts = AnimChannel<ntlSetVec3f>(aniverts,anitimes); 00358 mcAniNorms = AnimChannel<ntlSetVec3f>(aninorms,anitimes); 00359 } 00360 goto gzreaddone; 00361 } 00362 bytesRead += gzread(gzf, &numVerts2, sizeof(numVerts2) ); 00363 haveAniSets=true; 00364 // continue to read new set 00365 vector<ntlVec3Gfx> vertset; 00366 vector<ntlVec3Gfx> normset; 00367 vertset.resize(numVerts); 00368 normset.resize(numVerts); 00369 //vertset[0] = check; 00370 if(debugPrintFull) errMsg("FUL1V"," "<<0<<" "<< vertset[0] ); 00371 00372 for(int i=0; i<numVerts; i++) { // start at one! 00373 for(int j=0; j<3; j++) { 00374 bytesRead += gzread(gzf, &(x[j]), sizeof( (x[j]) ) ); 00375 } 00376 vertset[i] = ntlVec3Gfx(x[0],x[1],x[2]); 00377 if(debugPrintFull) errMsg("FUL2V"," "<<i<<" "<< vertset[i] ); 00378 } 00379 if(debugPrint) errMsg("ANI_VV"," "<<numVerts<<" "<< vertset.size()<<" bytes:"<<bytesRead ); 00380 00381 bytesRead += gzread(gzf, &numNorms2, sizeof(numNorms2) ); 00382 for(int i=0; i<numVerts; i++) { 00383 for(int j=0; j<3; j++) { 00384 bytesRead += gzread(gzf, &(x[j]), sizeof( (x[j]) ) ); 00385 } 00386 normset[i] = ntlVec3Gfx(x[0],x[1],x[2]); 00387 if(debugPrintFull) errMsg("FUL2N"," "<<i<<" "<< normset[i] ); 00388 } 00389 if(debugPrint) errMsg("ANI_NV"," "<<numVerts<<","<<numVerts2<<","<<numNorms2<<","<< normset.size()<<" bytes:"<<bytesRead ); 00390 00391 // set ok 00392 if(bytesRead== (int)( (numVerts*2*3+1) *sizeof(float)+2*sizeof(int) ) ) { 00393 if(aniverts.size()==0) { 00394 // TODO, ignore first mesh? 00395 double anitime = (double)(frameTime-1.); // start offset!? anitimes.size(); 00396 // get for current frame entry 00397 if(mcAniTimes.getSize()>1) anitime = mcAniTimes.get(anitime); 00398 anitime = anitime*mAniTimeScale+mAniTimeOffset; 00399 00400 anitimes.push_back( anitime ); 00401 aniverts.push_back( ntlSetVec3f(mVertices) ); 00402 aninorms.push_back( ntlSetVec3f(mNormals) ); 00403 if(debugPrint) errMsg("ANI_NV","new set "<<mVertices.size()<<","<< mNormals.size()<<" time:"<<anitime ); 00404 } 00405 double anitime = (double)(frameTime); //anitimes.size(); 00406 // get for current frame entry 00407 if(mcAniTimes.getSize()>1) anitime = mcAniTimes.get(anitime); 00408 anitime = anitime*mAniTimeScale+mAniTimeOffset; 00409 00410 anitimes.push_back( anitime ); 00411 aniverts.push_back( ntlSetVec3f(vertset) ); 00412 aninorms.push_back( ntlSetVec3f(normset) ); 00413 if(debugPrint) errMsg("ANI_NV","new set "<<vertset.size()<<","<< normset.size()<<" time:"<<anitime ); 00414 } else { 00415 errMsg("ntlGeometryObjModel::loadBobjModel","Malformed ani set! Aborting... ("<<bytesRead<<") "); 00416 goto gzreaddone; 00417 } 00418 } // anim sets */ 00419 00420 gzreaddone: 00421 00422 if(haveAniSets) { 00423 debMsgStd("ntlGeometryObjModel::loadBobjModel",DM_MSG, "File '"<<filename<<"' ani sets loaded: "<< mcAniVerts.accessValues().size() <<","<<mcAniNorms.accessValues().size() <<" ", 1 ); 00424 } 00425 gzclose( gzf ); 00426 return 0; 00427 00428 gzreaderror: 00429 mTriangles.clear(); 00430 mVertices.clear(); 00431 mNormals.clear(); 00432 gzclose( gzf ); 00433 errFatal("ntlGeometryObjModel::loadBobjModel","Reading GZ_BOBJ, Unable to load '"<< filename <<"', exiting...\n", SIMWORLD_INITERROR ); 00434 return 1; 00435 } 00436 00437 00438 /****************************************************************************** 00439 * 00440 *****************************************************************************/ 00441 void 00442 ntlGeometryObjModel::getTriangles(double t, vector<ntlTriangle> *triangles, 00443 vector<ntlVec3Gfx> *vertices, 00444 vector<ntlVec3Gfx> *normals, int objectId ) 00445 { 00446 if(!mLoaded) { // invalid type... 00447 return; 00448 } 00449 if(mcAniVerts.getSize()>1) { mVertices = mcAniVerts.get(t).mVerts; } 00450 if(mcAniNorms.getSize()>1) { mNormals = mcAniNorms.get(t).mVerts; } 00451 00452 int startvert = vertices->size(); 00453 vertices->resize( vertices->size() + mVertices.size() ); 00454 normals->resize( normals->size() + mVertices.size() ); 00455 for(int i=0; i<(int)mVertices.size(); i++) { 00456 (*vertices)[startvert+i] = mVertices[i]; 00457 (*normals)[startvert+i] = mNormals[i]; 00458 } 00459 00460 triangles->reserve(triangles->size() + mTriangles.size()/3 ); 00461 for(int i=0; i<(int)mTriangles.size(); i+=3) { 00462 int trip[3]; 00463 trip[0] = startvert+mTriangles[i+0]; 00464 trip[1] = startvert+mTriangles[i+1]; 00465 trip[2] = startvert+mTriangles[i+2]; 00466 00467 //sceneAddTriangle( 00468 //mVertices[trip[0]], mVertices[trip[1]], mVertices[trip[2]], 00469 //mNormals[trip[0]], mNormals[trip[1]], mNormals[trip[2]], 00470 //ntlVec3Gfx(0.0), 1 , triangles,vertices,normals ); /* normal unused */ 00471 sceneAddTriangleNoVert( trip, ntlVec3Gfx(0.0), 1 , triangles ); /* normal unused */ 00472 } 00473 objectId = -1; // remove warning 00474 // bobj 00475 return; 00476 } 00477 00478 00479 00480 00481