00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <core_api/scene.h>
00023 #include <core_api/object3d.h>
00024 #include <core_api/camera.h>
00025 #include <core_api/light.h>
00026 #include <core_api/background.h>
00027 #include <core_api/integrator.h>
00028 #include <core_api/imagefilm.h>
00029 #include <yafraycore/triangle.h>
00030 #include <yafraycore/kdtree.h>
00031 #include <yafraycore/ray_kdtree.h>
00032 #include <yafraycore/timer.h>
00033 #include <yafraycore/scr_halton.h>
00034 #include <yafraycore/vmap.h>
00035 #include <utilities/mcqmc.h>
00036 #include <utilities/sample_utils.h>
00037 #ifdef __APPLE__
00038 #include <sys/sysctl.h>
00039 #endif
00040 #include <iostream>
00041 #include <limits>
00042
00043 __BEGIN_YAFRAY
00044
00045 scene_t::scene_t(): volIntegrator(0), camera(0), imageFilm(0), tree(0), vtree(0), background(0), surfIntegrator(0),
00046 AA_samples(1), AA_passes(1), AA_threshold(0.05), nthreads(1), mode(1), do_depth(false), signals(0)
00047 {
00048 state.changes = C_ALL;
00049 state.stack.push_front(READY);
00050 state.nextFreeID = 1;
00051 state.curObj = 0;
00052 }
00053
00054 scene_t::~scene_t()
00055 {
00056 if(tree) delete tree;
00057 if(vtree) delete vtree;
00058 std::map<objID_t, objData_t>::iterator i;
00059 for(i = meshes.begin(); i != meshes.end(); ++i)
00060 {
00061 if(i->second.type == TRIM)
00062 delete i->second.obj;
00063 else
00064 delete i->second.mobj;
00065 }
00066 }
00067
00068 void scene_t::abort()
00069 {
00070 sig_mutex.lock();
00071 signals |= Y_SIG_ABORT;
00072 sig_mutex.unlock();
00073 }
00074
00075 int scene_t::getSignals() const
00076 {
00077 int sig;
00078 sig_mutex.lock();
00079 sig = signals;
00080 sig_mutex.unlock();
00081 return sig;
00082 }
00083
00084 void scene_t::getAAParameters(int &samples, int &passes, int &inc_samples, CFLOAT &threshold) const
00085 {
00086 samples = AA_samples;
00087 passes = AA_passes;
00088 inc_samples = AA_inc_samples;
00089 threshold = AA_threshold;
00090 }
00091
00092 bool scene_t::startGeometry()
00093 {
00094 if(state.stack.front() != READY) return false;
00095 state.stack.push_front(GEOMETRY);
00096 return true;
00097 }
00098
00099 bool scene_t::endGeometry()
00100 {
00101 if(state.stack.front() != GEOMETRY) return false;
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 state.stack.pop_front();
00112 return true;
00113 }
00114
00115 bool scene_t::startCurveMesh(objID_t id, int vertices)
00116 {
00117 if(state.stack.front() != GEOMETRY) return false;
00118 int ptype = 0 & 0xFF;
00119
00120
00121 objData_t &nObj = meshes[id];
00122
00123
00124
00125 nObj.obj = new triangleObject_t( 2 * (vertices-1) , true, false);
00126
00127 nObj.type = ptype;
00128 state.stack.push_front(OBJECT);
00129 state.changes |= C_GEOM;
00130 state.orco=false;
00131 state.curObj = &nObj;
00132
00133 nObj.points.reserve(2*vertices);
00134 return true;
00135 }
00136
00137 bool scene_t::endCurveMesh(const material_t *mat, float strandStart, float strandEnd, float strandShape)
00138 {
00139 if(state.stack.front() != OBJECT) return false;
00140
00141
00142
00143
00144
00145 std::vector<point3d_t> &points = state.curObj->points;
00146 float r;
00147 int i;
00148 point3d_t o,a,b;
00149 vector3d_t N(0),u(0),v(0);
00150 int n = points.size();
00151
00152 for (i=0;i<n;i++){
00153 o = points[i];
00154 if (strandShape < 0)
00155 {
00156 r = strandStart + pow((float)i/(n-1) ,1+strandShape) * ( strandEnd - strandStart );
00157 }
00158 else
00159 {
00160 r = strandStart + (1 - pow(((float)(n-i-1))/(n-1) ,1-strandShape)) * ( strandEnd - strandStart );
00161 }
00162
00163 if (i<n-1)
00164 {
00165 N = points[i+1]-points[i];
00166 N.normalize();
00167 createCS(N,u,v);
00168 }
00169
00170
00171 a = o - (0.5 * r *v) - 1.5 * r / sqrt(3) * u;
00172 b = o - (0.5 * r *v) + 1.5 * r / sqrt(3) * u;
00173
00174 state.curObj->points.push_back(a);
00175 state.curObj->points.push_back(b);
00176 }
00177
00178
00179 triangle_t tri;
00180 int a1,a2,a3,b1,b2,b3;
00181 float su,sv;
00182 int iu,iv;
00183 for (i=0;i<n-1;i++){
00184
00185 su = (float)i / (n-1);
00186 sv = su + 1. / (n-1);
00187 iu = addUV(su,su);
00188 iv = addUV(sv,sv);
00189
00190
00191
00192
00193 a1 = i;
00194 a2 = 2*i+n;
00195 a3 = a2 +1;
00196 b1 = i+1;
00197 b2 = a2 +2;
00198 b3 = b2 +1;
00199
00200 if (i == 0)
00201 {
00202 tri = triangle_t(a1, a3, a2, state.curObj->obj);
00203 tri.setMaterial(mat);
00204 state.curTri = state.curObj->obj->addTriangle(tri);
00205 state.curObj->obj->uv_offsets.push_back(iu);
00206 state.curObj->obj->uv_offsets.push_back(iu);
00207 state.curObj->obj->uv_offsets.push_back(iu);
00208 }
00209
00210
00211 tri = triangle_t(a1, b2, b1, state.curObj->obj);
00212 tri.setMaterial(mat);
00213 state.curTri = state.curObj->obj->addTriangle(tri);
00214
00215 state.curObj->obj->uv_offsets.push_back(iu);
00216 state.curObj->obj->uv_offsets.push_back(iv);
00217 state.curObj->obj->uv_offsets.push_back(iv);
00218
00219 tri = triangle_t(a1, a2, b2, state.curObj->obj);
00220 tri.setMaterial(mat);
00221 state.curTri = state.curObj->obj->addTriangle(tri);
00222 state.curObj->obj->uv_offsets.push_back(iu);
00223 state.curObj->obj->uv_offsets.push_back(iu);
00224 state.curObj->obj->uv_offsets.push_back(iv);
00225
00226 tri = triangle_t(a2, b3, b2, state.curObj->obj);
00227 tri.setMaterial(mat);
00228 state.curTri = state.curObj->obj->addTriangle(tri);
00229 state.curObj->obj->uv_offsets.push_back(iu);
00230 state.curObj->obj->uv_offsets.push_back(iv);
00231 state.curObj->obj->uv_offsets.push_back(iv);
00232
00233 tri = triangle_t(a2, a3, b3, state.curObj->obj);
00234 tri.setMaterial(mat);
00235 state.curTri = state.curObj->obj->addTriangle(tri);
00236 state.curObj->obj->uv_offsets.push_back(iu);
00237 state.curObj->obj->uv_offsets.push_back(iu);
00238 state.curObj->obj->uv_offsets.push_back(iv);
00239
00240 tri = triangle_t(b3, a3, a1, state.curObj->obj);
00241 tri.setMaterial(mat);
00242 state.curTri = state.curObj->obj->addTriangle(tri);
00243 state.curObj->obj->uv_offsets.push_back(iv);
00244 state.curObj->obj->uv_offsets.push_back(iu);
00245 state.curObj->obj->uv_offsets.push_back(iu);
00246
00247 tri = triangle_t(b3, a1, b1, state.curObj->obj);
00248 tri.setMaterial(mat);
00249 state.curTri = state.curObj->obj->addTriangle(tri);
00250 state.curObj->obj->uv_offsets.push_back(iv);
00251 state.curObj->obj->uv_offsets.push_back(iu);
00252 state.curObj->obj->uv_offsets.push_back(iv);
00253
00254 }
00255
00256 tri = triangle_t(i, 2*i+n, 2*i+n+1, state.curObj->obj);
00257 tri.setMaterial(mat);
00258 state.curTri = state.curObj->obj->addTriangle(tri);
00259 state.curObj->obj->uv_offsets.push_back(iv);
00260 state.curObj->obj->uv_offsets.push_back(iv);
00261 state.curObj->obj->uv_offsets.push_back(iv);
00262
00263 state.curObj->obj->setContext(state.curObj->points.begin(), state.curObj->normals.begin() );
00264 state.curObj->obj->finish();
00265
00266 state.stack.pop_front();
00267 return true;
00268 }
00269
00270 bool scene_t::startTriMesh(objID_t id, int vertices, int triangles, bool hasOrco, bool hasUV, int type)
00271 {
00272 if(state.stack.front() != GEOMETRY) return false;
00273 int ptype = type & 0xFF;
00274 if(ptype != TRIM && type != VTRIM && type != MTRIM) return false;
00275
00276 objData_t &nObj = meshes[id];
00277 switch(ptype)
00278 {
00279 case TRIM: nObj.obj = new triangleObject_t(triangles, hasUV, hasOrco);
00280 nObj.obj->setVisibility( !(type & INVISIBLEM) );
00281 break;
00282 case VTRIM:
00283 case MTRIM: nObj.mobj = new meshObject_t(triangles, hasUV, hasOrco);
00284 nObj.mobj->setVisibility( !(type & INVISIBLEM) );
00285 break;
00286 default: return false;
00287 }
00288 nObj.type = ptype;
00289 state.stack.push_front(OBJECT);
00290 state.changes |= C_GEOM;
00291 state.orco=hasOrco;
00292
00293 state.curObj = &nObj;
00294
00295
00296 if(hasOrco)
00297 {
00298
00299
00300 nObj.points.reserve(2*vertices);
00301 }
00302 else
00303 {
00304
00305 nObj.points.reserve(vertices);
00306 }
00307 return true;
00308 }
00309
00310 bool scene_t::endTriMesh()
00311 {
00312 if(state.stack.front() != OBJECT) return false;
00313
00314 if(state.curObj->type == TRIM)
00315 {
00316 if(state.curObj->obj->has_uv)
00317 {
00318 if( state.curObj->obj->uv_offsets.size() != 3*state.curObj->obj->triangles.size() )
00319 {
00320 std::cerr << "[FATAL ERROR]: UV-offsets mismatch!\n";
00321 return false;
00322 }
00323 }
00324
00325
00326 state.curObj->obj->setContext(state.curObj->points.begin(), state.curObj->normals.begin() );
00327
00328
00329
00330 state.curObj->obj->finish();
00331 }
00332 else
00333 {
00334 state.curObj->mobj->setContext(state.curObj->points.begin(), state.curObj->normals.begin() );
00335 state.curObj->mobj->finish();
00336 }
00337
00338 state.stack.pop_front();
00339
00340 return true;
00341 }
00342
00346 bool scene_t::startVmap(int id, int type, int dimensions)
00347 {
00348 if(state.stack.front() != GEOMETRY) return false;
00349 std::map<int, int>::iterator i = vmaps.find(id);
00350 if(i == vmaps.end())
00351 {
00352
00353 vmaps.insert(std::pair<int,int>(id, dimensions));
00354 }
00355 else
00356 {
00357
00358 if(i->second != dimensions) return false;
00359 }
00360
00361 int ntris;
00362 std::map<int, vmap_t> *vmm=0;
00363 if(state.curObj->type == TRIM)
00364 {
00365 vmm = &(state.curObj->obj->vmaps);
00366 ntris = state.curObj->obj->numPrimitives();
00367 }
00368 else
00369 {
00370 vmm = &(state.curObj->mobj->vmaps);
00371 ntris = state.curObj->mobj->numPrimitives();
00372 }
00373 std::map<int, vmap_t>::iterator vmap = vmm->find(id);
00374 if( vmap != vmm->end() ) return false;
00375 std::pair<std::map<int, vmap_t>::iterator, bool> res = vmm->insert( std::pair<int, vmap_t>(id, vmap_t()) );
00376 if(!res.second) return false;
00377 vmap = res.first;
00378 bool ok = vmap->second.init(type, dimensions, 3*ntris);
00379 if(!ok) vmm->erase(res.first);
00380 else state.stack.push_front(VMAP);
00381 state.cur_vmap = &(vmap->second);
00382 return ok;
00383 }
00384
00385 bool scene_t::endVmap()
00386 {
00387 if(state.stack.front() != VMAP) return false;
00388 state.stack.pop_front();
00389 return true;
00390 }
00391
00392 bool scene_t::addVmapValues(float *val)
00393 {
00394 if(state.stack.front() != VMAP) return false;
00395 state.cur_vmap->pushTriVal(val);
00396 return true;
00397 }
00398
00399 void scene_t::setNumThreads(int threads)
00400 {
00401 nthreads = threads;
00402
00403 if(nthreads == -1)
00404 {
00405 Y_INFO << "Automatic Detection of Threads: Active.\n";
00406
00407 #ifdef WIN32
00408 SYSTEM_INFO info;
00409 GetSystemInfo(&info);
00410 nthreads = (int) info.dwNumberOfProcessors;
00411 #else
00412 # ifdef __APPLE__
00413 int mib[2];
00414 size_t len;
00415
00416 mib[0] = CTL_HW;
00417 mib[1] = HW_NCPU;
00418 len = sizeof(int);
00419 sysctl(mib, 2, &nthreads, &len, NULL, 0);
00420 # elif defined(__sgi)
00421 nthreads = sysconf(_SC_NPROC_ONLN);
00422 # else
00423 nthreads = (int)sysconf(_SC_NPROCESSORS_ONLN);
00424 # endif
00425 #endif
00426
00427 Y_INFO << "Number of Threads supported: [" << nthreads << "].\n";
00428 }
00429 else
00430 {
00431 Y_INFO << "Automatic Detection of Threads: Inactive.\n";
00432 }
00433
00434 Y_INFO << "Using [" << nthreads << "] Threads.\n";
00435 }
00436
00437
00438 bool scene_t::smoothMesh(objID_t id, PFLOAT angle)
00439 {
00440 if( state.stack.front() != GEOMETRY ) return false;
00441 objData_t *odat;
00442 if(id)
00443 {
00444 std::map<objID_t, objData_t>::iterator it = meshes.find(id);
00445 if(it == meshes.end() ) return false;
00446 odat = &(it->second);
00447 }
00448 else
00449 {
00450 odat = state.curObj;
00451 if(!odat) return false;
00452 }
00453
00454 if(odat->type > 0) return false;
00455 unsigned int i1, i2, i3;
00456 std::vector<normal_t> &normals = odat->normals;
00457 std::vector<triangle_t> &triangles = odat->obj->triangles;
00458 std::vector<point3d_t> &points = odat->points;
00459 std::vector<triangle_t>::iterator tri;
00460 if (angle>=180)
00461 {
00462 normals.reserve(points.size());
00463 normals.resize(points.size(), normal_t(0,0,0));
00464 for (tri=triangles.begin(); tri!=triangles.end(); ++tri)
00465 {
00466 i1 = tri->pa;
00467 i2 = tri->pb;
00468 i3 = tri->pc;
00469
00470 vector3d_t normal = (vector3d_t)tri->normal;
00471 normals[i1] = normal_t( (vector3d_t)normals[i1] + normal );
00472 normals[i2] = normal_t( (vector3d_t)normals[i2] + normal );
00473 normals[i3] = normal_t( (vector3d_t)normals[i3] + normal );
00474 tri->setNormals(i1, i2, i3);
00475 }
00476 for (i1=0;i1<normals.size();i1++)
00477 normals[i1] = normal_t( vector3d_t(normals[i1]).normalize() );
00478
00479 odat->obj->setContext(odat->points.begin(), odat->normals.begin() );
00480 odat->obj->is_smooth = true;
00481 }
00482 else if(angle>0.1)
00483 {
00484 PFLOAT thresh = fCos(degToRad(angle));
00485
00486 std::vector<vector3d_t> vnormals;
00487 std::vector<int> vn_index;
00488
00489 std::vector<std::vector<triangle_t*> > vface(points.size());
00490 for (tri=triangles.begin(); tri!=triangles.end(); ++tri)
00491 {
00492 vface[tri->pa].push_back(&(*tri));
00493 vface[tri->pb].push_back(&(*tri));
00494 vface[tri->pc].push_back(&(*tri));
00495 }
00496 for(int i=0; i<(int)vface.size(); ++i)
00497 {
00498 std::vector<triangle_t*> &tris = vface[i];
00499 for(std::vector<triangle_t*>::iterator fi=tris.begin(); fi!=tris.end(); ++fi)
00500 {
00501 triangle_t* f = *fi;
00502 bool smooth = false;
00503
00504 vector3d_t vnorm(f->normal), fnorm(f->normal);
00505 for(std::vector<triangle_t*>::iterator f2=tris.begin(); f2!=tris.end(); ++f2)
00506 {
00507 if(fi == f2) continue;
00508 vector3d_t f2norm((*f2)->normal);
00509 if((fnorm * f2norm) > thresh)
00510 {
00511 smooth = true;
00512 vnorm += f2norm;
00513 }
00514 }
00515 int n_idx = -1;
00516 if(smooth)
00517 {
00518 vnorm.normalize();
00519
00520 for(unsigned int j=0; j<vnormals.size(); ++j)
00521 {
00522 if(vnorm*vnormals[j] > 0.999){ n_idx = vn_index[j]; break; }
00523 }
00524
00525 if(n_idx == -1)
00526 {
00527 n_idx = normals.size();
00528 vnormals.push_back(vnorm);
00529 vn_index.push_back(n_idx);
00530 normals.push_back( normal_t(vnorm) );
00531 }
00532 }
00533
00534 if (f->pa == i) f->na = n_idx;
00535 else if(f->pb == i) f->nb = n_idx;
00536 else if(f->pc == i) f->nc = n_idx;
00537 else{ std::cout << "!! mesh smoothing error!\n"; return false; }
00538 }
00539 vnormals.clear();
00540 vn_index.clear();
00541 }
00542
00543 odat->obj->setContext(odat->points.begin(), odat->normals.begin() );
00544 odat->obj->is_smooth = true;
00545 }
00546 return true;
00547 }
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 int scene_t::addVertex(const point3d_t &p)
00593 {
00594 if(state.stack.front() != OBJECT) return -1;
00595 state.curObj->points.push_back(p);
00596 if(state.curObj->type == MTRIM)
00597 {
00598 std::vector<point3d_t> &points = state.curObj->points;
00599 int n = points.size();
00600 if(n%3==0)
00601 {
00602
00603 points[n-2] = 2.f*points[n-2] - 0.5f*(points[n-3] + points[n-1]);
00604 }
00605 return (n-1)/3;
00606 }
00607 return state.curObj->points.size()-1;
00608 }
00609
00610 int scene_t::addVertex(const point3d_t &p, const point3d_t &orco)
00611 {
00612 if(state.stack.front() != OBJECT) return -1;
00613 state.curObj->points.push_back(p);
00614 state.curObj->points.push_back(orco);
00615 return (state.curObj->points.size()-1)/2;
00616 }
00617
00618 bool scene_t::addTriangle(int a, int b, int c, const material_t *mat)
00619 {
00620 if(state.stack.front() != OBJECT) return false;
00621 if(state.curObj->type == MTRIM)
00622 {
00623 bsTriangle_t tri(3*a, 3*b, 3*c, state.curObj->mobj);
00624 tri.setMaterial(mat);
00625 state.curObj->mobj->addBsTriangle(tri);
00626 }
00627 else if(state.curObj->type == VTRIM)
00628 {
00629 if(state.orco) a*=2, b*=2, c*=2;
00630 vTriangle_t tri(a, b, c, state.curObj->mobj);
00631 tri.setMaterial(mat);
00632 state.curObj->mobj->addTriangle(tri);
00633 }
00634 else
00635 {
00636 if(state.orco) a*=2, b*=2, c*=2;
00637 triangle_t tri(a, b, c, state.curObj->obj);
00638 tri.setMaterial(mat);
00639 state.curTri = state.curObj->obj->addTriangle(tri);
00640 }
00641 return true;
00642 }
00643
00644 bool scene_t::addTriangle(int a, int b, int c, int uv_a, int uv_b, int uv_c, const material_t *mat)
00645 {
00646 if(!addTriangle(a, b, c, mat)) return false;
00647
00648 if(state.curObj->type == TRIM)
00649 {
00650 state.curObj->obj->uv_offsets.push_back(uv_a);
00651 state.curObj->obj->uv_offsets.push_back(uv_b);
00652 state.curObj->obj->uv_offsets.push_back(uv_c);
00653 }
00654 else
00655 {
00656 state.curObj->mobj->uv_offsets.push_back(uv_a);
00657 state.curObj->mobj->uv_offsets.push_back(uv_b);
00658 state.curObj->mobj->uv_offsets.push_back(uv_c);
00659 }
00660
00661 return true;
00662 }
00663
00664 int scene_t::addUV(GFLOAT u, GFLOAT v)
00665 {
00666 if(state.stack.front() != OBJECT) return false;
00667 if(state.curObj->type == TRIM)
00668 {
00669 state.curObj->obj->uv_values.push_back(uv_t(u, v));
00670 return (int)state.curObj->obj->uv_values.size()-1;
00671 }
00672 else
00673 {
00674 state.curObj->mobj->uv_values.push_back(uv_t(u, v));
00675 return (int)state.curObj->mobj->uv_values.size()-1;
00676 }
00677 return -1;
00678 }
00679
00680 bool scene_t::addLight(light_t *l)
00681 {
00682 if(l != 0)
00683 {
00684 lights.push_back(l);
00685 state.changes |= C_LIGHT;
00686 return true;
00687 }
00688 return false;
00689 }
00690
00691 void scene_t::setCamera(camera_t *cam)
00692 {
00693 camera = cam;
00694 }
00695
00696 void scene_t::setImageFilm(imageFilm_t *film)
00697 {
00698 imageFilm = film;
00699 }
00700
00701 void scene_t::setBackground(background_t *bg)
00702 {
00703 background = bg;
00704
00705 }
00706
00707 void scene_t::setSurfIntegrator(surfaceIntegrator_t *s)
00708 {
00709 surfIntegrator = s;
00710 surfIntegrator->setScene(this);
00711 state.changes |= C_OTHER;
00712 }
00713
00714 void scene_t::setVolIntegrator(volumeIntegrator_t *v)
00715 {
00716 volIntegrator = v;
00717 volIntegrator->setScene(this);
00718 state.changes |= C_OTHER;
00719 }
00720
00721 background_t* scene_t::getBackground() const
00722 {
00723 return background;
00724 }
00725
00726 triangleObject_t* scene_t::getMesh(objID_t id) const
00727 {
00728 std::map<objID_t, objData_t>::const_iterator i = meshes.find(id);
00729 return (i==meshes.end()) ? 0 : i->second.obj;
00730 }
00731
00732 object3d_t* scene_t::getObject(objID_t id) const
00733 {
00734 std::map<objID_t, objData_t>::const_iterator i = meshes.find(id);
00735 if(i != meshes.end())
00736 {
00737 if(i->second.type == TRIM) return i->second.obj;
00738 else return i->second.mobj;
00739 }
00740 else
00741 {
00742 std::map<objID_t, object3d_t *>::const_iterator oi = objects.find(id);
00743 if(oi != objects.end() ) return oi->second;
00744 }
00745 return 0;
00746 }
00747
00748 bound_t scene_t::getSceneBound() const
00749 {
00750 return sceneBound;
00751 }
00752
00753 void scene_t::setAntialiasing(int numSamples, int numPasses, int incSamples, double threshold)
00754 {
00755 AA_samples = std::max(1, numSamples);
00756 AA_passes = numPasses;
00757 AA_inc_samples = (incSamples > 0) ? incSamples : AA_samples;
00758 AA_threshold = (CFLOAT)threshold;
00759 }
00760
00765 bool scene_t::update()
00766 {
00767 std::cout << "scene mode:" << mode << std::endl;
00768 if(!camera || !imageFilm) return false;
00769 if(state.changes & C_GEOM)
00770 {
00771 if(tree) delete tree;
00772 if(vtree) delete vtree;
00773 tree = 0, vtree = 0;
00774 int nprims=0;
00775 if(mode==0)
00776 {
00777 for(std::map<objID_t, objData_t>::iterator i=meshes.begin(); i!=meshes.end(); ++i)
00778 {
00779 objData_t &dat = (*i).second;
00780 if(!dat.obj->isVisible()) continue;
00781 if(dat.type == TRIM) nprims += dat.obj->numPrimitives();
00782 }
00783 if(nprims > 0)
00784 {
00785 const triangle_t **tris = new const triangle_t*[nprims];
00786 const triangle_t **insert = tris;
00787 for(std::map<objID_t, objData_t>::iterator i=meshes.begin(); i!=meshes.end(); ++i)
00788 {
00789 objData_t &dat = (*i).second;
00790 if(!dat.obj->isVisible()) continue;
00791 if(dat.type == TRIM) insert += dat.obj->getPrimitives(insert);
00792 }
00793 tree = new triKdTree_t(tris, nprims, -1, 1, 0.8, 0.33 );
00794 delete [] tris;
00795 sceneBound = tree->getBound();
00796 std::cout << "scene_t::update(): new scene bound is \n\t("<<sceneBound.a.x<<", "<<sceneBound.a.y<<", "<<sceneBound.a.z<<"), ("<<
00797 sceneBound.g.x<<", "<<sceneBound.g.y<<", "<<sceneBound.g.z<<")\n";
00798 }
00799 else std::cout << "scene is empty...\n";
00800 }
00801 else
00802 {
00803 for(std::map<objID_t, objData_t>::iterator i=meshes.begin(); i!=meshes.end(); ++i)
00804 {
00805 objData_t &dat = (*i).second;
00806 if(dat.type != TRIM) nprims += dat.mobj->numPrimitives();
00807 }
00808
00809 for(std::map<objID_t, object3d_t *>::iterator i=objects.begin(); i!=objects.end(); ++i)
00810 {
00811 nprims += i->second->numPrimitives();
00812 }
00813 if(nprims > 0)
00814 {
00815 const primitive_t **tris = new const primitive_t*[nprims];
00816 const primitive_t **insert = tris;
00817 for(std::map<objID_t, objData_t>::iterator i=meshes.begin(); i!=meshes.end(); ++i)
00818 {
00819 objData_t &dat = (*i).second;
00820 if(dat.type != TRIM) insert += dat.mobj->getPrimitives(insert);
00821 }
00822 for(std::map<objID_t, object3d_t *>::iterator i=objects.begin(); i!=objects.end(); ++i)
00823 {
00824 insert += i->second->getPrimitives(insert);
00825 }
00826 vtree = new kdTree_t<primitive_t>(tris, nprims, -1, 1, 0.8, 0.33 );
00827 delete [] tris;
00828 sceneBound = vtree->getBound();
00829 std::cout << "scene_t::update(): new scene bound is \n\t("<<sceneBound.a.x<<", "<<sceneBound.a.y<<", "<<sceneBound.a.z<<"), ("<<
00830 sceneBound.g.x<<", "<<sceneBound.g.y<<", "<<sceneBound.g.z<<")\n";
00831 }
00832 else std::cout << "scene is empty...\n";
00833 }
00834 }
00835 for(unsigned int i=0; i<lights.size(); ++i) lights[i]->init(*this);
00836 if(background)
00837 {
00838 light_t *bgl = background->getLight();
00839 if(bgl) bgl->init(*this);
00840 }
00841 if(!surfIntegrator){ std::cout << "no surface integrator!\n"; return false; }
00842 if(state.changes != C_NONE)
00843 {
00844 bool success = (surfIntegrator->preprocess() && volIntegrator->preprocess());
00845 if(!success) return false;
00846 }
00847 state.changes = C_NONE;
00848 return true;
00849 }
00850
00851 bool scene_t::intersect(const ray_t &ray, surfacePoint_t &sp) const
00852 {
00853 PFLOAT dis, Z;
00854 unsigned char udat[PRIM_DAT_SIZE];
00855 if(ray.tmax<0) dis=std::numeric_limits<PFLOAT>::infinity();
00856 else dis=ray.tmax;
00857
00858 if(mode == 0)
00859 {
00860 if(!tree) return false;
00861 triangle_t *hitt=0;
00862 if( ! tree->Intersect(ray, dis, &hitt, Z, (void*)&udat[0]) ){ return false; }
00863 point3d_t h=ray.from + Z*ray.dir;
00864 hitt->getSurface(sp, h, (void*)&udat[0]);
00865 sp.origin = hitt;
00866 }
00867 else
00868 {
00869 if(!vtree) return false;
00870 primitive_t *hitprim=0;
00871 if( ! vtree->Intersect(ray, dis, &hitprim, Z, (void*)&udat[0]) ){ return false; }
00872 point3d_t h=ray.from + Z*ray.dir;
00873 hitprim->getSurface(sp, h, (void*)&udat[0]);
00874 sp.origin = hitprim;
00875 }
00876 ray.tmax = Z;
00877 return true;
00878 }
00879
00880 bool scene_t::isShadowed(renderState_t &state, const ray_t &ray) const
00881 {
00882
00883 ray_t sray(ray);
00884 sray.from += sray.dir * sray.tmin;
00885 sray.time = state.time;
00886 PFLOAT dis;
00887 if(ray.tmax<0) dis=std::numeric_limits<PFLOAT>::infinity();
00888 else dis = sray.tmax - 2*sray.tmin;
00889 if(mode==0)
00890 {
00891 triangle_t *hitt=0;
00892 if(!tree) return false;
00893 return tree->IntersectS(sray, dis, &hitt);
00894 }
00895 else
00896 {
00897 primitive_t *hitt=0;
00898 if(!vtree) return false;
00899 return vtree->IntersectS(sray, dis, &hitt);
00900 }
00901 }
00902
00903 bool scene_t::isShadowed(renderState_t &state, const ray_t &ray, int maxDepth, color_t &filt) const
00904 {
00905 ray_t sray(ray);
00906 sray.from += sray.dir * sray.tmin;
00907 PFLOAT dis;
00908 if(ray.tmax<0) dis=std::numeric_limits<PFLOAT>::infinity();
00909 else dis = sray.tmax - 2*sray.tmin;
00910 filt = color_t(1.0);
00911 void *odat = state.userdata;
00912 unsigned char userdata[USER_DATA_SIZE+7];
00913 state.userdata = (void *)( ((size_t)&userdata[7])&(~7 ) );
00914 bool isect=false;
00915 if(mode==0)
00916 {
00917 triangle_t *hitt=0;
00918 if(tree) isect = tree->IntersectTS(state, sray, maxDepth, dis, &hitt, filt);
00919 }
00920 else
00921 {
00922 primitive_t *hitt=0;
00923 if(vtree) isect = vtree->IntersectTS(state, sray, maxDepth, dis, &hitt, filt);
00924 }
00925 state.userdata = odat;
00926 return isect;
00927 }
00928
00929
00930 bool scene_t::render()
00931 {
00932 sig_mutex.lock();
00933 signals = 0;
00934 sig_mutex.unlock();
00935
00936 if(!update()) return false;
00937
00938 bool success = surfIntegrator->render(imageFilm);
00939
00940 surfIntegrator->cleanup();
00941 imageFilm->flush();
00942
00943 return success;
00944 }
00945
00947 bool scene_t::addMaterial(material_t *m, const char* name) { return false; }
00948
00949 objID_t scene_t::getNextFreeID() {
00950 objID_t id;
00951 id = state.nextFreeID;
00952
00953 if(meshes.find(id) != meshes.end())
00954 {
00955 std::cerr << "program error! ID already in use!\n"; return 0;
00956 }
00957 ++state.nextFreeID;
00958 return id;
00959 }
00960
00961 bool scene_t::addObject(object3d_t *obj, objID_t &id)
00962 {
00963 id = getNextFreeID();
00964 if( id>0 )
00965 {
00966
00967 objects[id] = obj;
00968 return true;
00969 }
00970 else
00971 {
00972 return false;
00973 }
00974 }
00975
00976 __END_YAFRAY