00001
00002 #include "std/config.H"
00003
00004 #include "std/stop_watch.H"
00005 #include "std/thread.H"
00006
00007 #include "disp/ray.H"
00008 #include "disp/gel.H"
00009 #include "disp/cam_focus.H"
00010 #include "disp/recorder.H"
00011 #include "disp/animator.H"
00012 #include "disp/frame_time_observer.H"
00013 #include "disp/paper_effect_base.H"
00014 #include "disp/jitter.H"
00015 #include "net/io_manager.H"
00016
00017 using namespace mlib;
00018
00019 #define DEFAULT_LIGHT_COORD_0 Wvec::Z()
00020 #define DEFAULT_LIGHT_POSITIONAL_0 false
00021 #define DEFAULT_LIGHT_IN_CAM_SPACE_0 true
00022 #define DEFAULT_LIGHT_DIFFUSE_0 COLOR(0.9,0.9,0.9)
00023 #define DEFAULT_LIGHT_AMBIENT_0 COLOR::black
00024 #define DEFAULT_LIGHT_SPECULAR_0 COLOR(0.9,0.9,0.9)
00025 #define DEFAULT_LIGHT_ENABLE_0 true
00026
00027 #define DEFAULT_LIGHT_COORD_1 Wvec::Z()
00028 #define DEFAULT_LIGHT_POSITIONAL_1 false
00029 #define DEFAULT_LIGHT_IN_CAM_SPACE_1 true
00030 #define DEFAULT_LIGHT_DIFFUSE_1 COLOR(0.9,0.0,0.0)
00031 #define DEFAULT_LIGHT_AMBIENT_1 COLOR::black
00032 #define DEFAULT_LIGHT_SPECULAR_1 COLOR::black
00033 #define DEFAULT_LIGHT_ENABLE_1 false
00034
00035 #define DEFAULT_LIGHT_COORD_2 Wvec::Z()
00036 #define DEFAULT_LIGHT_POSITIONAL_2 false
00037 #define DEFAULT_LIGHT_IN_CAM_SPACE_2 true
00038 #define DEFAULT_LIGHT_DIFFUSE_2 COLOR(0.0,0.9,0.0)
00039 #define DEFAULT_LIGHT_AMBIENT_2 COLOR::black
00040 #define DEFAULT_LIGHT_SPECULAR_2 COLOR::black
00041 #define DEFAULT_LIGHT_ENABLE_2 false
00042
00043 #define DEFAULT_LIGHT_COORD_3 Wvec::Z()
00044 #define DEFAULT_LIGHT_POSITIONAL_3 false
00045 #define DEFAULT_LIGHT_IN_CAM_SPACE_3 true
00046 #define DEFAULT_LIGHT_DIFFUSE_3 COLOR(0.0,0.0,0.9)
00047 #define DEFAULT_LIGHT_AMBIENT_3 COLOR::black
00048 #define DEFAULT_LIGHT_SPECULAR_3 COLOR::black
00049 #define DEFAULT_LIGHT_ENABLE_3 false
00050
00051 #define DEFAULT_LIGHT_GLOBAL_AMBIENT COLOR(0.1,0.1,0.1)
00052
00053
00054 hashvar<int> DONOT_CLIP_OBJ("DONOT_CLIP_OBJ", 0, 1);
00055 int VIEW::_num_views = 0;
00056 Threadobs_list *ThreadObs::_all_thread;
00057
00058 bool multithread = Config::get_var_bool("JOT_MULTITHREAD",false,true);
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 Cstr_ptr RSMOOTH_SHADE ("Smooth Shading");
00069 Cstr_ptr RFLAT_SHADE ("Flat Shading");
00070 Cstr_ptr RSPEC_SHADE ("Specular Shading");
00071 Cstr_ptr RHIDDEN_LINE ("Hidden Line");
00072 Cstr_ptr RWIRE_FRAME ("Wireframe");
00073 Cstr_ptr RNORMALS ("Normals");
00074 Cstr_ptr RNORMALS_ONLY ("Normals Only");
00075 Cstr_ptr RCOLOR_ID ("Color ID");
00076 Cstr_ptr RSHOW_TRI_STRIPS("Show tri-strips");
00077 Cstr_ptr RKEY_LINE ("Key Line");
00078 Cstr_ptr RSIL_FRAME ("Sil Frame");
00079 Cstr_ptr RLINE_DRAWING ("Line Drawing");
00080 Cstr_ptr RCURVATURE ("Curvature");
00081 Cstr_ptr SKYBOX_GRADIENT ("SkyBox_Texture");
00082
00083
00084
00085
00086 str_list VIEW::_rend_types(25);
00087 VIEWlist VIEW::_views;
00088 VIEWlist VIEWS;
00089 VIEWobs::view_list *VIEWobs::_view_obs;
00090
00091 unsigned int VIEW::_stamp = 0;
00092 double VIEW::_pix_to_ndc_scale = 0;
00093
00094 void
00095 FRAME_TIME_OBSERVER_list::frame_time_changed() const
00096 {
00097 for (int i=0; i<num(); i++)
00098 (*this)[i]->frame_time_changed();
00099 }
00100
00101 #ifdef USE_PTHREAD
00102 class ThreadToView : public ThreadObs {
00103 public:
00104 virtual void notify_render_thread(CVIEWptr &v) {
00105 assert(_instance);
00106 _data.set((VIEW *) &*v);
00107 }
00108 static VIEW *get() { assert(_instance); return (VIEW *) _data.get();}
00109 static void make_if_needed() {
00110 if (!_instance) {_instance = new ThreadToView();}
00111 }
00112 protected:
00113 ThreadToView() { thread_obs(); }
00114 static ThreadData _data;
00115 static ThreadToView *_instance;
00116 };
00117
00118 ThreadData ThreadToView::_data;
00119 ThreadToView *ThreadToView::_instance = 0;
00120 #endif
00121
00122
00123
00124
00125 TAGlist * VIEW::_v_tags = 0;
00126
00127 ARRAY<ARRAY<VEXEL>*> VIEW::_jitters;
00128
00129
00130
00131
00132 CTAGlist &
00133 VIEW::tags() const
00134 {
00135 if (!_v_tags) {
00136 _v_tags = new TAGlist;
00137
00138 *_v_tags += new TAG_meth<VIEW>(
00139 "view_animator",
00140 &VIEW::put_view_animator,
00141 &VIEW::get_view_animator,
00142 1);
00143
00144 *_v_tags += new TAG_meth<VIEW>(
00145 "view_data_file",
00146 &VIEW::put_view_data_file,
00147 &VIEW::get_view_data_file,
00148 1);
00149
00150 *_v_tags += new TAG_meth<VIEW>(
00151 "view_color",
00152 &VIEW::put_view_color,
00153 &VIEW::get_view_color,
00154 1);
00155
00156 *_v_tags += new TAG_meth<VIEW>(
00157 "view_alpha",
00158 &VIEW::put_view_alpha,
00159 &VIEW::get_view_alpha,
00160 1);
00161
00162 *_v_tags += new TAG_meth<VIEW>(
00163 "view_paper_use",
00164 &VIEW::put_view_paper_use,
00165 &VIEW::get_view_paper_use,
00166 1);
00167
00168 *_v_tags += new TAG_meth<VIEW>(
00169 "view_paper_name",
00170 &VIEW::put_view_paper_name,
00171 &VIEW::get_view_paper_name,
00172 1);
00173
00174 *_v_tags += new TAG_meth<VIEW>(
00175 "view_paper_active",
00176 &VIEW::put_view_paper_active,
00177 &VIEW::get_view_paper_active,
00178 1);
00179
00180 *_v_tags += new TAG_meth<VIEW>(
00181 "view_paper_brig",
00182 &VIEW::put_view_paper_brig,
00183 &VIEW::get_view_paper_brig,
00184 1);
00185
00186 *_v_tags += new TAG_meth<VIEW>(
00187 "view_paper_cont",
00188 &VIEW::put_view_paper_cont,
00189 &VIEW::get_view_paper_cont,
00190 1);
00191
00192 *_v_tags += new TAG_meth<VIEW>(
00193 "view_texture",
00194 &VIEW::put_view_texture,
00195 &VIEW::get_view_texture,
00196 1);
00197
00198 *_v_tags += new TAG_meth<VIEW>(
00199 "view_light_coords",
00200 &VIEW::put_view_light_coords,
00201 &VIEW::get_view_light_coords,
00202 1);
00203
00204 *_v_tags += new TAG_meth<VIEW>(
00205 "view_light_positional",
00206 &VIEW::put_view_light_positional,
00207 &VIEW::get_view_light_positional,
00208 1);
00209
00210 *_v_tags += new TAG_meth<VIEW>(
00211 "view_light_cam_space",
00212 &VIEW::put_view_light_cam_space,
00213 &VIEW::get_view_light_cam_space,
00214 1);
00215
00216 *_v_tags += new TAG_meth<VIEW>(
00217 "view_light_color_diff",
00218 &VIEW::put_view_light_color_diff,
00219 &VIEW::get_view_light_color_diff,
00220 1);
00221
00222 *_v_tags += new TAG_meth<VIEW>(
00223 "view_light_color_amb",
00224 &VIEW::put_view_light_color_amb,
00225 &VIEW::get_view_light_color_amb,
00226 1);
00227
00228 *_v_tags += new TAG_meth<VIEW>(
00229 "view_light_global",
00230 &VIEW::put_view_light_color_global,
00231 &VIEW::get_view_light_color_global,
00232 1);
00233
00234 *_v_tags += new TAG_meth<VIEW>(
00235 "view_light_enable",
00236 &VIEW::put_view_light_enable,
00237 &VIEW::get_view_light_enable,
00238 1);
00239
00240 *_v_tags += new TAG_meth<VIEW>(
00241 "view_antialias_enable",
00242 &VIEW::put_view_antialias_enable,
00243 &VIEW::get_view_antialias_enable,
00244 1);
00245
00246 *_v_tags += new TAG_meth<VIEW>(
00247 "view_antialias_mode",
00248 &VIEW::put_view_antialias_mode,
00249 &VIEW::get_view_antialias_mode,
00250 1);
00251
00252
00253 }
00254 return *_v_tags;
00255 }
00256
00257
00258
00259
00260
00261 void
00262 VIEW::get_view_data_file (TAGformat &d)
00263 {
00264
00265 assert(!_in_data_file);
00266
00267 str_ptr str;
00268 *d >> str;
00269
00270 if (str == "NULL_STR") {
00271 err_mesg(ERR_LEV_SPAM, "VIEW::get_view_data_file() - Loaded NULL string.");
00272 _data_file = NULL_STR;
00273 } else {
00274 err_mesg(ERR_LEV_SPAM, "VIEW::get_view_data_file() - Loaded string: '%s'.", **str);
00275 _data_file = str;
00276
00277 str_ptr fname = IOManager::load_prefix() + str + ".view";
00278
00279 err_mesg(ERR_LEV_SPAM, "VIEW::get_view_data_file() - Opening: '%s'...", **fname);
00280
00281 fstream fin;
00282 #if (defined (WIN32) && defined(_MSC_VER) && (_MSC_VER <=1300))
00283 fin.open(**(fname),ios::in | ios::nocreate);
00284 #else
00285 fin.open(**(fname),ios::in);
00286 #endif
00287 if (!fin)
00288 {
00289 err_msg("VIEW::get_view_data_file() - Could not open: '%s'!!", **fname);
00290
00291
00292 }
00293 else
00294 {
00295 STDdstream s(&fin);
00296 s >> str;
00297
00298 if (str != VIEW::static_name())
00299 {
00300 err_msg("VIEW::get_view_data_file() - Not 'VIEW': '%s'!!", **str);
00301 }
00302 else
00303 {
00304 _in_data_file = true;
00305 decode(s);
00306 _in_data_file = false;
00307 }
00308 }
00309 }
00310 }
00311
00312
00313
00314
00315 void
00316 VIEW::put_view_data_file (TAGformat &d) const
00317 {
00318
00319
00320 if (_in_data_file) return;
00321
00322
00323 if (_data_file == NULL_STR)
00324 {
00325 d.id();
00326 *d << str_ptr("NULL_STR");
00327 d.end_id();
00328 }
00329
00330
00331
00332 else
00333 {
00334 str_ptr fname = IOManager::save_prefix() + _data_file + ".view";
00335 fstream fout;
00336 fout.open(**fname,ios::out);
00337
00338 if (!fout)
00339 {
00340 err_msg("VIEW::put_view_data_file - Could not open: '%s', so changing to using no external npr file...!", **fname);
00341
00342
00343
00344 ((str_ptr)_data_file) = NULL_STR;
00345
00346 d.id();
00347 *d << str_ptr("NULL_STR");
00348 d.end_id();
00349 }
00350
00351 else
00352 {
00353 d.id();
00354 *d << _data_file;
00355 d.end_id();
00356
00357
00358
00359
00360
00361
00362 ((VIEW*)this)->_in_data_file = true;
00363 STDdstream stream(&fout);
00364 format(stream);
00365 ((VIEW*)this)->_in_data_file = false;
00366
00367 }
00368 }
00369 }
00370
00371
00372
00373
00374 void
00375 VIEW::get_view_animator(TAGformat &d)
00376 {
00377
00378 assert(!_in_data_file);
00379
00380 str_ptr str;
00381 *d >> str;
00382
00383 if (str != Animator::static_name())
00384 {
00385 err_msg("VIEW::get_view_animator() - 'Not Animator': '%s'!!", **str);
00386 }
00387 else
00388 {
00389 assert(_animator);
00390
00391 _animator->decode(*d);
00392 }
00393 }
00394
00395
00396
00397
00398 void
00399 VIEW::put_view_animator(TAGformat &d) const
00400 {
00401
00402
00403 if (_in_data_file) return;
00404
00405 assert(_animator);
00406
00407 d.id();
00408 _animator->format(*d);
00409 d.end_id();
00410
00411 }
00412
00413
00414
00415
00416 void
00417 VIEW::get_view_color(TAGformat &d)
00418 {
00419
00420 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00421 (!_in_data_file && (_data_file == NULL_STR)) );
00422
00423 COLOR c;
00424 *d >> c;
00425 set_color(c);
00426
00427 }
00428
00429
00430
00431
00432 void
00433 VIEW::put_view_color(TAGformat &d) const
00434 {
00435 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
00436
00437 assert(!(_in_data_file && _data_file == NULL_STR));
00438
00439 d.id();
00440 *d << color();
00441 d.end_id();
00442
00443 }
00444
00445
00446
00447
00448 void
00449 VIEW::get_view_alpha (TAGformat &d)
00450 {
00451
00452 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00453 (!_in_data_file && (_data_file == NULL_STR)) );
00454
00455 double a;
00456 *d >> a;
00457 set_alpha(a);
00458 }
00459
00460
00461
00462
00463 void
00464 VIEW::put_view_alpha (TAGformat &d) const
00465 {
00466 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
00467
00468 assert(!(_in_data_file && _data_file == NULL_STR));
00469
00470 d.id();
00471 *d << get_alpha();
00472 d.end_id();
00473
00474 }
00475
00476
00477
00478
00479 void
00480 VIEW::get_view_paper_use (TAGformat &d)
00481 {
00482
00483 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00484 (!_in_data_file && (_data_file == NULL_STR)) );
00485
00486 int p;
00487 *d >> p;
00488 set_use_paper((p==1)?true:false);
00489 }
00490
00491
00492
00493
00494 void
00495 VIEW::put_view_paper_use (TAGformat &d) const
00496 {
00497 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
00498
00499 assert(!(_in_data_file && _data_file == NULL_STR));
00500
00501 d.id();
00502 *d << ((get_use_paper())?(1):(0));
00503 d.end_id();
00504
00505 }
00506
00507
00508
00509
00510 void
00511 VIEW::get_view_paper_name (TAGformat &d)
00512 {
00513
00514 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00515 (!_in_data_file && (_data_file == NULL_STR)) );
00516
00517
00518 str_ptr str, tex, space;
00519 *d >> str;
00520
00521
00522
00523
00524
00525
00526
00527 if (!(*d).ascii()) *d >> space;
00528
00529 if (str == "NULL_STR")
00530 {
00531 tex = NULL_STR;
00532 err_mesg(ERR_LEV_SPAM, "VIEW::get_view_paper_name() - Loaded NULL string.");
00533 }
00534 else
00535 {
00536 tex = str;
00537 err_mesg(ERR_LEV_SPAM, "VIEW::get_view_paper_name() - Loaded string: '%s'", **tex);
00538 }
00539 PaperEffectBase::set_paper_tex(tex);
00540
00541 }
00542
00543
00544
00545
00546 void
00547 VIEW::put_view_paper_name (TAGformat &d) const
00548 {
00549 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
00550
00551 assert(!(_in_data_file && _data_file == NULL_STR));
00552
00553
00554 d.id();
00555 if (PaperEffectBase::get_paper_tex() == NULL_STR)
00556 {
00557 err_mesg(ERR_LEV_SPAM, "VIEW::put_view_paper_name() - Wrote NULL string.");
00558 *d << "NULL_STR";
00559 *d << " ";
00560 }
00561 else
00562 {
00563
00564 *d << PaperEffectBase::get_paper_tex();
00565 *d << " ";
00566 err_mesg(ERR_LEV_SPAM, "VIEW::put_view_paper_name() - Wrote string: '%s'", **PaperEffectBase::get_paper_tex());
00567 }
00568 d.end_id();
00569 }
00570
00571
00572
00573
00574 void
00575 VIEW::get_view_paper_active (TAGformat &d)
00576 {
00577
00578 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00579 (!_in_data_file && (_data_file == NULL_STR)) );
00580
00581 int a;
00582 *d >> a;
00583 PaperEffectBase::set_delayed_activate(a==1);
00584 }
00585
00586
00587
00588
00589 void
00590 VIEW::put_view_paper_active (TAGformat &d) const
00591 {
00592 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
00593
00594 assert(!(_in_data_file && _data_file == NULL_STR));
00595
00596 d.id();
00597 *d << ((PaperEffectBase::is_active())?(1):(0));
00598 d.end_id();
00599
00600 }
00601
00602
00603
00604
00605 void
00606 VIEW::get_view_paper_cont (TAGformat &d)
00607 {
00608
00609 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00610 (!_in_data_file && (_data_file == NULL_STR)) );
00611
00612 float c;
00613 *d >> c;
00614 PaperEffectBase::set_cont(c);
00615 }
00616
00617
00618
00619
00620 void
00621 VIEW::put_view_paper_cont (TAGformat &d) const
00622 {
00623 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
00624
00625 assert(!(_in_data_file && _data_file == NULL_STR));
00626
00627 d.id();
00628 *d << PaperEffectBase::get_cont();
00629 d.end_id();
00630
00631 }
00632
00633
00634
00635
00636 void
00637 VIEW::get_view_paper_brig (TAGformat &d)
00638 {
00639
00640 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00641 (!_in_data_file && (_data_file == NULL_STR)) );
00642
00643 float b;
00644 *d >> b;
00645 PaperEffectBase::set_brig(b);
00646 }
00647
00648
00649
00650
00651 void
00652 VIEW::put_view_paper_brig (TAGformat &d) const
00653 {
00654 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
00655
00656 assert(!(_in_data_file && _data_file == NULL_STR));
00657
00658 d.id();
00659 *d << PaperEffectBase::get_brig();
00660 d.end_id();
00661
00662 }
00663
00664
00665
00666 void
00667 VIEW::get_view_texture (TAGformat &d)
00668 {
00669
00670 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00671 (!_in_data_file && (_data_file == NULL_STR)) );
00672
00673 str_ptr str, space;
00674 *d >> str;
00675
00676 if (!(*d).ascii()) *d >> space;
00677
00678 if (str == "NULL_STR")
00679 {
00680 err_mesg(ERR_LEV_SPAM, "VIEW::get_view_texture() - Loaded NULL string.");
00681 set_bkg_file(NULL_STR);
00682 }
00683 else
00684 {
00685 err_mesg(ERR_LEV_SPAM, "VIEW::get_view_texture() - Loaded string: '%s'", **str);
00686 set_bkg_file(Config::JOT_ROOT() + str);
00687 }
00688
00689 }
00690
00691
00692
00693
00694 void
00695 VIEW::put_view_texture (TAGformat &d) const
00696 {
00697 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
00698
00699 assert(!(_in_data_file && _data_file == NULL_STR));
00700
00701
00702
00703 d.id();
00704 if (get_bkg_file() == NULL_STR)
00705 {
00706 err_mesg(ERR_LEV_SPAM, "VIEW::put_view_texture() - Wrote NULL string.");
00707 *d << "NULL_STR";
00708 *d << " ";
00709 }
00710 else
00711 {
00712
00713 str_ptr tex = get_bkg_file();
00714 str_ptr str;
00715 int i;
00716 for (i=Config::JOT_ROOT().len(); i<(int)tex.len(); i++)
00717 str = str + str_ptr(tex[i]);
00718 *d << **str;
00719 *d << " ";
00720 err_mesg(ERR_LEV_SPAM, "VIEW::put_view_texture() - Wrote string: '%s'", **str);
00721 }
00722 d.end_id();
00723
00724 }
00725
00726
00727
00728
00729 void
00730 VIEW::get_view_light_coords (TAGformat &d)
00731 {
00732
00733 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00734 (!_in_data_file && (_data_file == NULL_STR)) );
00735
00736 ARRAY<Wvec> c;
00737 *d >> c;
00738 assert(c.num() <= MAX_LIGHTS);
00739 for (int i=0; i<c.num(); i++)
00740 light_set_coordinates_v(i,c[i]);
00741
00742 }
00743
00744
00745
00746
00747 void
00748 VIEW::put_view_light_coords (TAGformat &d) const
00749 {
00750 if ((!_in_data_file) && (_data_file != NULL_STR))
00751 return;
00752
00753 ARRAY<Wvec> c;
00754 for (int i=0; i<MAX_LIGHTS; i++)
00755 c.add(light_get_coordinates_v(i));
00756 d.id();
00757 *d << c;
00758 d.end_id();
00759 }
00760
00761
00762
00763
00764 void
00765 VIEW::get_view_light_positional (TAGformat &d)
00766 {
00767
00768 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00769 (!_in_data_file && (_data_file == NULL_STR)) );
00770
00771 ARRAY<int> p;
00772 *d >> p;
00773 assert(p.num() <= MAX_LIGHTS);
00774 for (int i=0; i<MAX_LIGHTS; i++)
00775 light_set_positional(i,(p[i]==1)?(true):(false));
00776 }
00777
00778
00779
00780
00781 void
00782 VIEW::put_view_light_positional (TAGformat &d) const
00783 {
00784 if ((!_in_data_file) && (_data_file != NULL_STR))
00785 return;
00786
00787 ARRAY<int> p;
00788 for (int i=0; i<MAX_LIGHTS; i++)
00789 p.add((light_get_positional(i))?(1):(0));
00790 d.id();
00791 *d << p;
00792 d.end_id();
00793
00794 }
00795
00796
00797
00798
00799 void
00800 VIEW::get_view_light_cam_space (TAGformat &d)
00801 {
00802
00803 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00804 (!_in_data_file && (_data_file == NULL_STR)) );
00805
00806 ARRAY<int> c;
00807 *d >> c;
00808 assert(c.num() <= MAX_LIGHTS);
00809 for (int i=0; i<MAX_LIGHTS; i++)
00810 light_set_in_cam_space(i,((c[i]==1)?(true):(false)));
00811
00812 }
00813
00814
00815
00816
00817 void
00818 VIEW::put_view_light_cam_space (TAGformat &d) const
00819 {
00820 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
00821
00822 assert(!(_in_data_file && _data_file == NULL_STR));
00823
00824 ARRAY<int> c;
00825 for (int i=0; i<MAX_LIGHTS; i++)
00826 c.add((light_get_in_cam_space(i))?(1):(0));
00827 d.id();
00828 *d << c;
00829 d.end_id();
00830
00831 }
00832
00833
00834
00835
00836 void
00837 VIEW::get_view_light_color_diff (TAGformat &d)
00838 {
00839
00840 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00841 (!_in_data_file && (_data_file == NULL_STR)) );
00842
00843 ARRAY<COLOR> c;
00844 *d >> c;
00845 assert(c.num() <= MAX_LIGHTS);
00846 for (int i=0; i<MAX_LIGHTS; i++)
00847 light_set_diffuse(i,c[i]);
00848 }
00849
00850
00851
00852
00853 void
00854 VIEW::put_view_light_color_diff (TAGformat &d) const
00855 {
00856 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
00857
00858 assert(!(_in_data_file && _data_file == NULL_STR));
00859
00860 ARRAY<COLOR> c;
00861 for (int i=0; i<MAX_LIGHTS; i++)
00862 c.add(light_get_diffuse(i));
00863 d.id();
00864 *d << c;
00865 d.end_id();
00866
00867 }
00868
00869
00870
00871
00872 void
00873 VIEW::get_view_light_color_amb (TAGformat &d)
00874 {
00875
00876 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00877 (!_in_data_file && (_data_file == NULL_STR)) );
00878
00879 ARRAY<COLOR> a;
00880 *d >> a;
00881 assert(a.num() <= MAX_LIGHTS);
00882 for (int i=0; i<MAX_LIGHTS; i++)
00883 light_set_ambient(i,a[i]);
00884
00885 }
00886
00887
00888
00889
00890 void
00891 VIEW::put_view_light_color_amb (TAGformat &d) const
00892 {
00893 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
00894
00895 assert(!(_in_data_file && _data_file == NULL_STR));
00896
00897 ARRAY<COLOR> a;
00898 for (int i=0; i<MAX_LIGHTS; i++)
00899 a.add(light_get_ambient(i));
00900
00901 d.id();
00902 *d << a;
00903 d.end_id();
00904
00905 }
00906
00907
00908
00909
00910 void
00911 VIEW::get_view_light_color_global (TAGformat &d)
00912 {
00913
00914 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00915 (!_in_data_file && (_data_file == NULL_STR)) );
00916
00917 COLOR g;
00918 *d >> g;
00919 light_set_global_ambient(g);
00920
00921 }
00922
00923
00924
00925
00926 void
00927 VIEW::put_view_light_color_global (TAGformat &d) const
00928 {
00929 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
00930
00931 assert(!(_in_data_file && _data_file == NULL_STR));
00932
00933 d.id();
00934 *d << light_get_global_ambient();
00935 d.end_id();
00936
00937 }
00938
00939
00940
00941
00942 void
00943 VIEW::get_view_light_enable (TAGformat &d)
00944 {
00945
00946 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00947 (!_in_data_file && (_data_file == NULL_STR)) );
00948
00949 ARRAY<int> e;
00950 *d >> e;
00951 assert(e.num() <= MAX_LIGHTS);
00952 for (int i=0; i<MAX_LIGHTS; i++)
00953 light_set_enable(i,(e[i]==1)?(true):(false));
00954
00955 }
00956
00957
00958
00959
00960 void
00961 VIEW::put_view_light_enable (TAGformat &d) const
00962 {
00963 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
00964
00965 assert(!(_in_data_file && _data_file == NULL_STR));
00966
00967 ARRAY<int> e;
00968 for (int i=0; i<MAX_LIGHTS; i++)
00969 e.add((light_get_enable(i))?(1):(0));
00970 d.id();
00971 *d << e;
00972 d.end_id();
00973
00974 }
00975
00976
00977
00978
00979 void
00980 VIEW::get_view_antialias_enable (TAGformat &d)
00981 {
00982
00983 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
00984 (!_in_data_file && (_data_file == NULL_STR)) );
00985
00986 int e;
00987 *d >> e;
00988
00989 set_antialias_enable(e!=0);
00990
00991 }
00992
00993
00994
00995
00996 void
00997 VIEW::put_view_antialias_enable (TAGformat &d) const
00998 {
00999 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
01000
01001 assert(!(_in_data_file && _data_file == NULL_STR));
01002
01003 d.id();
01004 *d << get_antialias_enable();
01005 d.end_id();
01006 }
01007
01008
01009
01010
01011
01012 void
01013 VIEW::get_view_antialias_mode (TAGformat &d)
01014 {
01015
01016 assert( ( _in_data_file && (_data_file != NULL_STR)) ||
01017 (!_in_data_file && (_data_file == NULL_STR)) );
01018
01019 int m;
01020 *d >> m;
01021
01022 set_antialias_mode(m);
01023
01024 }
01025
01026
01027
01028
01029 void
01030 VIEW::put_view_antialias_mode (TAGformat &d) const
01031 {
01032 if ((!_in_data_file) && (_data_file != NULL_STR)) return;
01033
01034 assert(!(_in_data_file && _data_file == NULL_STR));
01035
01036 d.id();
01037 *d << get_antialias_mode();
01038 d.end_id();
01039 }
01040
01041 #ifdef USE_PTHREAD
01042 VIEWptr
01043 VIEW::peek()
01044 {
01045 VIEW *thread_view = ThreadToView::get();
01046 return thread_view ? VIEWptr(thread_view) : _views.last();
01047 }
01048
01049 const VIEW *
01050 VIEW::peek_ptr()
01051 {
01052 VIEW *thread_view = ThreadToView::get();
01053 return thread_view ? thread_view : &*_views.last();
01054 }
01055 #endif
01056
01057
01058 VIEW::VIEW(
01059 Cstr_ptr &s,
01060 WINSYS *w,
01061 VIEWimpl *i ) :
01062 _in_data_file(false),
01063 _impl(i),
01064 _view_id(_num_views),
01065 _cam(new CAM(str_ptr("camera"))),
01066 _cam_hist(100),
01067 _cam_hist_cur(0),
01068 _width(0),
01069 _height(0),
01070 _tris(0),
01071 _is_clipping(0),
01072 _dont_swap(0),
01073 _dont_draw(0),
01074 _messages_sent(0),
01075 _has_scissor_region(0),
01076 _sxmin(-1),
01077 _sxmax(1),
01078 _recorder(0),
01079 _alpha(1),
01080 _use_paper(false),
01081 _bkg_file(NULL_STR),
01082 _bkg_tex(NULL),
01083 _data_file(NULL_STR),
01084 _animator(0),
01085 _render_mode(NORMAL_MODE),
01086 _antialias_mode(2),
01087 _antialias_enable(0),
01088 _antialias_init(false),
01089 _line_scale(1.0),
01090 _grabbing_screen(0),
01091 _spf(1.0 / Config::get_var_dbl("JOT_FPS",60)),
01092 _frame_time(0),
01093 _win(w)
01094 {
01095 #ifdef USE_PTHREAD
01096 ThreadToView::make_if_needed();
01097 #endif
01098 init_lights();
01099 init_jitter();
01100
01101 _stereo = VIEWimpl::NONE;
01102 _render_type = Config::get_var_str("JOT_RENDER_STYLE",RSMOOTH_SHADE);
01103 _name = s;
01104 _tris = 0;
01105
01106 disp_obs();
01107
01108 _animator = new Animator(this);
01109 assert(_animator);
01110
01111 _recorder = new Recorder(this);
01112 assert(_recorder);
01113
01114 _num_views++;
01115
01116 if (_rend_types.empty()) {
01117
01118 add_rend_type(RSMOOTH_SHADE);
01119 add_rend_type(RFLAT_SHADE);
01120 add_rend_type(RHIDDEN_LINE);
01121
01122 if (!Config::get_var_bool("JOT_MINIMAL_RENDER_STYLES",false)) {
01123 add_rend_type(RWIRE_FRAME);
01124 add_rend_type(RNORMALS);
01125 add_rend_type(RSHOW_TRI_STRIPS);
01126 add_rend_type(RKEY_LINE);
01127 add_rend_type(RSIL_FRAME);
01128 }
01129 if (Config::get_var_bool("ENABLE_CURVATURE_TEXTURE",false))
01130 add_rend_type(RCURVATURE);
01131 if (Config::get_var_bool("ENABLE_LINE_DRAWING",false))
01132 add_rend_type(RLINE_DRAWING);
01133 if (Config::get_var_bool("ENABLE_SKYBOX_TEXTURE",false))
01134 add_rend_type(SKYBOX_GRADIENT);
01135 }
01136
01137 VIEWS.add(this);
01138
01139 _impl->set_view(this);
01140 }
01141
01142 void
01143 VIEW::set_jitter(
01144 int n,
01145 int i
01146 )
01147 {
01148 if (n==-1)
01149 {
01150 _jitter(0,3) = 0;
01151 _jitter(1,3) = 0;
01152 }
01153 else
01154 {
01155 assert(_jitters.valid_index(n));
01156 assert((*(_jitters[n])).valid_index(i));
01157 XYvec jit((*(_jitters[n]))[i]);
01158
01159 _jitter(0,3) = -jit[0];
01160 _jitter(1,3) = -jit[1];
01161 }
01162 }
01163
01164
01165 void
01166 VIEW::init_jitter()
01167 {
01168
01169 for(int n=0; n<JITTER_NUM; n++)
01170 {
01171 ARRAY<VEXEL>* jits = new ARRAY<VEXEL>(jnum[n]);
01172 _jitters.add(jits);
01173
01174 for (int i=0; i<jnum[n]; i++)
01175 jits->add(VEXEL(j[n][i].x,j[n][i].y));
01176 }
01177
01178 }
01179
01180 void
01181 VIEW::init_lights()
01182 {
01183 _lights[0] = Light(
01184 DEFAULT_LIGHT_COORD_0,
01185 DEFAULT_LIGHT_ENABLE_0,
01186 DEFAULT_LIGHT_IN_CAM_SPACE_0,
01187 DEFAULT_LIGHT_AMBIENT_0,
01188 DEFAULT_LIGHT_DIFFUSE_0,
01189 DEFAULT_LIGHT_SPECULAR_0
01190 );
01191
01192 _lights[1] = Light(
01193 DEFAULT_LIGHT_COORD_1,
01194 DEFAULT_LIGHT_ENABLE_1,
01195 DEFAULT_LIGHT_IN_CAM_SPACE_1,
01196 DEFAULT_LIGHT_AMBIENT_1,
01197 DEFAULT_LIGHT_DIFFUSE_1,
01198 DEFAULT_LIGHT_SPECULAR_1
01199 );
01200
01201 _lights[2] = Light(
01202 DEFAULT_LIGHT_COORD_2,
01203 DEFAULT_LIGHT_ENABLE_2,
01204 DEFAULT_LIGHT_IN_CAM_SPACE_2,
01205 DEFAULT_LIGHT_AMBIENT_2,
01206 DEFAULT_LIGHT_DIFFUSE_2,
01207 DEFAULT_LIGHT_SPECULAR_2
01208 );
01209
01210 _lights[3] = Light(
01211 DEFAULT_LIGHT_COORD_3,
01212 DEFAULT_LIGHT_ENABLE_3,
01213 DEFAULT_LIGHT_IN_CAM_SPACE_3,
01214 DEFAULT_LIGHT_AMBIENT_3,
01215 DEFAULT_LIGHT_DIFFUSE_3,
01216 DEFAULT_LIGHT_SPECULAR_3
01217 );
01218
01219 _light_global_ambient = DEFAULT_LIGHT_GLOBAL_AMBIENT;
01220 }
01221
01222 void
01223 VIEW::set_frame_time(double t)
01224 {
01225 if (_frame_time != t) {
01226 _frame_time = t;
01227 _frame_time_observers.frame_time_changed();
01228 }
01229 }
01230
01231 void
01232 VIEW::paint()
01233 {
01234 if (dont_draw())
01235 return;
01236
01237
01238 if (_spf_timer.elapsed_time() < _spf)
01239 return;
01240 _spf_timer.set();
01241
01242 _stamp++;
01243
01244 if (!_antialias_init)
01245 if (_impl && !_impl->antialias_check())
01246 _antialias_enable = 0;
01247
01248 _pix_to_ndc_scale = (_width > _height ? 2.0/_height : 2.0/_width);
01249
01250
01251
01252
01253 assert(!(_recorder->on() && _animator->on()));
01254
01255 if (_animator->on()) {
01256 set_frame_time(_animator->pre_draw_CB());
01257 } else if (_recorder->on()) {
01258
01259
01260
01261
01262
01263
01264 set_frame_time(stop_watch::sys_time());
01265 _recorder->pre_draw_CB();
01266 } else {
01267
01268 set_frame_time(stop_watch::sys_time());
01269 }
01270
01271
01272
01273
01274 _drawn.clear();
01275 if (_render_mode == NORMAL_MODE)
01276 {
01277 for (int i = 0; i < _active.num(); i++)
01278 if (!_active[i]->cull(this))
01279 _drawn += _active[i];
01280 }
01281 else if (_render_mode == OPAQUE_MODE)
01282 {
01283 for (int i = 0; i < _active.num(); i++)
01284 if ((!_active[i]->cull(this)) && (!_active[i]->needs_blend()))
01285 _drawn += _active[i];
01286 }
01287 else if (_render_mode == TRANSPARENT_MODE)
01288 {
01289 for (int i = 0; i < _active.num(); i++)
01290 if ((!_active[i]->cull(this)) && (_active[i]->needs_blend()))
01291 _drawn += _active[i];
01292 }
01293 else
01294 {
01295 assert(0);
01296 }
01297
01298
01299 if (_screen) _screen->config_cam(_cam);
01300
01301
01302
01303 if (!multithread) push(this);
01304
01305 if (_impl) _tris = _impl->paint();
01306
01307 if (!multithread) pop();
01308
01309 if (!dont_swap())
01310 swap();
01311 }
01312
01313 void
01314 VIEW::swap()
01315 {
01316
01317 assert(!(_recorder->on() && _animator->on()));
01318
01319 if ( _animator->on() )
01320 {
01321 _animator->post_draw_CB();
01322 }
01323 else if ( _recorder->on() )
01324 {
01325 _recorder->post_draw_CB();
01326 }
01327
01328 if (_impl)
01329 _impl->swap_buffers();
01330 }
01331
01332
01333
01334
01335 RAYhit
01336 VIEW::intersect(
01337 RAYhit &r,
01338 const GELFILTlist &filt
01339 ) const
01340 {
01341 #ifdef USE_PTHREAD
01342 assert(ThreadToView::get() == 0);
01343 #endif
01344 CVIEWptr this_view((VIEW *)this);
01345
01346 push(this_view);
01347
01348 GELFILTlist filter_list(filt);
01349
01350
01351 bool has_pickable = false;
01352 for (int f = 0; !has_pickable && f < filter_list.num(); f++)
01353 has_pickable =
01354 filter_list[f]->class_name() == GELFILTpickable::static_name();
01355
01356 GELFILTpickable pick(0);
01357 if (!has_pickable)
01358 filter_list += &pick;
01359
01360 for (int i = 0; i < _drawn.num(); i++ ) {
01361 if (filter_list.accept(_drawn[i]))
01362 _drawn[i]->intersect(r, Identity);
01363 }
01364
01365 pop();
01366 return r;
01367 }
01368
01369
01370
01371
01372
01373
01374 RAYhit
01375 VIEW::intersect_others(
01376 RAYhit &r,
01377 CGELlist &exclude,
01378 filt filter
01379 ) const
01380 {
01381 GELFILTlist filter_list;
01382
01383 GELFILTothers others(exclude);
01384 GELFILTpickable pick (1);
01385
01386
01387
01388
01389 GELFILTclass_desc_excl no_text("TEXT2D");
01390
01391 filter_list += &others;
01392
01393 if ((filter & H_TEXT) == 0)
01394 filter_list += &no_text;
01395 if (filter & H_UNPICKABLE)
01396 filter_list += &pick;
01397
01398 return intersect(r, filter_list);
01399 }
01400
01401
01402
01403
01404
01405 RAYhit
01406 VIEW::intersect(
01407 CXYpt &xy,
01408 filt filter
01409 ) const
01410 {
01411 RAYhit ray(xy);
01412 return intersect(ray,filter);
01413 }
01414
01415
01416
01417
01418
01419 RAYhit
01420 VIEW::intersect(
01421 RAYhit &r,
01422 filt filter
01423 ) const
01424 {
01425 GELFILTlist filter_list;
01426 GELFILTpickable pick(1);
01427
01428
01429
01430
01431 GELFILTclass_desc_excl no_text("TEXT2D");
01432
01433 if ((filter & H_TEXT) == 0)
01434 filter_list += &no_text;
01435 if (filter & H_UNPICKABLE)
01436 filter_list += &pick;
01437
01438 return intersect(r, filter_list);
01439 }
01440
01441
01442
01443
01444
01445 RAYhit
01446 VIEW::intersect(
01447 RAYhit &r,
01448 GELptr &g,
01449 filt filter
01450 ) const
01451 {
01452 intersect(r, filter);
01453 g = r.geom();
01454
01455 return r;
01456 }
01457
01458
01459
01460
01461
01462 RAYhit
01463 VIEW::intersect(
01464 RAYhit &r,
01465 Cstr_ptr &cn,
01466 filt filter
01467 ) const
01468 {
01469 for (int i = 0; i < _drawn.num(); i++)
01470 if (_drawn[i]->class_name() == cn &&
01471 (PICKABLE.get(_drawn[i]) || (filter & H_UNPICKABLE)))
01472 _drawn[i]->intersect(r, Identity);
01473
01474 return r;
01475 }
01476
01477
01478 RAYnear
01479 VIEW::nearest(
01480 RAYnear &r,
01481 filt filter
01482 ) const
01483 {
01484 for (int i = 0; i < _drawn.num(); i++)
01485 if (PICKABLE.get(_drawn[i]) || (filter & H_UNPICKABLE))
01486 _drawn[i]->nearest(r, Identity);
01487
01488 return r;
01489 }
01490
01491 RAYnear
01492 VIEW::nearest(
01493 RAYnear &r,
01494 Cstr_ptr &cn,
01495 filt filter
01496 ) const
01497 {
01498 for (int i = 0; i < _drawn.num(); i++)
01499 if (_drawn[i]->class_name() == cn &&
01500 (PICKABLE.get(_drawn[i]) || (filter & H_UNPICKABLE)))
01501 _drawn[i]->nearest(r, Identity);
01502
01503 return r;
01504 }
01505
01506
01507
01508
01509
01510 GELlist
01511 VIEW::inside(
01512 CXYpt_list &lasso
01513 ) const
01514 {
01515 GELlist objs;
01516 VIEWptr v((VIEW *)this);
01517 for (int i = 0; i < _drawn.num(); i++)
01518 if (!NO_COPY.get(_drawn[i]) && _drawn[i]->inside(lasso))
01519 objs += _drawn[i];
01520
01521 return objs;
01522 }
01523
01524 void
01525 VIEW::save_cam(CCAMptr c)
01526 {
01527
01528 if (_cam_hist.valid_index(_cam_hist_cur ))
01529 _cam_hist.truncate(_cam_hist_cur );
01530
01531 CAMptr cptr = new CAM("history");
01532 *cptr = (c ? *c : *_cam);
01533 _cam_hist += cptr;
01534 _cam_hist_cur++;
01535
01536 err_mesg_cond(Config::get_var_bool("DEBUG_CAM_HISTORY",false,true),
01537 ERR_LEV_ERROR, "VIEW::save_cam() - Saved camera. cam_hist = %d.", _cam_hist_cur);
01538 }
01539
01540 void
01541 VIEW::fwd_cam_hist()
01542 {
01543 if (_cam_hist_cur >= (_cam_hist.num()-1) ){
01544
01545 } else {
01546 new CamFocus(this, _cam_hist[++_cam_hist_cur]);
01547 }
01548 }
01549
01550 void
01551 VIEW::bk_cam_hist()
01552 {
01553 if(_cam_hist_cur<=0) return;
01554
01555
01556 if(_cam_hist_cur >= _cam_hist.num()){
01557 save_cam();
01558 _cam_hist_cur--;
01559 }
01560 new CamFocus(this, _cam_hist[--_cam_hist_cur]);
01561 }
01562
01563 void
01564 VIEW::copy_cam(CCAMptr &c)
01565 {
01566 assert(_cam != NULL);
01567
01568 if (c != NULL)
01569 *_cam = *c;
01570 else
01571 err_msg("VIEW::copy_cam: given CAMptr is null");
01572 }
01573
01574 void
01575 VIEW::use_cam(CCAMptr &c)
01576 {
01577 if (c == NULL) {
01578 err_msg("VIEW::use_cam: can't use null CAM");
01579 return;
01580 }
01581
01582 _cam = c;
01583 }
01584
01585 void
01586 VIEW::set_size(
01587 int w,
01588 int h,
01589 int x,
01590 int y
01591 )
01592 {
01593 _width = w;
01594 _height = h;
01595
01596 _cam->data()->changed();
01597
01598 if (_impl)
01599 _impl->set_size(w,h, x, y);
01600
01601
01602
01603
01604
01605
01606 _stamp++;
01607
01608 _pix_to_ndc_scale = (_width > _height ? 2.0/_height : 2.0/_width);
01609
01610 }
01611
01612
01613 Wtransf
01614 VIEW::wpt_proj(SCREENptr s, CAMdata::eye e) const
01615 {
01616 return _jitter * _lens * _cam->projection_xform(s,e);
01617 }
01618
01619 Wtransf
01620 VIEW::xypt_proj() const
01621 {
01622 return _jitter * _lens;
01623 }
01624
01625
01626
01627 Wtransf
01628 VIEW::ndc_proj() const
01629 {
01630 Wtransf ret;
01631
01632 if (_width > _height) ret(0,0) = double(_height)/_width;
01633 else ret(1,1) = double(_width)/_height;
01634
01635 return _jitter * _lens * ret;
01636 }
01637
01638
01639
01640 Wtransf
01641 VIEW::pix_proj() const
01642 {
01643 Wtransf ret;
01644
01645 ret(0,0) = 2.0/_width;
01646 ret(0,3) = -1;
01647 ret(1,1) = 2.0/_height;
01648 ret(1,3) = -1;
01649
01650 return _jitter * _lens * ret;
01651 }
01652
01653
01654
01655
01656 Wtransf
01657 VIEW::wpt_to_pix_proj(SCREENptr s, CAMdata::eye e) const
01658 {
01659 Wtransf world, ndc, pix;
01660
01661 world = _cam->projection_xform(s,e)*_cam->xform(s,e);
01662
01663 if (_width > _height) ndc(0,0) = double(_width)/_height;
01664 else ndc(1,1) = double(_height)/_width;
01665
01666 pix(0,0) = _width/2.0;
01667 pix(0,3) = _width/2.0;
01668 pix(1,1) = _height/2.0;
01669 pix(1,3) = _height/2.0;
01670
01671 Wtransf ret = pix*ndc*world;
01672
01673 return ret;
01674 }
01675
01676
01677
01678
01679 int
01680 VIEW::undisplay(
01681 CGELptr &o
01682 )
01683 {
01684 for (int i=0; i < _active.num(); i++)
01685 if (_active[i] == o) {
01686 _active.rem(o);
01687 _drawn .rem(o);
01688 return 1;
01689 }
01690 return 0;
01691 }
01692
01693
01694
01695
01696 int
01697 VIEW::display(
01698 CGELptr &o
01699 )
01700 {
01701 if (o != GELptr(0)) {
01702 for (int i=0; i < _active.num(); i++)
01703 if (_active[i] == o)
01704 return 0;
01705 _active.add(o);
01706 return 1;
01707 }
01708 return 0;
01709 }
01710
01711
01712
01713
01714 int
01715 VIEW::tick(void)
01716 {
01717
01718
01719 if (0) {
01720 cerr << "VIEW::tick: frame number " << stamp() << endl;
01721
01722 static uint last_stamp = 0;
01723 if (last_stamp == stamp()) {
01724 cerr << "VIEW::tick: repeating frame: " << stamp() << endl;
01725 }
01726 last_stamp = stamp();
01727 }
01728 for (int i = 0; i < _scheduled.num(); i++)
01729 if (_scheduled[i]->tick() == -1) {
01730 _scheduled.rem(_scheduled[i]);
01731 i--;
01732
01733
01734 }
01735 return 1;
01736 }
01737
01738 void
01739 VIEW::screen_grab(
01740 int scale_factor,
01741 Image &output
01742 )
01743 {
01744 bool alpha = Config::get_var_bool("GRAB_ALPHA",true,true);
01745
01746
01747
01748 const int n = max(1,scale_factor);
01749
01750
01751 assert(int(output.width()) >= n * _width && int(output.height()) >= n * _height);
01752
01753
01754 _line_scale = n;
01755
01756 _grabbing_screen = 1;
01757
01758
01759
01760
01761
01762
01763 int a = (alpha)?(4):(3);
01764 Image tile(_width,_height,a);
01765
01766 if (_impl)
01767 _impl->prepare_buf_read();
01768
01769
01770
01771
01772
01773
01774
01775
01776 _lens(0,0) = n;
01777 _lens(1,1) = n;
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788 for (int j=0; j<n; j++) {
01789
01790 _lens(1,3) = n - 2*j - 1;
01791 for (int i=0; i<n; i++) {
01792
01793 _lens(0,3) = n - 2*i - 1;
01794
01795 if (_impl)
01796 _impl->read_pixels(tile.data(),alpha);
01797
01798
01799 output.copy_tile(tile,i,j);
01800 }
01801 }
01802
01803
01804 _lens(0,0) = _lens(1,1) = 1;
01805 _lens(0,3) = _lens(1,3) = 0;
01806
01807
01808 _line_scale = 1.0;
01809
01810 _grabbing_screen = 0;
01811
01812 if (_impl)
01813 _impl->end_buf_read();
01814 }
01815
01816
01817 int
01818 VIEW::screen_grab(
01819 int scale_factor,
01820 Cstr_ptr& filename
01821 )
01822 {
01823 bool alpha = Config::get_var_bool("GRAB_ALPHA",true,true);
01824
01825
01826
01827
01828
01829
01830 const int n = max(1,scale_factor);
01831 int a = (alpha)?(4):(3);
01832 Image output(n*_width, n*_height,a);
01833
01834 screen_grab(scale_factor, output);
01835
01836
01837 if (!output.write_png(**filename)) {
01838
01839 return output.write_pnm(**filename);
01840 } else {
01841
01842 return 1;
01843 }
01844 }
01845
01846 void
01847 VIEW::viewall()
01848 {
01849
01850
01851
01852 BBOX bb;
01853 for (int i=0; i<_active.num(); i++)
01854 bb += _active[i]->bbox();
01855
01856 CAMdataptr camdata = cam()->data();
01857 double size = bb.dim().length();
01858 double dist = size * camdata->focal() / camdata->height();
01859 Wvec dirvec = -Wvec::Z();
01860
01861 Wpt from = bb.center() + dist * dirvec;
01862 new CamFocus(
01863 this,
01864 from,
01865 bb.center(),
01866 from + Wvec::Y(),
01867 bb.center(),
01868 camdata->width(),
01869 camdata->height()
01870 );
01871 }
01872
01873 void
01874 VIEW::set_color(CCOLOR &c)
01875 {
01876 if (c != _bkgnd_col) {
01877 _bkgnd_col = c;
01878 VIEWobs::notify_viewobs(this, COLOR_ALPHA_CHANGED);
01879 }
01880 }
01881
01882 void
01883 VIEW::set_alpha(double a)
01884 {
01885 if (_alpha != a) {
01886 _alpha = a;
01887 VIEWobs::notify_viewobs(this, COLOR_ALPHA_CHANGED);
01888 }
01889 }
01890
01891 void
01892 VIEW::set_render_mode(render_mode_t r)
01893 {
01894 if (_render_mode != r) {
01895 _render_mode = r;
01896 VIEWobs::notify_viewobs(this, UNKNOWN_CHANGED);
01897 }
01898 }
01899
01900 Wpt
01901 xy_to_w_1(CXYpt& x, CWpt& w)
01902 {
01903 return VIEW::peek_cam_const()->xy_to_w(x,w);
01904 }
01905
01906 Wpt
01907 xy_to_w_2(CXYpt& x, double d)
01908 {
01909 return VIEW::peek_cam_const()->xy_to_w(x,d);
01910 }
01911
01912 Wpt
01913 xy_to_w_3(CXYpt& x)
01914 {
01915 return VIEW::peek_cam_const()->xy_to_w(x);
01916 }
01917
01918 Wvec
01919 xy_to_wvec(CXYpt& x)
01920 {
01921 return VIEW::peek_cam_const()->film_dir(x);
01922 }
01923
01924 XYpt
01925 w_to_xy(CWpt& w)
01926 {
01927 return VIEW::peek_cam_const()->w_to_xy(w);
01928 }
01929
01930 void
01931 view_size (int& w, int& h)
01932 {
01933 VIEW::peek_size(w,h);
01934 }
01935
01936 double
01937 view_aspect()
01938 {
01939 return VIEW::peek_cam_const()->aspect();
01940 }
01941
01942 void
01943 view_pixels(double& z, NDCpt& p)
01944 {
01945 z=VIEW::peek_cam_const()->zoom();
01946 p=VIEW::peek_cam_const()->min();
01947 }
01948
01949 CWtransf&
01950 view_ndc_trans()
01951 {
01952 return VIEW::peek_cam()->ndc_projection();
01953 }
01954
01955 CWtransf&
01956 view_ndc_trans_inv()
01957 {
01958 return VIEW::peek_cam()->ndc_projection_inv();
01959 }
01960
01961
01962
01963
01964
01965 Wpt (*XYtoW_1 )(CXYpt &, CWpt &) = xy_to_w_1;
01966 Wpt (*XYtoW_2 )(CXYpt &, double) = xy_to_w_2;
01967 Wpt (*XYtoW_3 )(CXYpt &) = xy_to_w_3;
01968 Wvec (*XYtoWvec )(CXYpt &) = xy_to_wvec;
01969 XYpt (*WtoXY )(CWpt &) = w_to_xy;
01970 void (*VIEW_SIZE )(int &, int &) = view_size;
01971 double (*VIEW_ASPECT )() = view_aspect;
01972 void (*VIEW_PIXELS )(double &, NDCpt &) = view_pixels;
01973 CWtransf& (*VIEW_NDC_TRANS)() = view_ndc_trans;
01974 CWtransf& (*VIEW_NDC_TRANS_INV)() = view_ndc_trans_inv;
01975
01976 double at_length(CWpt& p, double length)
01977 {
01978 CWpt from = VIEW::peek_cam()->data()->from();
01979 Wvec at_v = VIEW::peek_cam()->data()->at_v();
01980 Wvec right= VIEW::peek_cam()->data()->right_v();
01981
01982 double dist = from.dist(p);
01983 CWpt new_p = from + (at_v * dist);
01984 CWpt new_q = new_p + (right * length);
01985 return PIXEL(new_p).dist(new_q);
01986 }
01987
01988