YafaRay Core  v3.2.0-ALPHA-10-g60452c5
scene.cc
Go to the documentation of this file.
1 /****************************************************************************
2  * scene.cc: scene_t controls the rendering of a scene
3  * This is part of the yafray package
4  * Copyright (C) 2006 Mathias Wein
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 
22 #include <core_api/scene.h>
23 #include <core_api/object3d.h>
24 #include <core_api/camera.h>
25 #include <core_api/material.h>
26 #include <core_api/light.h>
27 #include <core_api/background.h>
28 #include <core_api/integrator.h>
29 #include <core_api/imagefilm.h>
30 #include <yafraycore/triangle.h>
31 #include <yafraycore/kdtree.h>
32 #include <yafraycore/ray_kdtree.h>
33 #include <yafraycore/timer.h>
34 #include <yafraycore/scr_halton.h>
35 #include <utilities/mcqmc.h>
36 #include <utilities/sample_utils.h>
37 #ifdef __APPLE__
38  #include <sys/sysctl.h>
39 #endif
40 #include <iostream>
41 #include <limits>
42 #include <sstream>
43 #if HAVE_UNISTD_H
44  #include <unistd.h>
45 #endif
46 
48 
49 scene_t::scene_t(const renderEnvironment_t *render_environment): volIntegrator(nullptr), camera(nullptr), imageFilm(nullptr), tree(nullptr), vtree(nullptr), background(nullptr), surfIntegrator(nullptr), AA_samples(1), AA_passes(1), AA_threshold(0.05), nthreads(1), nthreads_photons(1), mode(1), signals(0), env(render_environment)
50 {
52  state.stack.push_front(READY);
54  state.curObj = nullptr;
55 
56  AA_resampled_floor = 0.f;
60  AA_detect_color_noise = false;
64  AA_clamp_samples = 0.f;
65  AA_clamp_indirect = 0.f;
66 }
67 
69 {
70  if(tree) delete tree;
71  if(vtree) delete vtree;
72  for(auto i = meshes.begin(); i != meshes.end(); ++i)
73  {
74  if(i->second.type == TRIM)
75  delete i->second.obj;
76  else
77  delete i->second.mobj;
78  }
79 }
80 
82 {
83  sig_mutex.lock();
85  sig_mutex.unlock();
86 }
87 
89 {
90  int sig;
91  sig_mutex.lock();
92  sig = signals;
93  sig_mutex.unlock();
94  return sig;
95 }
96 
97 void scene_t::getAAParameters(int &samples, int &passes, int &inc_samples, float &threshold, float &resampled_floor, float &sample_multiplier_factor, float &light_sample_multiplier_factor, float &indirect_sample_multiplier_factor, bool &detect_color_noise, int &dark_detection_type, float &dark_threshold_factor, int &variance_edge_size, int &variance_pixels, float &clamp_samples, float &clamp_indirect) const
98 {
99  samples = AA_samples;
100  passes = AA_passes;
101  inc_samples = AA_inc_samples;
102  threshold = AA_threshold;
103  resampled_floor = AA_resampled_floor;
104  sample_multiplier_factor = AA_sample_multiplier_factor;
105  light_sample_multiplier_factor = AA_light_sample_multiplier_factor;
106  indirect_sample_multiplier_factor = AA_indirect_sample_multiplier_factor;
107  detect_color_noise = AA_detect_color_noise;
108  dark_detection_type = AA_dark_detection_type;
109  dark_threshold_factor = AA_dark_threshold_factor;
110  variance_edge_size = AA_variance_edge_size;
111  variance_pixels = AA_variance_pixels;
112  clamp_samples = AA_clamp_samples;
113  clamp_indirect = AA_clamp_indirect;
114 }
115 
117 {
118  if(state.stack.front() != READY) return false;
119  state.stack.push_front(GEOMETRY);
120  return true;
121 }
122 
124 {
125  if(state.stack.front() != GEOMETRY) return false;
126  // in case objects share arrays, so they all need to be updated
127  // after each object change, uncomment the below block again:
128  // don't forget to update the mesh object iterators!
129 /* for(auto i=meshes.begin();
130  i!=meshes.end(); ++i)
131  {
132  objData_t &dat = (*i).second;
133  dat.obj->setContext(dat.points.begin(), dat.normals.begin() );
134  }*/
135  state.stack.pop_front();
136  return true;
137 }
138 
139 bool scene_t::startCurveMesh(objID_t id, int vertices, int obj_pass_index)
140 {
141  if(state.stack.front() != GEOMETRY) return false;
142  int ptype = 0 & 0xFF;
143 
144  objData_t &nObj = meshes[id];
145 
146  //TODO: switch?
147  // Allocate triangles to render the curve
148  nObj.obj = new triangleObject_t( 2 * (vertices-1) , true, false);
149  nObj.obj->setObjectIndex(obj_pass_index);
150  nObj.type = ptype;
151  state.stack.push_front(OBJECT);
152  state.changes |= C_GEOM;
153  state.orco=false;
154  state.curObj = &nObj;
155 
156  nObj.obj->points.reserve(2*vertices);
157  return true;
158 }
159 
160 bool scene_t::endCurveMesh(const material_t *mat, float strandStart, float strandEnd, float strandShape)
161 {
162  if(state.stack.front() != OBJECT) return false;
163 
164  // TODO: Check if we have at least 2 vertex...
165  // TODO: math optimizations
166 
167  // extrude vertices and create faces
168  std::vector<point3d_t> &points = state.curObj->obj->points;
169  float r; //current radius
170  int i;
171  point3d_t o,a,b;
172  vector3d_t N(0),u(0),v(0);
173  int n = points.size();
174  // Vertex extruding
175  for (i=0;i<n;i++){
176  o = points[i];
177  if (strandShape < 0)
178  {
179  r = strandStart + pow((float)i/(n-1) ,1+strandShape) * ( strandEnd - strandStart );
180  }
181  else
182  {
183  r = strandStart + (1 - pow(((float)(n-i-1))/(n-1) ,1-strandShape)) * ( strandEnd - strandStart );
184  }
185  // Last point keep previous tangent plane
186  if (i<n-1)
187  {
188  N = points[i+1]-points[i];
189  N.normalize();
190  createCS(N,u,v);
191  }
192  // TODO: thikness?
193  a = o - (0.5 * r *v) - 1.5 * r / sqrt(3.f) * u;
194  b = o - (0.5 * r *v) + 1.5 * r / sqrt(3.f) * u;
195 
196  state.curObj->obj->points.push_back(a);
197  state.curObj->obj->points.push_back(b);
198  }
199 
200  // Face fill
201  triangle_t tri;
202  int a1,a2,a3,b1,b2,b3;
203  float su,sv;
204  int iu,iv;
205  for (i=0;i<n-1;i++){
206  // 1D particles UV mapping
207  su = (float)i / (n-1);
208  sv = su + 1. / (n-1);
209  iu = addUV(su,su);
210  iv = addUV(sv,sv);
211  a1 = i;
212  a2 = 2*i+n;
213  a3 = a2 +1;
214  b1 = i+1;
215  b2 = a2 +2;
216  b3 = b2 +1;
217  // Close bottom
218  if (i == 0)
219  {
220  tri = triangle_t(a1, a3, a2, state.curObj->obj);
221  tri.setMaterial(mat);
223  state.curObj->obj->uv_offsets.push_back(iu);
224  state.curObj->obj->uv_offsets.push_back(iu);
225  state.curObj->obj->uv_offsets.push_back(iu);
226  }
227 
228  // Fill
229  tri = triangle_t(a1, b2, b1, state.curObj->obj);
230  tri.setMaterial(mat);
232  // StrandUV
233  state.curObj->obj->uv_offsets.push_back(iu);
234  state.curObj->obj->uv_offsets.push_back(iv);
235  state.curObj->obj->uv_offsets.push_back(iv);
236 
237  tri = triangle_t(a1, a2, b2, state.curObj->obj);
238  tri.setMaterial(mat);
240  state.curObj->obj->uv_offsets.push_back(iu);
241  state.curObj->obj->uv_offsets.push_back(iu);
242  state.curObj->obj->uv_offsets.push_back(iv);
243 
244  tri = triangle_t(a2, b3, b2, state.curObj->obj);
245  tri.setMaterial(mat);
247  state.curObj->obj->uv_offsets.push_back(iu);
248  state.curObj->obj->uv_offsets.push_back(iv);
249  state.curObj->obj->uv_offsets.push_back(iv);
250 
251  tri = triangle_t(a2, a3, b3, state.curObj->obj);
252  tri.setMaterial(mat);
254  state.curObj->obj->uv_offsets.push_back(iu);
255  state.curObj->obj->uv_offsets.push_back(iu);
256  state.curObj->obj->uv_offsets.push_back(iv);
257 
258  tri = triangle_t(b3, a3, a1, state.curObj->obj);
259  tri.setMaterial(mat);
261  state.curObj->obj->uv_offsets.push_back(iv);
262  state.curObj->obj->uv_offsets.push_back(iu);
263  state.curObj->obj->uv_offsets.push_back(iu);
264 
265  tri = triangle_t(b3, a1, b1, state.curObj->obj);
266  tri.setMaterial(mat);
268  state.curObj->obj->uv_offsets.push_back(iv);
269  state.curObj->obj->uv_offsets.push_back(iu);
270  state.curObj->obj->uv_offsets.push_back(iv);
271 
272  }
273  // Close top
274  tri = triangle_t(i, 2*i+n, 2*i+n+1, state.curObj->obj);
275  tri.setMaterial(mat);
277  state.curObj->obj->uv_offsets.push_back(iv);
278  state.curObj->obj->uv_offsets.push_back(iv);
279  state.curObj->obj->uv_offsets.push_back(iv);
280 
281  state.curObj->obj->finish();
282 
283  state.stack.pop_front();
284  return true;
285 }
286 
287 bool scene_t::startTriMesh(objID_t id, int vertices, int triangles, bool hasOrco, bool hasUV, int type, int obj_pass_index)
288 {
289  if(state.stack.front() != GEOMETRY) return false;
290  int ptype = type & 0xFF;
291  if(ptype != TRIM && type != VTRIM && type != MTRIM) return false;
292 
293  objData_t &nObj = meshes[id];
294  switch(ptype)
295  {
296  case TRIM: nObj.obj = new triangleObject_t(triangles, hasUV, hasOrco);
297  nObj.obj->setVisibility( !(type & INVISIBLEM) );
298  nObj.obj->useAsBaseObject( (type & BASEMESH) );
299  nObj.obj->setObjectIndex(obj_pass_index);
300  break;
301  case VTRIM:
302  case MTRIM: nObj.mobj = new meshObject_t(triangles, hasUV, hasOrco);
303  nObj.mobj->setVisibility( !(type & INVISIBLEM) );
304  nObj.obj->setObjectIndex(obj_pass_index);
305  break;
306  default: return false;
307  }
308  nObj.type = ptype;
309  state.stack.push_front(OBJECT);
310  state.changes |= C_GEOM;
311  state.orco=hasOrco;
312  state.curObj = &nObj;
313 
314  return true;
315 }
316 
318 {
319  if(state.stack.front() != OBJECT) return false;
320 
321  if(state.curObj->type == TRIM)
322  {
323  if(state.curObj->obj->has_uv)
324  {
325  if( state.curObj->obj->uv_offsets.size() != 3*state.curObj->obj->triangles.size() )
326  {
327  Y_ERROR << "Scene: UV-offsets mismatch!" << yendl;
328  return false;
329  }
330  }
331 
332  //calculate geometric normals of tris
333  state.curObj->obj->finish();
334  }
335  else
336  {
337  state.curObj->mobj->finish();
338  }
339 
340  state.stack.pop_front();
341  return true;
342 }
343 
344 void scene_t::setNumThreads(int threads)
345 {
346  nthreads = threads;
347 
348  if(nthreads == -1) //Automatic detection of number of threads supported by this system, taken from Blender. (DT)
349  {
350  Y_VERBOSE << "Automatic Detection of Threads: Active." << yendl;
351 
352 #ifdef WIN32
353  SYSTEM_INFO info;
354  GetSystemInfo(&info);
355  nthreads = (int) info.dwNumberOfProcessors;
356 #else
357  # ifdef __APPLE__
358  int mib[2];
359  size_t len;
360 
361  mib[0] = CTL_HW;
362  mib[1] = HW_NCPU;
363  len = sizeof(int);
364  sysctl(mib, 2, &nthreads, &len, nullptr, 0);
365  # elif defined(__sgi)
366  nthreads = sysconf(_SC_NPROC_ONLN);
367  # else
368  nthreads = (int)sysconf(_SC_NPROCESSORS_ONLN);
369  # endif
370 #endif
371 
372  Y_VERBOSE << "Number of Threads supported: [" << nthreads << "]." << yendl;
373  }
374  else
375  {
376  Y_VERBOSE << "Automatic Detection of Threads: Inactive." << yendl;
377  }
378 
379  Y_PARAMS << "Using [" << nthreads << "] Threads." << yendl;
380 
381  std::stringstream set;
382  set << "CPU threads=" << nthreads << std::endl;
383 
384  yafLog.appendRenderSettings(set.str());
385 }
386 
387 void scene_t::setNumThreadsPhotons(int threads_photons)
388 {
389  nthreads_photons = threads_photons;
390 
391  if(nthreads_photons == -1) //Automatic detection of number of threads supported by this system, taken from Blender. (DT)
392  {
393  Y_VERBOSE << "Automatic Detection of Threads for Photon Mapping: Active." << yendl;
394 
395 #ifdef WIN32
396  SYSTEM_INFO info;
397  GetSystemInfo(&info);
398  nthreads_photons = (int) info.dwNumberOfProcessors;
399 #else
400  # ifdef __APPLE__
401  int mib[2];
402  size_t len;
403 
404  mib[0] = CTL_HW;
405  mib[1] = HW_NCPU;
406  len = sizeof(int);
407  sysctl(mib, 2, &nthreads_photons, &len, nullptr, 0);
408  # elif defined(__sgi)
409  nthreads_photons = sysconf(_SC_NPROC_ONLN);
410  # else
411  nthreads_photons = (int)sysconf(_SC_NPROCESSORS_ONLN);
412  # endif
413 #endif
414 
415  Y_VERBOSE << "Number of Threads supported for Photon Mapping: [" << nthreads_photons << "]." << yendl;
416  }
417  else
418  {
419  Y_VERBOSE << "Automatic Detection of Threads for Photon Mapping: Inactive." << yendl;
420  }
421 
422  Y_PARAMS << "Using for Photon Mapping [" << nthreads_photons << "] Threads." << yendl;
423 }
424 
425 #define prepareEdges(q, v1, v2) e1 = vertices[v1] - vertices[q]; \
426  e2 = vertices[v2] - vertices[q];
427 
428 bool scene_t::smoothMesh(objID_t id, float angle)
429 {
430  if( state.stack.front() != GEOMETRY ) return false;
431  objData_t *odat;
432  if(id)
433  {
434  auto it = meshes.find(id);
435  if(it == meshes.end() ) return false;
436  odat = &(it->second);
437  }
438  else
439  {
440  odat = state.curObj;
441  if(!odat) return false;
442  }
443 
444  if(odat->obj->normals_exported && odat->obj->points.size() == odat->obj->normals.size())
445  {
446  odat->obj->is_smooth = true;
447  return true;
448  }
449 
450  // cannot smooth other mesh types yet...
451  if(odat->type > 0) return false;
452  unsigned int idx = 0;
453  std::vector<normal_t> &normals = odat->obj->normals;
454  std::vector<triangle_t> &triangles = odat->obj->triangles;
455  size_t points = odat->obj->points.size();
456  std::vector<triangle_t>::iterator tri;
457  std::vector<point3d_t> const &vertices = odat->obj->points;
458 
459  normals.reserve(points);
460  normals.resize(points, normal_t(0,0,0));
461 
462  if (angle>=180)
463  {
464  for (tri=triangles.begin(); tri!=triangles.end(); ++tri)
465  {
466 
467  vector3d_t n = tri->getNormal();
468  vector3d_t e1, e2;
469  float alpha = 0;
470 
471  prepareEdges(tri->pa, tri->pb, tri->pc)
472  alpha = e1.sinFromVectors(e2);
473 
474  normals[tri->pa] += n * alpha;
475 
476  prepareEdges(tri->pb, tri->pa, tri->pc)
477  alpha = e1.sinFromVectors(e2);
478 
479  normals[tri->pb] += n * alpha;
480 
481  prepareEdges(tri->pc, tri->pa, tri->pb)
482  alpha = e1.sinFromVectors(e2);
483 
484  normals[tri->pc] += n * alpha;
485 
486  tri->setNormals(tri->pa, tri->pb, tri->pc);
487  }
488 
489  for (idx=0;idx<normals.size();++idx) normals[idx].normalize();
490 
491  }
492  else if(angle>0.1)// angle dependant smoothing
493  {
494  float thresh = fCos(degToRad(angle));
495  std::vector<vector3d_t> vnormals;
496  std::vector<int> vn_index;
497  // create list of faces that include given vertex
498  std::vector<std::vector<triangle_t*> > vface(points);
499  std::vector<std::vector<float> > alphas(points);
500  for (tri=triangles.begin(); tri!=triangles.end(); ++tri)
501  {
502  vector3d_t e1, e2;
503 
504  prepareEdges(tri->pa, tri->pb, tri->pc)
505  alphas[tri->pa].push_back(e1.sinFromVectors(e2));
506  vface[tri->pa].push_back(&(*tri));
507 
508  prepareEdges(tri->pb, tri->pa, tri->pc)
509  alphas[tri->pb].push_back(e1.sinFromVectors(e2));
510  vface[tri->pb].push_back(&(*tri));
511 
512  prepareEdges(tri->pc, tri->pa, tri->pb)
513  alphas[tri->pc].push_back(e1.sinFromVectors(e2));
514  vface[tri->pc].push_back(&(*tri));
515  }
516  for(int i=0; i<(int)vface.size(); ++i)
517  {
518  std::vector<triangle_t*> &tris = vface[i];
519  int j = 0;
520  for(auto fi=tris.begin(); fi!=tris.end(); ++fi)
521  {
522  triangle_t* f = *fi;
523  bool smooth = false;
524  // calculate vertex normal for face
525  vector3d_t vnorm, fnorm;
526 
527  fnorm = f->getNormal();
528  vnorm = fnorm * alphas[i][j];
529  int k = 0;
530  for(auto f2=tris.begin(); f2!=tris.end(); ++f2)
531  {
532  if(**fi == **f2)
533  {
534  k++;
535  continue;
536  }
537  vector3d_t f2norm = (*f2)->getNormal();
538  if((fnorm * f2norm) > thresh)
539  {
540  smooth = true;
541  vnorm += f2norm * alphas[i][k];
542  }
543  k++;
544  }
545  int n_idx = -1;
546  if(smooth)
547  {
548  vnorm.normalize();
549  //search for existing normal
550  for(unsigned int l=0; l<vnormals.size(); ++l)
551  {
552  if(vnorm*vnormals[l] > 0.999)
553  {
554  n_idx = vn_index[l];
555  break;
556  }
557  }
558  // create new if none found
559  if(n_idx == -1)
560  {
561  n_idx = normals.size();
562  vnormals.push_back(vnorm);
563  vn_index.push_back(n_idx);
564  normals.push_back( normal_t(vnorm) );
565  }
566  }
567  // set vertex normal to idx
568  if (f->pa == i) f->na = n_idx;
569  else if(f->pb == i) f->nb = n_idx;
570  else if(f->pc == i) f->nc = n_idx;
571  else
572  {
573  Y_ERROR << "Scene: Mesh smoothing error!" << yendl;
574  return false;
575  }
576  j++;
577  }
578  vnormals.clear();
579  vn_index.clear();
580  }
581  }
582 
583  odat->obj->is_smooth = true;
584 
585  return true;
586 }
587 
589 {
590  if(state.stack.front() != OBJECT) return -1;
591  state.curObj->obj->points.push_back(p);
592  if(state.curObj->type == MTRIM)
593  {
594  std::vector<point3d_t> &points = state.curObj->mobj->points;
595  int n = points.size();
596  if(n%3==0)
597  {
598  //convert point 2 to quadratic bezier control point
599  points[n-2] = 2.f*points[n-2] - 0.5f*(points[n-3] + points[n-1]);
600  }
601  return (n-1)/3;
602  }
603 
604  state.curObj->lastVertId = state.curObj->obj->points.size()-1;
605 
606  return state.curObj->lastVertId;
607 }
608 
609 int scene_t::addVertex(const point3d_t &p, const point3d_t &orco)
610 {
611  if(state.stack.front() != OBJECT) return -1;
612 
613  switch(state.curObj->type)
614  {
615  case TRIM:
616  state.curObj->obj->points.push_back(p);
617  state.curObj->obj->points.push_back(orco);
618  state.curObj->lastVertId = (state.curObj->obj->points.size()-1) / 2;
619  break;
620 
621  case VTRIM:
622  state.curObj->mobj->points.push_back(p);
623  state.curObj->mobj->points.push_back(orco);
624  state.curObj->lastVertId = (state.curObj->mobj->points.size()-1) / 2;
625  break;
626 
627  case MTRIM:
628  return addVertex(p);
629  }
630 
631  return state.curObj->lastVertId;
632 }
633 
635 {
636  if(mode != 0)
637  {
638  Y_WARNING << "Normal exporting is only supported for triangle mode" << yendl;
639  return;
640  }
641  if(state.curObj->obj->points.size() > state.curObj->lastVertId && state.curObj->obj->points.size() > state.curObj->obj->normals.size())
642  {
643  if(state.curObj->obj->normals.size() < state.curObj->obj->points.size())
644  state.curObj->obj->normals.resize(state.curObj->obj->points.size());
645 
646  state.curObj->obj->normals[state.curObj->lastVertId] = n;
647  state.curObj->obj->normals_exported = true;
648  }
649 }
650 
651 bool scene_t::addTriangle(int a, int b, int c, const material_t *mat)
652 {
653  if(state.stack.front() != OBJECT) return false;
654  if(state.curObj->type == MTRIM)
655  {
656  bsTriangle_t tri(3*a, 3*b, 3*c, state.curObj->mobj);
657  tri.setMaterial(mat);
659  }
660  else if(state.curObj->type == VTRIM)
661  {
662  if(state.orco) a*=2, b*=2, c*=2;
663  vTriangle_t tri(a, b, c, state.curObj->mobj);
664  tri.setMaterial(mat);
665  state.curObj->mobj->addTriangle(tri);
666  }
667  else
668  {
669  if(state.orco) a*=2, b*=2, c*=2;
670  triangle_t tri(a, b, c, state.curObj->obj);
671  tri.setMaterial(mat);
673  {
674  if(state.orco)
675  {
676  // Since the vertex indexes are duplicated with orco
677  // we divide by 2: a / 2 == a >> 1 since is an integer division
678  tri.na = a >> 1;
679  tri.nb = b >> 1;
680  tri.nc = c >> 1;
681  }
682  else
683  {
684  tri.na = a;
685  tri.nb = b;
686  tri.nc = c;
687  }
688  }
690  }
691  return true;
692 }
693 
694 bool scene_t::addTriangle(int a, int b, int c, int uv_a, int uv_b, int uv_c, const material_t *mat)
695 {
696  if(!addTriangle(a, b, c, mat)) return false;
697 
698  if(state.curObj->type == TRIM)
699  {
700  state.curObj->obj->uv_offsets.push_back(uv_a);
701  state.curObj->obj->uv_offsets.push_back(uv_b);
702  state.curObj->obj->uv_offsets.push_back(uv_c);
703  }
704  else
705  {
706  state.curObj->mobj->uv_offsets.push_back(uv_a);
707  state.curObj->mobj->uv_offsets.push_back(uv_b);
708  state.curObj->mobj->uv_offsets.push_back(uv_c);
709  }
710 
711  return true;
712 }
713 
714 int scene_t::addUV(float u, float v)
715 {
716  if(state.stack.front() != OBJECT) return false;
717  if(state.curObj->type == TRIM)
718  {
719  state.curObj->obj->uv_values.push_back(uv_t(u, v));
720  return (int)state.curObj->obj->uv_values.size()-1;
721  }
722  else
723  {
724  state.curObj->mobj->uv_values.push_back(uv_t(u, v));
725  return (int)state.curObj->mobj->uv_values.size()-1;
726  }
727  return -1;
728 }
729 
731 {
732  if(l != 0)
733  {
734  if(!l->lightEnabled()) return false; //if a light is disabled, don't add it to the list of lights
735  lights.push_back(l);
736  state.changes |= C_LIGHT;
737  return true;
738  }
739  return false;
740 }
741 
743 {
744  camera = cam;
745 }
746 
748 {
749  imageFilm = film;
750 }
751 
753 {
754  background = bg;
755 }
756 
758 {
759  surfIntegrator = s;
760  surfIntegrator->setScene(this);
761  state.changes |= C_OTHER;
762 }
763 
765 {
766  volIntegrator = v;
767  volIntegrator->setScene(this);
768  state.changes |= C_OTHER;
769 }
770 
772 {
773  return background;
774 }
775 
777 {
778  auto i = meshes.find(id);
779  return (i==meshes.end()) ? 0 : i->second.obj;
780 }
781 
783 {
784  auto i = meshes.find(id);
785  if(i != meshes.end())
786  {
787  if(i->second.type == TRIM) return i->second.obj;
788  else return i->second.mobj;
789  }
790  else
791  {
792  auto oi = objects.find(id);
793  if(oi != objects.end() ) return oi->second;
794  }
795  return nullptr;
796 }
797 
799 {
800  return sceneBound;
801 }
802 
803 void scene_t::setAntialiasing(int numSamples, int numPasses, int incSamples, double threshold, float resampled_floor, float sample_multiplier_factor, float light_sample_multiplier_factor, float indirect_sample_multiplier_factor, bool detect_color_noise, int dark_detection_type, float dark_threshold_factor, int variance_edge_size, int variance_pixels, float clamp_samples, float clamp_indirect)
804 {
805  AA_samples = std::max(1, numSamples);
806  AA_passes = numPasses;
807  AA_inc_samples = (incSamples > 0) ? incSamples : AA_samples;
808  AA_threshold = (float)threshold;
809  AA_resampled_floor = resampled_floor;
810  AA_sample_multiplier_factor = sample_multiplier_factor;
811  AA_light_sample_multiplier_factor = light_sample_multiplier_factor;
812  AA_indirect_sample_multiplier_factor = indirect_sample_multiplier_factor;
813  AA_detect_color_noise = detect_color_noise;
814  AA_dark_detection_type = dark_detection_type;
815  AA_dark_threshold_factor = dark_threshold_factor;
816  AA_variance_edge_size = variance_edge_size;
817  AA_variance_pixels = variance_pixels;
818  AA_clamp_samples = clamp_samples;
819  AA_clamp_indirect = clamp_indirect;
820 }
821 
827 {
828  Y_VERBOSE << "Scene: Mode \"" << ((mode == 0) ? "Triangle" : "Universal" ) << "\"" << yendl;
829  if(!camera || !imageFilm) return false;
830  if(state.changes & C_GEOM)
831  {
832  if(tree) delete tree;
833  if(vtree) delete vtree;
834  tree = nullptr, vtree = nullptr;
835  int nprims=0;
836  if(mode==0)
837  {
838  for(auto i=meshes.begin(); i!=meshes.end(); ++i)
839  {
840  objData_t &dat = (*i).second;
841 
842  if (!dat.obj->isVisible()) continue;
843  if (dat.obj->isBaseObject()) continue;
844 
845  if(dat.type == TRIM) nprims += dat.obj->numPrimitives();
846  }
847  if(nprims > 0)
848  {
849  const triangle_t **tris = new const triangle_t*[nprims];
850  const triangle_t **insert = tris;
851  for(auto i=meshes.begin(); i!=meshes.end(); ++i)
852  {
853  objData_t &dat = (*i).second;
854 
855  if (!dat.obj->isVisible()) continue;
856  if (dat.obj->isBaseObject()) continue;
857 
858  if(dat.type == TRIM) insert += dat.obj->getPrimitives(insert);
859  }
860  tree = new triKdTree_t(tris, nprims, -1, 1, 0.8, 0.33 /* -1, 1.2, 0.40 */ );
861  delete [] tris;
862  sceneBound = tree->getBound();
863  Y_VERBOSE << "Scene: New scene bound is:" <<
864  "(" << sceneBound.a.x << ", " << sceneBound.a.y << ", " << sceneBound.a.z << "), (" <<
865  sceneBound.g.x << ", " << sceneBound.g.y << ", " << sceneBound.g.z << ")" << yendl;
866 
867  if(shadowBiasAuto) shadowBias = YAF_SHADOW_BIAS;
868  if(rayMinDistAuto) rayMinDist = MIN_RAYDIST;
869 
870  Y_INFO << "Scene: total scene dimensions: X=" << sceneBound.longX() << ", Y=" << sceneBound.longY() << ", Z=" << sceneBound.longZ() << ", volume=" << sceneBound.vol() << ", Shadow Bias=" << shadowBias << (shadowBiasAuto ? " (auto)":"") << ", Ray Min Dist=" << rayMinDist << (rayMinDistAuto ? " (auto)":"") << yendl;
871  }
872  else Y_WARNING << "Scene: Scene is empty..." << yendl;
873  }
874  else
875  {
876  for(auto i=meshes.begin(); i!=meshes.end(); ++i)
877  {
878  objData_t &dat = (*i).second;
879  if(dat.type != TRIM) nprims += dat.mobj->numPrimitives();
880  }
881  // include all non-mesh objects; eventually make a common map...
882  for(auto i=objects.begin(); i!=objects.end(); ++i)
883  {
884  nprims += i->second->numPrimitives();
885  }
886  if(nprims > 0)
887  {
888  const primitive_t **tris = new const primitive_t*[nprims];
889  const primitive_t **insert = tris;
890  for(auto i=meshes.begin(); i!=meshes.end(); ++i)
891  {
892  objData_t &dat = (*i).second;
893  if(dat.type != TRIM) insert += dat.mobj->getPrimitives(insert);
894  }
895  for(auto i=objects.begin(); i!=objects.end(); ++i)
896  {
897  insert += i->second->getPrimitives(insert);
898  }
899  vtree = new kdTree_t<primitive_t>(tris, nprims, -1, 1, 0.8, 0.33 /* -1, 1.2, 0.40 */ );
900  delete [] tris;
902  Y_VERBOSE << "Scene: New scene bound is:" << yendl <<
903  "(" << sceneBound.a.x << ", " << sceneBound.a.y << ", " << sceneBound.a.z << "), (" <<
904  sceneBound.g.x << ", " << sceneBound.g.y << ", " << sceneBound.g.z << ")" << yendl;
905 
906  if(shadowBiasAuto) shadowBias = YAF_SHADOW_BIAS;
907  if(rayMinDistAuto) rayMinDist = MIN_RAYDIST;
908 
909  Y_INFO << "Scene: total scene dimensions: X=" << sceneBound.longX() << ", Y=" << sceneBound.longY() << ", Z=" << sceneBound.longZ() << ", volume=" << sceneBound.vol() << ", Shadow Bias=" << shadowBias << (shadowBiasAuto ? " (auto)":"") << ", Ray Min Dist=" << rayMinDist << (rayMinDistAuto ? " (auto)":"") << yendl;
910 
911  }
912  else Y_ERROR << "Scene: Scene is empty..." << yendl;
913  }
914  }
915 
916  for(unsigned int i=0; i<lights.size(); ++i) lights[i]->init(*this);
917 
918  if(!surfIntegrator)
919  {
920  Y_ERROR << "Scene: No surface integrator, bailing out..." << yendl;
921  return false;
922  }
923 
924  if(state.changes != C_NONE)
925  {
926  std::stringstream inteSettings;
927 
928  bool success = (surfIntegrator->preprocess() && volIntegrator->preprocess());
929 
930  if(!success) return false;
931  }
932 
933  state.changes = C_NONE;
934 
935  return true;
936 }
937 
938 bool scene_t::intersect(const ray_t &ray, surfacePoint_t &sp) const
939 {
940  float dis, Z;
941  intersectData_t data;
942  if(ray.tmax<0) dis=std::numeric_limits<float>::infinity();
943  else dis=ray.tmax;
944  // intersect with tree:
945  if(mode == 0)
946  {
947  if(!tree) return false;
948  triangle_t *hitt=0;
949  if( ! tree->Intersect(ray, dis, &hitt, Z, data) ){ return false; }
950  point3d_t h=ray.from + Z*ray.dir;
951  hitt->getSurface(sp, h, data);
952  sp.origin = hitt;
953  sp.data = data;
954  sp.ray = nullptr;
955  }
956  else
957  {
958  if(!vtree) return false;
959  primitive_t *hitprim=0;
960  if( ! vtree->Intersect(ray, dis, &hitprim, Z, data) ){ return false; }
961  point3d_t h=ray.from + Z*ray.dir;
962  hitprim->getSurface(sp, h, data);
963  sp.origin = hitprim;
964  sp.data = data;
965  sp.ray = nullptr;
966  }
967  ray.tmax = Z;
968  return true;
969 }
970 
971 bool scene_t::intersect(const diffRay_t &ray, surfacePoint_t &sp) const
972 {
973  float dis, Z;
974  intersectData_t data;
975  if(ray.tmax<0) dis=std::numeric_limits<float>::infinity();
976  else dis=ray.tmax;
977  // intersect with tree:
978  if(mode == 0)
979  {
980  if(!tree) return false;
981  triangle_t *hitt=0;
982  if( ! tree->Intersect(ray, dis, &hitt, Z, data) ){ return false; }
983  point3d_t h=ray.from + Z*ray.dir;
984  hitt->getSurface(sp, h, data);
985  sp.origin = hitt;
986  sp.data = data;
987  sp.ray = &ray;
988  }
989  else
990  {
991  if(!vtree) return false;
992  primitive_t *hitprim=0;
993  if( ! vtree->Intersect(ray, dis, &hitprim, Z, data) ){ return false; }
994  point3d_t h=ray.from + Z*ray.dir;
995  hitprim->getSurface(sp, h, data);
996  sp.origin = hitprim;
997  sp.data = data;
998  sp.ray = &ray;
999  }
1000  ray.tmax = Z;
1001  return true;
1002 }
1003 
1004 bool scene_t::isShadowed(renderState_t &state, const ray_t &ray, float &obj_index, float &mat_index) const
1005 {
1006 
1007  ray_t sray(ray);
1008  sray.from += sray.dir * sray.tmin;
1009  sray.time = state.time;
1010  float dis;
1011  if(ray.tmax<0) dis=std::numeric_limits<float>::infinity();
1012  else dis = sray.tmax - 2*sray.tmin;
1013  if(mode==0)
1014  {
1015  triangle_t *hitt=0;
1016  if(!tree) return false;
1017  bool shadowed = tree->IntersectS(sray, dis, &hitt, shadowBias);
1018  if(hitt)
1019  {
1020  if(hitt->getMesh()) obj_index = hitt->getMesh()->getAbsObjectIndex(); //Object index of the object casting the shadow
1021  if(hitt->getMaterial()) mat_index = hitt->getMaterial()->getAbsMaterialIndex(); //Material index of the object casting the shadow
1022  }
1023  return shadowed;
1024  }
1025  else
1026  {
1027  primitive_t *hitt=0;
1028  if(!vtree) return false;
1029  bool shadowed = vtree->IntersectS(sray, dis, &hitt, shadowBias);
1030  if(hitt)
1031  {
1032  if(hitt->getMaterial()) mat_index = hitt->getMaterial()->getAbsMaterialIndex(); //Material index of the object casting the shadow
1033  }
1034  return shadowed;
1035  }
1036 }
1037 
1038 bool scene_t::isShadowed(renderState_t &state, const ray_t &ray, int maxDepth, color_t &filt, float &obj_index, float &mat_index) const
1039 {
1040  ray_t sray(ray);
1041  sray.from += sray.dir * sray.tmin;
1042  float dis;
1043  if(ray.tmax<0) dis=std::numeric_limits<float>::infinity();
1044  else dis = sray.tmax - 2*sray.tmin;
1045  filt = color_t(1.0);
1046  void *odat = state.userdata;
1047  unsigned char userdata[USER_DATA_SIZE+7];
1048  state.userdata = (void *)( ((size_t)&userdata[7])&(~7 ) ); // pad userdata to 8 bytes
1049  bool isect=false;
1050  if(mode==0)
1051  {
1052  triangle_t *hitt=0;
1053  if(tree)
1054  {
1055  isect = tree->IntersectTS(state, sray, maxDepth, dis, &hitt, filt, shadowBias);
1056  if(hitt)
1057  {
1058  if(hitt->getMesh()) obj_index = hitt->getMesh()->getAbsObjectIndex(); //Object index of the object casting the shadow
1059  if(hitt->getMaterial()) mat_index = hitt->getMaterial()->getAbsMaterialIndex(); //Material index of the object casting the shadow
1060  }
1061  }
1062  }
1063  else
1064  {
1065  primitive_t *hitt=0;
1066  if(vtree)
1067  {
1068  isect = vtree->IntersectTS(state, sray, maxDepth, dis, &hitt, filt, shadowBias);
1069  if(hitt)
1070  {
1071  if(hitt->getMaterial()) mat_index = hitt->getMaterial()->getAbsMaterialIndex(); //Material index of the object casting the shadow
1072  }
1073  }
1074  }
1075  state.userdata = odat;
1076  return isect;
1077 }
1078 
1080 {
1081  sig_mutex.lock();
1082  signals = 0;
1083  sig_mutex.unlock();
1084 
1085  bool success = false;
1086 
1087  const std::map<std::string,camera_t *> *camera_table = env->getCameraTable();
1088 
1089  if(camera_table->size() == 0)
1090  {
1091  Y_ERROR << "No cameras/views found, exiting." << yendl;
1092  return false;
1093  }
1094 
1095  for(auto cam_table_entry = camera_table->begin(); cam_table_entry != camera_table->end(); ++cam_table_entry)
1096  {
1097  int numView = distance(camera_table->begin(), cam_table_entry);
1098  camera_t* cam = cam_table_entry->second;
1099  setCamera(cam);
1100  if(!update()) return false;
1101 
1102  success = surfIntegrator->render(numView, imageFilm);
1103 
1105  imageFilm->flush(numView);
1106  }
1107 
1108  return success;
1109 }
1110 
1112 bool scene_t::addMaterial(material_t *m, const char* name) { return false; }
1113 
1115 {
1116  objID_t id;
1117  id = state.nextFreeID;
1118 
1119  //create new entry for object, assert that no ID collision happens:
1120  if(meshes.find(id) != meshes.end())
1121  {
1122  Y_ERROR << "Scene: Object ID already in use!" << yendl;
1123  --state.nextFreeID;
1124  return getNextFreeID();
1125  }
1126 
1127  --state.nextFreeID;
1128 
1129  return id;
1130 }
1131 
1133 {
1134  id = getNextFreeID();
1135  if( id > 0 )
1136  {
1137  //create new triangle object:
1138  objects[id] = obj;
1139  return true;
1140  }
1141  else
1142  {
1143  return false;
1144  }
1145 }
1146 
1147 bool scene_t::addInstance(objID_t baseObjectId, matrix4x4_t objToWorld)
1148 {
1149  if(mode != 0) return false;
1150 
1151  if (meshes.find(baseObjectId) == meshes.end())
1152  {
1153  Y_ERROR << "Base mesh for instance doesn't exist " << baseObjectId << yendl;
1154  return false;
1155  }
1156 
1157  int id = getNextFreeID();
1158 
1159  if (id > 0)
1160  {
1161  objData_t &od = meshes[id];
1162  objData_t &base = meshes[baseObjectId];
1163 
1164  od.obj = new triangleObjectInstance_t(base.obj, objToWorld);
1165 
1166  return true;
1167  }
1168  else
1169  {
1170  return false;
1171  }
1172 }
1173 
1175 bool scene_t::pass_enabled(intPassTypes_t intPassType) const { return env->getRenderPasses()->pass_enabled(intPassType); }
1176 
1177 
point3d_t g
Definition: bound.h:134
vector3d_t dir
Definition: ray.h:19
int AA_inc_samples
sample count for additional passes
Definition: scene.h:233
bool Intersect(const ray_t &ray, float dist, T **tr, float &Z, intersectData_t &data) const
Definition: ray_kdtree.cc:691
bool lightEnabled() const
Enable/disable entire light source.
Definition: light.h:65
bool isVisible() const
Definition: object3d.h:57
intersectData_t data
Definition: surface.h:67
#define prepareEdges(q, v1, v2)
Definition: scene.cc:425
const renderPasses_t * getRenderPasses() const
Definition: scene.cc:1174
float fCos(float x)
meshObject_t * mobj
Definition: scene.h:127
bool pass_enabled(intPassTypes_t intPassType) const
Definition: scene.cc:1175
int nthreads
Definition: scene.h:246
void setMaterial(const material_t *m)
Definition: triangle.h:157
bool shadowBiasAuto
Definition: scene.h:212
void getAAParameters(int &samples, int &passes, int &inc_samples, float &threshold, float &resampled_floor, float &sample_multiplier_factor, float &light_sample_multiplier_factor, float &indirect_sample_multiplier_factor, bool &detect_color_noise, int &dark_detection_type, float &dark_threshold_factor, int &variance_edge_size, int &variance_pixels, float &clamp_samples, float &clamp_indirect) const
only for backward compatibility!
Definition: scene.cc:97
bool IntersectTS(renderState_t &state, const ray_t &ray, int maxDepth, float dist, T **tr, color_t &filt, float shadow_bias) const
Definition: ray_kdtree.cc:965
float longX() const
Returns the lenght along X axis.
Definition: bound.h:89
bool startTriMesh(objID_t id, int vertices, int triangles, bool hasOrco, bool hasUV=false, int type=0, int object_pass_index=0)
Definition: scene.cc:287
bool endTriMesh()
Definition: scene.cc:317
bool smoothMesh(objID_t id, float angle)
Definition: scene.cc:428
vector3d_t & normalize()
Definition: vector3d.h:267
void useAsBaseObject(bool v)
Definition: object3d.h:55
void setScene(scene_t *s)
this MUST be called before any other member function!
Definition: integrator.h:46
float AA_threshold
Definition: scene.h:234
bool render()
Definition: scene.cc:1079
void createCS(const vector3d_t &N, vector3d_t &u, vector3d_t &v)
Definition: vector3d.h:337
#define VTRIM
Definition: scene.h:20
int AA_variance_pixels
Definition: scene.h:243
std::vector< uv_t > uv_values
Definition: meshtypes.h:50
int AA_variance_edge_size
Definition: scene.h:242
Camera base class.
Definition: camera.h:37
virtual void cleanup()
Definition: integrator.h:72
int AA_passes
Definition: scene.h:232
triKdTree_t * tree
kdTree for triangle-only mode
Definition: scene.h:226
Definition: meshtypes.h:12
float z
Definition: vector3d.h:140
int addUV(float u, float v)
Definition: scene.cc:714
void setNumThreadsPhotons(int threads_photons)
Definition: scene.cc:387
void setNumThreads(int threads)
Definition: scene.cc:344
bool isBaseObject() const
Definition: object3d.h:59
#define __BEGIN_YAFRAY
void setMaterial(const material_t *m)
Definition: triangle.h:49
float tmin
Definition: ray.h:20
void setAntialiasing(int numSamples, int numPasses, int incSamples, double threshold, float resampled_floor, float sample_multiplier_factor, float light_sample_multiplier_factor, float indirect_sample_multiplier_factor, bool detect_color_noise, int dark_detection_type, float dark_threshold_factor, int variance_edge_size, int variance_pixels, float clamp_samples, float clamp_indirect)
Definition: scene.cc:803
virtual const material_t * getMaterial() const
Definition: triangle.h:42
float getAbsObjectIndex() const
Definition: object3d.h:68
std::mutex sig_mutex
Definition: scene.h:251
bool IntersectS(const ray_t &ray, float dist, triangle_t **tr, float shadow_bias) const
Definition: kdtree.cc:810
triangle_t * addTriangle(const triangle_t &t)
Definition: object3d.cc:38
bool addInstance(objID_t baseObjectId, matrix4x4_t objToWorld)
Definition: scene.cc:1147
Definition: ray.h:11
float AA_light_sample_multiplier_factor
Definition: scene.h:237
void abort()
Definition: scene.cc:81
const diffRay_t * ray
Definition: surface.h:97
int addVertex(const point3d_t &p)
Definition: scene.cc:588
bool addLight(light_t *l)
Definition: scene.cc:730
bool addMaterial(material_t *m, const char *name)
does not do anything yet...maybe never will
Definition: scene.cc:1112
#define degToRad(deg)
unsigned int changes
Definition: scene.h:135
background_t * getBackground() const
Definition: scene.cc:771
void setVisibility(bool v)
Definition: object3d.h:53
void setImageFilm(imageFilm_t *film)
Definition: scene.cc:747
size_t lastVertId
Definition: scene.h:129
bool startGeometry()
Definition: scene.cc:116
std::vector< point3d_t > points
Definition: meshtypes.h:47
void setBackground(background_t *bg)
Definition: scene.cc:752
virtual const material_t * getMaterial() const =0
float shadowBias
Definition: scene.h:211
scene_t(const renderEnvironment_t *render_environment)
Definition: scene.cc:49
bool startCurveMesh(objID_t id, int vertices, int object_pass_index=0)
Definition: scene.cc:139
std::vector< int > uv_offsets
Definition: meshtypes.h:49
#define Y_SIG_ABORT
Definition: scene.h:109
Definition: color.h:49
std::map< objID_t, object3d_t * > objects
Definition: scene.h:220
void appendRenderSettings(const std::string &render_settings)
Definition: logging.cc:360
triangleObject_t * obj
Definition: scene.h:126
int getPrimitives(const primitive_t **prims) const
Definition: object3d.cc:102
bool AA_detect_color_noise
Definition: scene.h:239
Definition: light.h:29
virtual bool preprocess()
Definition: integrator.h:85
bound_t getBound()
Definition: ray_kdtree.h:90
primitive_t * addBsTriangle(const bsTriangle_t &t)
Definition: object3d.cc:122
bool update()
Definition: scene.cc:826
bound_t sceneBound
bounding box of all (finite) scene geometry
Definition: scene.h:230
bool rayMinDistAuto
Definition: scene.h:215
std::list< unsigned int > stack
Definition: scene.h:134
kdTree_t< primitive_t > * vtree
kdTree for universal mode
Definition: scene.h:227
virtual vector3d_t getNormal() const
Definition: triangle.h:47
Definition: bound.h:50
float max(float a, float b)
Definition: GridVolume.cc:117
primitive_t * addTriangle(const vTriangle_t &t)
Definition: object3d.cc:116
int AA_dark_detection_type
Definition: scene.h:240
float AA_sample_multiplier_factor
Definition: scene.h:236
bool isShadowed(renderState_t &state, const ray_t &ray, float &obj_index, float &mat_index) const
Definition: scene.cc:1004
void finish()
Definition: object3d.cc:128
virtual bool preprocess()
Definition: integrator.h:69
bool IntersectTS(renderState_t &state, const ray_t &ray, int maxDepth, float dist, triangle_t **tr, color_t &filt, float shadow_bias) const
Definition: kdtree.cc:953
float AA_resampled_floor
minimum amount of resampled pixels (% of the total pixels) below which we will automatically decrease...
Definition: scene.h:235
virtual int getPrimitives(const triangle_t **prims)
Definition: object3d.cc:29
virtual void getSurface(surfacePoint_t &sp, const point3d_t &hit, intersectData_t &data) const
Definition: triangle.cc:13
bound_t getBound()
Definition: kdtree.h:137
int type
Definition: scene.h:128
#define TRIM
Definition: scene.h:19
int nthreads_photons
Definition: scene.h:247
surfaceIntegrator_t * surfIntegrator
Definition: scene.h:229
virtual bool render(int numView, imageFilm_t *imageFilm)
Definition: integrator.h:48
float tmax
Definition: ray.h:20
const std::map< std::string, camera_t * > * getCameraTable() const
Definition: environment.h:76
imageFilm_t * imageFilm
Definition: scene.h:225
float AA_clamp_samples
Definition: scene.h:244
objID_t nextFreeID
Definition: scene.h:136
float getAbsMaterialIndex() const
Definition: material.h:190
bool normals_exported
Definition: meshtypes.h:102
virtual int numPrimitives() const
Definition: meshtypes.h:74
#define MTRIM
Definition: scene.h:21
bool intersect(const ray_t &ray, surfacePoint_t &sp) const
Definition: scene.cc:938
object3d_t * getObject(objID_t id) const
Definition: scene.cc:782
float rayMinDist
Definition: scene.h:214
std::map< objID_t, objData_t > meshes
Definition: scene.h:221
void * userdata
a fixed amount of memory where materials may keep data to avoid recalculations...really need better m...
Definition: scene.h:83
bool Intersect(const ray_t &ray, float dist, triangle_t **tr, float &Z, intersectData_t &data) const
Definition: kdtree.cc:655
float x
Definition: vector3d.h:140
void setCamera(camera_t *cam)
Definition: scene.cc:742
virtual const triangleObject_t * getMesh() const
Definition: triangle.h:62
bool addObject(object3d_t *obj, objID_t &id)
Definition: scene.cc:1132
objData_t * curObj
Definition: scene.h:137
#define BASEMESH
Definition: scene.h:25
void setObjectIndex(const float &newObjIndex)
Definition: object3d.h:61
std::vector< light_t * > lights
Definition: scene.h:208
void flush(int numView, int flags=IF_ALL, colorOutput_t *out=nullptr)
Definition: imagefilm.cc:637
~scene_t()
Definition: scene.cc:68
virtual void getSurface(surfacePoint_t &sp, const point3d_t &hit, intersectData_t &data) const =0
#define USER_DATA_SIZE
Definition: scene.h:14
point3d_t a
Two points define the box.
Definition: bound.h:134
float time
relative frame time (values between [0;1]) at which ray was generated
Definition: ray.h:21
intPassTypes_t
Definition: renderpasses.h:113
sceneGeometryState_t state
Definition: scene.h:219
triangle_t * curTri
Definition: scene.h:138
#define Z
Definition: tribox3_d.cc:25
int numPrimitives() const
Definition: meshtypes.h:35
bool addTriangle(int a, int b, int c, const material_t *mat)
Definition: scene.cc:651
bool pass_enabled(intPassTypes_t intPassType) const
Definition: renderpasses.h:220
void setVolIntegrator(volumeIntegrator_t *v)
Definition: scene.cc:764
void addNormal(const normal_t &n)
Definition: scene.cc:634
camera_t * camera
Definition: scene.h:224
void * origin
Definition: surface.h:66
triangleObject_t * getMesh(objID_t id) const
Definition: scene.cc:776
float sinFromVectors(const vector3d_t &v)
Definition: vector3d.h:281
int signals
Definition: scene.h:249
const renderPasses_t * getRenderPasses() const
Definition: environment.h:75
#define INVISIBLEM
Definition: scene.h:24
volumeIntegrator_t * volIntegrator
Definition: scene.h:209
float time
the current (normalized) frame time
Definition: scene.h:82
Definition: ray.h:24
virtual void finish()
Definition: object3d.cc:45
float longZ() const
Returns the lenght along Y axis.
Definition: bound.h:93
float AA_indirect_sample_multiplier_factor
Definition: scene.h:238
unsigned int objID_t
Definition: scene.h:47
float longY() const
Returns the lenght along Y axis.
Definition: bound.h:91
void setMaterial(const material_t *m)
Definition: triangle.h:125
bound_t getSceneBound() const
Definition: scene.cc:798
int AA_samples
Definition: scene.h:232
float y
Definition: vector3d.h:140
void setSurfIntegrator(surfaceIntegrator_t *s)
Definition: scene.cc:757
int getSignals() const
Definition: scene.cc:88
float AA_dark_threshold_factor
Definition: scene.h:241
YAFRAYCORE_EXPORT yafarayLog_t yafLog
Definition: session.cc:30
const renderEnvironment_t * env
reference to the environment to which this scene belongs to
Definition: scene.h:250
objID_t getNextFreeID()
Definition: scene.cc:1114
point3d_t from
Definition: ray.h:18
background_t * background
Definition: scene.h:228
int mode
sets the scene mode (triangle-only, virtual primitives)
Definition: scene.h:248
float AA_clamp_indirect
Definition: scene.h:245
float vol() const
Returns the volume of the bound.
Definition: bound.cc:19
bool endCurveMesh(const material_t *mat, float strandStart, float strandEnd, float strandShape)
Definition: scene.cc:160
bool IntersectS(const ray_t &ray, float dist, T **tr, float shadow_bias) const
Definition: ray_kdtree.cc:833
bool endGeometry()
Definition: scene.cc:123
#define __END_YAFRAY