1 // generated by Fast Light User Interface Designer (fluid) version 1.0100
2 
3 #include "ViewEditor.h"
4 // Quat - A 3D fractal generation program
5 // Copyright (C) 1997-2000 Dirk Meyer
6 // (email: dirk.meyer@studserv.uni-stuttgart.de)
7 // mail:  Dirk Meyer
8 //        Marbacher Weg 29
9 //        D-71334 Waiblingen
10 //        Germany
11 //
12 // This program is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License
14 // as published by the Free Software Foundation; either version 2
15 // of the License, or (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28 #include "ChildWindow.h"
29 #include "ViewSelector.h"
30 #include <FL/math.h>
31 #include <cassert>
32 
cb_vre_i(Fl_Value_Input * o,void *)33 inline void ViewEditor::cb_vre_i(Fl_Value_Input* o, void*) {
34   view.s[0] = o->value();
35 for (int i=0; i<3; i++)
36   vs[i]->viewpointre(o->value());
37 if (radio2->value()) { ocular_dist->value(newdist()); ocular_dist->do_callback(); }
38 if (radio1->value()) ocular_angle->value(newangle());
39 checkValidity();
40 }
cb_vre(Fl_Value_Input * o,void * v)41 void ViewEditor::cb_vre(Fl_Value_Input* o, void* v) {
42   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_vre_i(o,v);
43 }
44 
cb_vi_i(Fl_Value_Input * o,void *)45 inline void ViewEditor::cb_vi_i(Fl_Value_Input* o, void*) {
46   view.s[1] = o->value();
47 for (int i=0; i<3; i++)
48   vs[i]->viewpointi(o->value());
49 if (radio2->value()) { ocular_dist->value(newdist()); ocular_dist->do_callback(); }
50 if (radio1->value()) ocular_angle->value(newangle());
51 checkValidity();
52 }
cb_vi(Fl_Value_Input * o,void * v)53 void ViewEditor::cb_vi(Fl_Value_Input* o, void* v) {
54   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_vi_i(o,v);
55 }
56 
cb_vj_i(Fl_Value_Input * o,void *)57 inline void ViewEditor::cb_vj_i(Fl_Value_Input* o, void*) {
58   view.s[2] = o->value();
59 for (int i=0; i<3; i++)
60   vs[i]->viewpointj(o->value());
61 if (radio2->value()) { ocular_dist->value(newdist()); ocular_dist->do_callback(); }
62 if (radio1->value()) ocular_angle->value(newangle());
63 checkValidity();
64 }
cb_vj(Fl_Value_Input * o,void * v)65 void ViewEditor::cb_vj(Fl_Value_Input* o, void* v) {
66   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_vj_i(o,v);
67 }
68 
cb_upre_i(Fl_Value_Input * o,void *)69 inline void ViewEditor::cb_upre_i(Fl_Value_Input* o, void*) {
70   view.up[0] = o->value();
71 for (int i=0; i<3; i++) vs[i]->upre(o->value());
72 checkValidity();
73 }
cb_upre(Fl_Value_Input * o,void * v)74 void ViewEditor::cb_upre(Fl_Value_Input* o, void* v) {
75   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_upre_i(o,v);
76 }
77 
cb_upi_i(Fl_Value_Input * o,void *)78 inline void ViewEditor::cb_upi_i(Fl_Value_Input* o, void*) {
79   view.up[1] = o->value();
80 for (int i=0; i<3; i++) vs[i]->upi(o->value());
81 checkValidity();
82 }
cb_upi(Fl_Value_Input * o,void * v)83 void ViewEditor::cb_upi(Fl_Value_Input* o, void* v) {
84   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_upi_i(o,v);
85 }
86 
cb_upj_i(Fl_Value_Input * o,void *)87 inline void ViewEditor::cb_upj_i(Fl_Value_Input* o, void*) {
88   view.up[2] = o->value();
89 for (int i=0; i<3; i++) vs[i]->upj(o->value());
90 checkValidity();
91 }
cb_upj(Fl_Value_Input * o,void * v)92 void ViewEditor::cb_upj(Fl_Value_Input* o, void* v) {
93   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_upj_i(o,v);
94 }
95 
cb_lxr_i(Fl_Value_Input * o,void *)96 inline void ViewEditor::cb_lxr_i(Fl_Value_Input* o, void*) {
97   view.LXR = o->value();
98 for (int i=0; i<3; i++) vs[i]->LXR(o->value());
99 checkValidity();
100 }
cb_lxr(Fl_Value_Input * o,void * v)101 void ViewEditor::cb_lxr(Fl_Value_Input* o, void* v) {
102   ((ViewEditor*)(o->parent()->user_data()))->cb_lxr_i(o,v);
103 }
104 
cb_ocular_dist_i(Fl_Value_Input * o,void *)105 inline void ViewEditor::cb_ocular_dist_i(Fl_Value_Input* o, void*) {
106   view.interocular = o->value();
107 ocular_angle->value(newangle());
108 checkValidity();
109 }
cb_ocular_dist(Fl_Value_Input * o,void * v)110 void ViewEditor::cb_ocular_dist(Fl_Value_Input* o, void* v) {
111   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_ocular_dist_i(o,v);
112 }
113 
cb_ocular_angle_i(Fl_Value_Input *,void *)114 inline void ViewEditor::cb_ocular_angle_i(Fl_Value_Input*, void*) {
115   view.interocular = newdist();
116 ocular_dist->value(view.interocular);
117 checkValidity();
118 }
cb_ocular_angle(Fl_Value_Input * o,void * v)119 void ViewEditor::cb_ocular_angle(Fl_Value_Input* o, void* v) {
120   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_ocular_angle_i(o,v);
121 }
122 
cb_radio1_i(Fl_Round_Button *,void *)123 inline void ViewEditor::cb_radio1_i(Fl_Round_Button*, void*) {
124   ocular_angle->deactivate();
125 ocular_dist->activate();
126 }
cb_radio1(Fl_Round_Button * o,void * v)127 void ViewEditor::cb_radio1(Fl_Round_Button* o, void* v) {
128   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_radio1_i(o,v);
129 }
130 
cb_radio2_i(Fl_Round_Button *,void *)131 inline void ViewEditor::cb_radio2_i(Fl_Round_Button*, void*) {
132   ocular_dist->deactivate();
133 ocular_angle->activate();
134 }
cb_radio2(Fl_Round_Button * o,void * v)135 void ViewEditor::cb_radio2(Fl_Round_Button* o, void* v) {
136   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_radio2_i(o,v);
137 }
138 
cb_lightx_i(Fl_Value_Input * o,void *)139 inline void ViewEditor::cb_lightx_i(Fl_Value_Input* o, void*) {
140   view.light[0] = o->value();
141 }
cb_lightx(Fl_Value_Input * o,void * v)142 void ViewEditor::cb_lightx(Fl_Value_Input* o, void* v) {
143   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_lightx_i(o,v);
144 }
145 
cb_lighty_i(Fl_Value_Input * o,void *)146 inline void ViewEditor::cb_lighty_i(Fl_Value_Input* o, void*) {
147   view.light[1] = o->value();
148 }
cb_lighty(Fl_Value_Input * o,void * v)149 void ViewEditor::cb_lighty(Fl_Value_Input* o, void* v) {
150   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_lighty_i(o,v);
151 }
152 
cb_lightz_i(Fl_Value_Input * o,void *)153 inline void ViewEditor::cb_lightz_i(Fl_Value_Input* o, void*) {
154   view.light[2] = o->value();
155 }
cb_lightz(Fl_Value_Input * o,void * v)156 void ViewEditor::cb_lightz(Fl_Value_Input* o, void* v) {
157   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_lightz_i(o,v);
158 }
159 
cb_movex_i(Fl_Value_Input * o,void *)160 inline void ViewEditor::cb_movex_i(Fl_Value_Input* o, void*) {
161   view.Mov[0] = o->value();
162 for (int i=0; i<3; i++) vs[i]->movex(o->value());
163 }
cb_movex(Fl_Value_Input * o,void * v)164 void ViewEditor::cb_movex(Fl_Value_Input* o, void* v) {
165   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_movex_i(o,v);
166 }
167 
cb_movey_i(Fl_Value_Input * o,void *)168 inline void ViewEditor::cb_movey_i(Fl_Value_Input* o, void*) {
169   view.Mov[1] = o->value();
170 for (int i=0; i<3; i++) vs[i]->movey(o->value());
171 }
cb_movey(Fl_Value_Input * o,void * v)172 void ViewEditor::cb_movey(Fl_Value_Input* o, void* v) {
173   ((ViewEditor*)(o->parent()->parent()->user_data()))->cb_movey_i(o,v);
174 }
175 
ViewEditor(int X,int Y,int W,int H,const char * label)176 ViewEditor::ViewEditor(int X, int Y, int W, int H, const char *label) : Fl_Group(X,Y,W,H,label) {
177   ChildWindow* w;
178   { ChildWindow* o = win = new ChildWindow(416, 216);
179     w = o;
180     o->user_data((void*)(this));
181     { Fl_Group* o = new Fl_Group(5, 5, 260, 200, "QSpace coordinates (1, i, j)");
182       o->tooltip("All parameters in this box are coordinates in Quaternion space.");
183       o->box(FL_ENGRAVED_BOX);
184       o->labelsize(12);
185       o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
186       o->end();
187     }
188     { Fl_Group* o = group_v = new Fl_Group(15, 30, 110, 75, "v");
189       o->tooltip("The view point represents the center point of the screen in QSpace.\nYou can \
190 also use the three View Selectors to set the View Point with the mouse.");
191       o->labeltype(FL_NO_LABEL);
192       { Fl_Value_Input* o = vre = new Fl_Value_Input(15, 45, 110, 20, "View Point");
193         o->tooltip("Real part of View Point.");
194         o->labelsize(12);
195         o->minimum(-1e+20);
196         o->maximum(1e+20);
197         o->textsize(12);
198         o->callback((Fl_Callback*)cb_vre);
199         o->align(FL_ALIGN_TOP_LEFT);
200       }
201       { Fl_Value_Input* o = vi = new Fl_Value_Input(15, 65, 110, 20, "value:");
202         o->tooltip("1st imaginary (i) part of View Point.");
203         o->labeltype(FL_NO_LABEL);
204         o->labelsize(12);
205         o->minimum(-1e+20);
206         o->maximum(1e+20);
207         o->textsize(12);
208         o->callback((Fl_Callback*)cb_vi);
209       }
210       { Fl_Value_Input* o = vj = new Fl_Value_Input(15, 85, 110, 20, "value:");
211         o->tooltip("2nd imaginary (j) part of View Point.");
212         o->labeltype(FL_NO_LABEL);
213         o->labelsize(12);
214         o->minimum(-1e+20);
215         o->maximum(1e+20);
216         o->textsize(12);
217         o->callback((Fl_Callback*)cb_vj);
218       }
219       o->end();
220     }
221     { Fl_Group* o = group_up = new Fl_Group(15, 120, 110, 75, "up");
222       o->tooltip("Needed for orientation of the screen in QSpace.\nDefines the vertical directi\
223 on of screen.");
224       o->labeltype(FL_NO_LABEL);
225       { Fl_Value_Input* o = upre = new Fl_Value_Input(15, 135, 110, 20, "Up (Orientation)");
226         o->tooltip("Real part of Up.");
227         o->labelsize(12);
228         o->minimum(-1e+20);
229         o->maximum(1e+20);
230         o->textsize(12);
231         o->callback((Fl_Callback*)cb_upre);
232         o->align(FL_ALIGN_TOP_LEFT);
233       }
234       { Fl_Value_Input* o = upi = new Fl_Value_Input(15, 155, 110, 20, "value:");
235         o->tooltip("1st imaginary (i) part of Up.");
236         o->labeltype(FL_NO_LABEL);
237         o->labelsize(12);
238         o->minimum(-1e+20);
239         o->maximum(1e+20);
240         o->textsize(12);
241         o->callback((Fl_Callback*)cb_upi);
242       }
243       { Fl_Value_Input* o = upj = new Fl_Value_Input(15, 175, 110, 20, "value:");
244         o->tooltip("2nd imaginary (j) part of Up.");
245         o->labeltype(FL_NO_LABEL);
246         o->labelsize(12);
247         o->minimum(-1e+20);
248         o->maximum(1e+20);
249         o->textsize(12);
250         o->callback((Fl_Callback*)cb_upj);
251       }
252       o->end();
253     }
254     { Fl_Value_Input* o = lxr = new Fl_Value_Input(145, 65, 110, 20, "Length of View\nPlane\'s X-Axis");
255       o->tooltip("Use this to scale the screen (image).");
256       o->labelsize(12);
257       o->minimum(-1e+20);
258       o->maximum(1e+20);
259       o->textsize(12);
260       o->callback((Fl_Callback*)cb_lxr);
261       o->align(FL_ALIGN_TOP_LEFT);
262     }
263     { Fl_Group* o = group_interocular = new Fl_Group(145, 115, 110, 85, "Interocular");
264       o->labelsize(12);
265       o->align(FL_ALIGN_TOP_LEFT);
266       { Fl_Value_Input* o = ocular_dist = new Fl_Value_Input(165, 135, 90, 20, "Distance");
267         o->tooltip("Distance (in QSpace) between the two eyes. If nonzero, you\'ll get a stereo i\
268 mage.");
269         o->labelsize(12);
270         o->maximum(1e+20);
271         o->textsize(12);
272         o->callback((Fl_Callback*)cb_ocular_dist);
273         o->align(FL_ALIGN_TOP_LEFT);
274       }
275       { Fl_Value_Input* o = ocular_angle = new Fl_Value_Input(165, 175, 90, 20, "Angle (\260)");
276         o->tooltip("Angle between the two eyes. If nonzero, you\'ll get a stereo image.");
277         o->labelsize(12);
278         o->maximum(360);
279         o->textsize(12);
280         o->callback((Fl_Callback*)cb_ocular_angle);
281         o->align(FL_ALIGN_TOP_LEFT);
282         o->deactivate();
283       }
284       { Fl_Round_Button* o = radio1 = new Fl_Round_Button(145, 130, 20, 30, "button");
285         o->tooltip("If selected: Interocular distance constant while moving the View Point.");
286         o->type(102);
287         o->down_box(FL_DOWN_BOX);
288         o->value(1);
289         o->selection_color(2);
290         o->labeltype(FL_NO_LABEL);
291         o->labelsize(12);
292         o->callback((Fl_Callback*)cb_radio1);
293       }
294       { Fl_Round_Button* o = radio2 = new Fl_Round_Button(145, 170, 20, 30, "button");
295         o->tooltip("If selected: Angle is constant while moving the View Point.");
296         o->type(102);
297         o->down_box(FL_DOWN_BOX);
298         o->selection_color(2);
299         o->labeltype(FL_NO_LABEL);
300         o->labelsize(12);
301         o->callback((Fl_Callback*)cb_radio2);
302       }
303       o->end();
304     }
305     { Fl_Group* o = new Fl_Group(275, 5, 130, 200, "Viewplane coord.");
306       o->tooltip("All coordinates in this box are measured relative to the view plane.\nX=horiz\
307 ontal, Y=vertical, Z=perpendicular to screen.");
308       o->box(FL_ENGRAVED_BOX);
309       o->labelsize(12);
310       o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
311       o->end();
312     }
313     { Fl_Group* o = new Fl_Group(285, 30, 110, 75, "light");
314       o->tooltip("Measured from the View Point.");
315       o->labeltype(FL_NO_LABEL);
316       { Fl_Value_Input* o = lightx = new Fl_Value_Input(285, 45, 110, 20, "Light Source");
317         o->tooltip("X coordinate of Light Source.");
318         o->labelsize(12);
319         o->minimum(-1e+20);
320         o->maximum(1e+20);
321         o->textsize(12);
322         o->callback((Fl_Callback*)cb_lightx);
323         o->align(FL_ALIGN_TOP_LEFT);
324       }
325       { Fl_Value_Input* o = lighty = new Fl_Value_Input(285, 65, 110, 20, "value:");
326         o->tooltip("Y coordinate of Light Source.");
327         o->labeltype(FL_NO_LABEL);
328         o->labelsize(12);
329         o->minimum(-1e+20);
330         o->maximum(1e+20);
331         o->textsize(12);
332         o->callback((Fl_Callback*)cb_lighty);
333       }
334       { Fl_Value_Input* o = lightz = new Fl_Value_Input(285, 85, 110, 20, "value:");
335         o->tooltip("Z coordinate of Light Source.");
336         o->labeltype(FL_NO_LABEL);
337         o->labelsize(12);
338         o->minimum(-1e+20);
339         o->maximum(1e+20);
340         o->textsize(12);
341         o->callback((Fl_Callback*)cb_lightz);
342       }
343       o->end();
344     }
345     { Fl_Group* o = group_move = new Fl_Group(285, 120, 110, 55, "move");
346       o->tooltip("Move the view plane parallel to itself.");
347       o->labeltype(FL_NO_LABEL);
348       { Fl_Value_Input* o = movex = new Fl_Value_Input(285, 135, 110, 20, "Move");
349         o->tooltip("Movement in X direction.");
350         o->labelsize(12);
351         o->minimum(-1e+20);
352         o->maximum(1e+20);
353         o->textsize(12);
354         o->callback((Fl_Callback*)cb_movex);
355         o->align(FL_ALIGN_TOP_LEFT);
356       }
357       { Fl_Value_Input* o = movey = new Fl_Value_Input(285, 155, 110, 20, "value:");
358         o->tooltip("Movement in Y direction.");
359         o->labeltype(FL_NO_LABEL);
360         o->labelsize(12);
361         o->minimum(-1e+20);
362         o->maximum(1e+20);
363         o->textsize(12);
364         o->callback((Fl_Callback*)cb_movey);
365       }
366       o->end();
367     }
368     o->clear_border();
369     o->end();
370   }
371   memset(&view, 0, sizeof(view));
372 end(); // VERY IMPORTANT!
373 win->position(X+2, Y+2);
374 // DON'T delete win in destructor (or elsewhere)
375 // it's automatically deleted by Fl_Group
376 }
377 
setSelectors(ViewSelector * vsa,ViewSelector * vsb,ViewSelector * vsf,Fl_Light_Button * ster)378 void ViewEditor::setSelectors(ViewSelector *vsa, ViewSelector *vsb, ViewSelector *vsf, Fl_Light_Button *ster) {
379   vs[0] = vsa; vs[1] = vsb; vs[2] = vsf;
380 stereo = ster;
381 }
382 
set(const view_cpp & v)383 void ViewEditor::set(const view_cpp& v) {
384   for (int i=0; i<3; i++) assert(vs[i] != 0);
385 assert(stereo != 0);
386 view = v;
387 vre->value(v.s[0]); vi->value(v.s[1]); vj->value(v.s[2]);
388 upre->value(v.up[0]); upi->value(v.up[1]); upj->value(v.up[2]);
389 lxr->value(v.LXR);
390 ocular_dist->value(v.interocular);
391 lightx->value(v.light[0]); lighty->value(v.light[1]); lightz->value(v.light[2]);
392 movex->value(v.Mov[0]);
393 movey->value(v.Mov[1]);
394 
395 // Set Angle, set ViewSelectors and checkValidity:
396 ocular_dist->do_callback();
397 vre->do_callback(); vi->do_callback(); vj->do_callback();
398 upre->do_callback(); upi->do_callback(); upj->do_callback();
399 lxr->do_callback(); movex->do_callback(); movey->do_callback();
400 
401 return;
402 }
403 
get(view_cpp & v)404 void ViewEditor::get(view_cpp& v) {
405   // Don't do v=view, because there are other members
406 // which aren't in the ViewEditor
407 
408 v.s[0] = view.s[0]; v.s[1] = view.s[1]; v.s[2] = view.s[2];
409 v.up[0] = view.up[0]; v.up[1] = view.up[1];  v.up[2] = view.up[2];
410 v.LXR = view.LXR;
411 v.interocular = view.interocular;
412 v.light[0] = view.light[0];
413 v.light[1] = view.light[1];
414 v.light[2] = view.light[2];
415 v.Mov[0] = view.Mov[0];
416 v.Mov[1] = view.Mov[1];
417 
418 return;
419 }
420 
parallel(double a[],double b[])421 bool ViewEditor::parallel(double a[], double b[]) {
422   double c[3] = {0.0, 0.0, 0.0};
423 c[0] = a[1]*b[2] - a[2]*b[1];
424 c[1] = a[2]*b[0] - a[0]*b[2];
425 c[2] = a[0]*b[1] - a[1]*b[0];
426 //double ab = c[0]*c[0] + c[1]*c[1] + c[2]*c[2];
427 return (vec_abs(c)==0.0);
428 }
429 
vec_abs(double a[])430 double ViewEditor::vec_abs(double a[]) {
431   return sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
432 }
433 
newangle()434 double ViewEditor::newangle() {
435   double a = vec_abs(view.s);
436 if (a==0.0 && view.interocular != 0.0) return 180.0;
437 else if (a==0.0) return(ocular_angle->value());
438 else return atan(view.interocular/(2.0*a))*360.0/M_PI;
439 }
440 
newdist()441 double ViewEditor::newdist() {
442   return 2.0*vec_abs(view.s)*tan(M_PI*ocular_angle->value()/360.0);
443 }
444 
checkValidity()445 void ViewEditor::checkValidity() {
446   const Fl_Color okc = FL_WHITE;
447 const Fl_Color ndefc = FL_RED;
448 Fl_Color vre_c = okc, vi_c = okc, vj_c = okc,
449 	upre_c = okc, upi_c = okc, upj_c = okc,
450 	lxr_c = okc, od_c = okc, oa_c = okc;
451 
452 if (vec_abs(view.s) == 0.0) {
453 	vre_c = ndefc; vi_c = ndefc; vj_c = ndefc;
454 }
455 else if (parallel(view.s, view.up)) {
456 	upre_c = ndefc; upi_c = ndefc; upj_c = ndefc;
457 }
458 
459 if (view.LXR <= 0.0) lxr_c = ndefc;
460 
461 if (view.interocular < 0.0) {
462 	od_c = ndefc; oa_c = ndefc;
463 }
464 
465 if (vre_c != vre->color()) { vre->color(vre_c); vre->redraw(); }
466 if (vi_c != vi->color()) { vi->color(vi_c); vi->redraw(); }
467 if (vj_c != vj->color()) { vj->color(vj_c); vj->redraw(); }
468 
469 if (upre_c != upre->color()) { upre->color(upre_c); upre->redraw(); }
470 if (upi_c != upi->color()) { upi->color(upi_c); upi->redraw(); }
471 if (upj_c != upj->color()) { upj->color(upj_c); upj->redraw(); }
472 
473 if (lxr_c != lxr->color()) { lxr->color(lxr_c); lxr->redraw(); }
474 
475 if (od_c != ocular_dist->color()) { ocular_dist->color(od_c); ocular_dist->redraw(); }
476 if (oa_c != ocular_angle->color()) { ocular_angle->color(oa_c); ocular_angle->redraw(); }
477 
478 if (view.interocular == 0.0 && stereo->active()) stereo->deactivate();
479 if (view.interocular != 0.0 && !stereo->active()) stereo->activate();
480 
481 return;
482 }
483