57 const char * TGLSAViewer::fgHelpText1 =
"\
58 DIRECT SCENE INTERACTIONS\n\n\
60 \tw --- wireframe mode\n\
61 \te --- switch between dark / light color-set\n\
62 \tr --- filled polygons mode\n\
63 \tt --- outline mode\n\
66 \ta --- switch on/off arc-ball camera rotation control\n\
67 \tArrow Keys --- PAN (TRUCK) across scene\n\
68 \tHome --- reset current camera\n\
69 \tCtrl-Home --- switch external/automatic camera center\n\
71 LEFT mouse button -- ROTATE (ORBIT) the scene by holding the mouse button and moving\n\
72 the mouse (perspective camera, needs to be enabled in menu for orthographic cameras).\n\
73 By default, the scene will be rotated about its center. To select arbitrary center\n\
74 bring up the viewer-editor (e.g., shift-click into empty background) and use\n\
75 'Camera center' controls in the 'Guides' tab.\n\
77 MIDDLE mouse button or arrow keys -- PAN (TRUCK) the camera.\n\
79 RIGHT mouse button action depends on camera type:\n\
80 orthographic -- zoom,\n\
81 perspective -- move camera forwards / backwards\n\
83 By pressing Ctrl and Shift keys the mouse precision can be changed:\n\
84 Shift -- 10 times less precise\n\
85 Ctrl -- 10 times more precise\n\
86 Ctrl Shift -- 100 times more precise\n\
88 Mouse wheel action depends on camera type:\n\
89 orthographic -- zoom,\n\
90 perspective -- change field-of-view (focal length)\n\
92 To invert direction of mouse and key actions from scene-centric\n\
93 to viewer-centric, set in your .rootrc file:\n\
94 OpenGL.EventHandler.ViewerCentricControls: 1\n\
96 Double click will show GUI editor of the viewer (if assigned).\n\
98 RESET the camera via the button in viewer-editor or Home key.\n\
100 SELECT a shape with Shift+Left mouse button click.\n\
102 SELECT the viewer with Shift+Left mouse button click on a free space.\n\
104 MOVE a selected shape using Shift+Mid mouse drag.\n\
106 Invoke the CONTEXT menu with Shift+Right mouse click.\n\n"
107 "Secondary selection and direct render object interaction is initiated\n\
108 by Alt+Left mouse click (Mod1, actually). Only few classes support this option.\n\
109 When 'Alt' is taken by window manager, try Alt-Ctrl-Left.\n\
113 The \"Camera\" menu is used to select the different projections from \n\
114 the 3D world onto the 2D viewport. There are three perspective cameras:\n\
116 \tPerspective (Floor XOZ)\n\
117 \tPerspective (Floor YOZ)\n\
118 \tPerspective (Floor XOY)\n\
120 In each case the floor plane (defined by two axes) is kept level.\n\
122 There are also four orthographic cameras:\n\
124 \tOrthographic (XOY)\n\
125 \tOrthographic (XOZ)\n\
126 \tOrthographic (ZOY)\n\
127 \tOrthographic (ZOX)\n\
129 In each case the first axis is placed horizontal, the second vertical e.g.\n\
130 XOY means X horizontal, Y vertical.\n\n";
132 const char * TGLSAViewer::fgHelpText2 =
"\
133 SHAPES COLOR AND MATERIAL\n\
135 The selected shape's color can be modified in the Shapes-Color tabs.\n\
136 Shape's color is specified by the percentage of red, green, blue light\n\
137 it reflects. A surface can reflect DIFFUSE, AMBIENT and SPECULAR light.\n\
138 A surface can also emit light. The EMISSIVE parameter allows to define it.\n\
139 The surface SHININESS can also be modified.\n\
143 The selected shape's location and geometry can be modified in the Shapes-Geom\n\
144 tabs by entering desired values in respective number entry controls.\n\
148 In the Scene-Clipping tabs select a 'Clip Type': None, Plane, Box\n\
150 For 'Plane' and 'Box' the lower pane shows the relevant parameters:\n\
152 \tPlane: Equation coefficients of form aX + bY + cZ + d = 0\n\
153 \tBox: Center X/Y/Z and Length X/Y/Z\n\n"
154 "For Box checking the 'Show / Edit' checkbox shows the clip box (in light blue)\n\
155 in viewer. It also attaches the current manipulator to the box - enabling\n\
156 direct editing in viewer.\n\
160 A widget attached to the selected object - allowing direct manipulation\n\
161 of the object with respect to its local axes.\n\
163 There are three modes, toggled with keys while manipulator is active, that is,\n\
164 mouse pointer is above it (switches color to yellow):\n\
165 \tMode\t\tWidget Component Style\t\tKey\n\
166 \t----\t\t----------------------\t\t---\n\
167 \tTranslation\tLocal axes with arrows\t\tv\n\
168 \tScale\t\tLocal axes with boxes\t\tx\n\
169 \tRotate\t\tLocal axes rings\t\tc\n\
171 Each widget has three axis components - red (X), green (Y) and blue (Z).\n\
172 The component turns yellow, indicating an active state, when the mouse is moved\n\
173 over it. Left click and drag on the active component to adjust the objects\n\
174 translation, scale or rotation.\n\
175 Some objects do not support all manipulations (e.g. clipping planes cannot be \n\
176 scaled). If a manipulation is not permitted the component it drawn in grey and \n\
177 cannot be selected/dragged.\n";
185 ClassImp(TGLSAViewer);
187 Long_t TGLSAViewer::fgMenuHidingTimeout = 400;
189 const Int_t TGLSAViewer::fgInitX = 0;
190 const Int_t TGLSAViewer::fgInitY = 0;
191 const Int_t TGLSAViewer::fgInitW = 780;
192 const Int_t TGLSAViewer::fgInitH = 670;
197 const char *gGLSaveAsTypes[] = {
"Encapsulated PostScript",
"*.eps",
200 "Animated GIF",
"*.gif+",
208 TGLSAViewer::TGLSAViewer(TVirtualPad *pad, TGLFormat* format) :
209 TGLViewer(pad, fgInitX, fgInitY, fgInitW, fgInitH),
216 fLeftVerticalFrame(0),
217 fRightVerticalFrame(0),
223 fHideMenuBar(kFALSE),
225 fMenuHidingShowMenu(kTRUE),
226 fDeleteMenuBar(kFALSE)
228 fFrame =
new TGLSAFrame(*
this);
233 fFrame->SetWindowName(
"ROOT's GL viewer");
234 fFrame->SetClassHints(
"GLViewer",
"GLViewer");
235 fFrame->SetMWMHints(kMWMDecorAll, kMWMFuncAll, kMWMInputModeless);
236 fFrame->MapSubwindows();
237 fFrame->HideFrame(fMenuBut);
239 fFrame->Resize(fFrame->GetDefaultSize());
240 fFrame->MoveResize(fgInitX, fgInitY, fgInitW, fgInitH);
241 fFrame->SetWMPosition(fgInitX, fgInitY);
245 TObject* fe = fLeftVerticalFrame->GetList()->First();
246 fLeftVerticalFrame->GetList()->Remove(fe);
247 fFrame->SetCleanup(kDeepCleanup);
248 fLeftVerticalFrame->GetList()->AddFirst(fe);
261 TGLSAViewer::TGLSAViewer(
const TGWindow *parent, TVirtualPad *pad, TGedEditor *ged,
263 TGLViewer(pad, fgInitX, fgInitY, fgInitW, fgInitH),
269 fLeftVerticalFrame(0),
270 fRightVerticalFrame(0),
274 fHideMenuBar(kFALSE),
276 fMenuHidingShowMenu(kTRUE),
277 fDeleteMenuBar(kFALSE)
280 fFrame =
new TGLSAFrame(parent, *
this);
285 fFrame->MapSubwindows();
286 fFrame->HideFrame(fMenuBut);
287 fFrame->Resize(fFrame->GetDefaultSize());
288 fFrame->Resize(fgInitW, fgInitH);
292 if (fLeftVerticalFrame)
294 TObject* fe = fLeftVerticalFrame->GetList()->First();
295 fLeftVerticalFrame->GetList()->Remove(fe);
296 fFrame->SetCleanup(kDeepCleanup);
297 fLeftVerticalFrame->GetList()->AddFirst(fe);
306 TGLSAViewer::~TGLSAViewer()
308 fGedEditor->DisconnectFromCanvas();
310 DisableMenuBarHiding();
314 delete fFileSaveMenu;
327 TGCompositeFrame* TGLSAViewer::GetFrame()
const
336 void TGLSAViewer::CreateGLWidget()
339 Error(
"CreateGLWidget",
"Widget already exists.");
344 fFormat =
new TGLFormat;
346 fGLWidget = TGLWidget::Create(*fFormat, fRightVerticalFrame, kTRUE, kTRUE, 0, 10, 10);
347 fGLWidget->SetEventHandler(fEventHandler);
349 fRightVerticalFrame->AddFrame(fGLWidget,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
352 fGLWidget->MapWindow();
359 void TGLSAViewer::DestroyGLWidget()
361 if (fGLWidget == 0) {
362 Error(
"DestroyGLWidget",
"Widget does not exist.");
366 fGLWidget->UnmapWindow();
367 fGLWidget->SetEventHandler(0);
369 fRightVerticalFrame->RemoveFrame(fGLWidget);
370 fGLWidget->DeleteWindow();
377 void TGLSAViewer::CreateMenus()
379 fFileMenu =
new TGPopupMenu(fFrame->GetClient()->GetDefaultRoot());
380 fFileMenu->AddEntry(
"&Hide Menus", kGLHideMenus);
381 fFileMenu->AddEntry(
"&Edit Object", kGLEditObject);
382 fFileMenu->AddSeparator();
383 fFileMenu->AddEntry(
"&Close Viewer", kGLCloseViewer);
384 fFileMenu->AddSeparator();
385 fFileSaveMenu =
new TGPopupMenu(fFrame->GetClient()->GetDefaultRoot());
386 fFileSaveMenu->AddEntry(
"viewer.&eps", kGLSaveEPS);
387 fFileSaveMenu->AddEntry(
"viewer.&pdf", kGLSavePDF);
388 fFileSaveMenu->AddEntry(
"viewer.&gif", kGLSaveGIF);
389 fFileSaveMenu->AddEntry(
"viewer.g&if+", kGLSaveAnimGIF);
390 fFileSaveMenu->AddEntry(
"viewer.&jpg", kGLSaveJPG);
391 fFileSaveMenu->AddEntry(
"viewer.p&ng", kGLSavePNG);
392 fFileMenu->AddPopup(
"&Save", fFileSaveMenu);
393 fFileMenu->AddEntry(
"Save &As...", kGLSaveAS);
394 fFileMenu->AddSeparator();
395 fFileMenu->AddEntry(
"&Quit ROOT", kGLQuitROOT);
396 fFileMenu->Associate(fFrame);
398 fCameraMenu =
new TGPopupMenu(fFrame->GetClient()->GetDefaultRoot());
399 fCameraMenu->AddEntry(
"Perspective (Floor XOZ)", kGLPerspXOZ);
400 fCameraMenu->AddEntry(
"Perspective (Floor YOZ)", kGLPerspYOZ);
401 fCameraMenu->AddEntry(
"Perspective (Floor XOY)", kGLPerspXOY);
402 fCameraMenu->AddEntry(
"Orthographic (XOY)", kGLXOY);
403 fCameraMenu->AddEntry(
"Orthographic (XOZ)", kGLXOZ);
404 fCameraMenu->AddEntry(
"Orthographic (ZOY)", kGLZOY);
405 fCameraMenu->AddEntry(
"Orthographic (ZOX)", kGLZOX);
406 fCameraMenu->AddEntry(
"Orthographic (XnOY)", kGLXnOY);
407 fCameraMenu->AddEntry(
"Orthographic (XnOZ)", kGLXnOZ);
408 fCameraMenu->AddEntry(
"Orthographic (ZnOY)", kGLZnOY);
409 fCameraMenu->AddEntry(
"Orthographic (ZnOX)", kGLZnOX);
410 fCameraMenu->AddSeparator();
411 fCameraMenu->AddEntry(
"Ortho allow rotate", kGLOrthoRotate);
412 fCameraMenu->AddEntry(
"Ortho allow dolly", kGLOrthoDolly);
413 fCameraMenu->Associate(fFrame);
415 fHelpMenu =
new TGPopupMenu(fFrame->GetClient()->GetDefaultRoot());
416 fHelpMenu->AddEntry(
"Help on GL Viewer...", kGLHelpViewer);
417 fHelpMenu->AddSeparator();
418 fHelpMenu->AddEntry(
"&About ROOT...", kGLHelpAbout);
419 fHelpMenu->Associate(fFrame);
422 fMenuBar =
new TGMenuBar(fFrame);
423 fMenuBar->AddPopup(
"&File", fFileMenu,
new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0));
424 fMenuBar->AddPopup(
"&Camera", fCameraMenu,
new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0));
425 fMenuBar->AddPopup(
"&Help", fHelpMenu,
new TGLayoutHints(kLHintsTop | kLHintsRight));
426 fFrame->AddFrame(fMenuBar,
new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1));
427 gVirtualX->SelectInput(fMenuBar->GetId(),
428 kKeyPressMask | kExposureMask | kPointerMotionMask
429 | kStructureNotifyMask | kFocusChangeMask
430 | kEnterWindowMask | kLeaveWindowMask);
432 fMenuBut =
new TGButton(fFrame);
433 fMenuBut->ChangeOptions(kRaisedFrame | kFixedHeight);
434 fMenuBut->Resize(20, 4);
435 fMenuBut->SetBackgroundColor(0x80A0C0);
436 fFrame->AddFrame(fMenuBut,
new TGLayoutHints(kLHintsNormal | kLHintsExpandX, 0, 0, 1, 1));
442 void TGLSAViewer::CreateFrames()
444 TGCompositeFrame* compositeFrame = fFrame;
447 compositeFrame =
new TGCompositeFrame(fFrame, 100, 100, kHorizontalFrame | kRaisedFrame);
448 fFrame->AddFrame(compositeFrame,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
450 fLeftVerticalFrame =
new TGVerticalFrame(compositeFrame, 195, 10, kFixedWidth);
451 compositeFrame->AddFrame(fLeftVerticalFrame,
new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 2, 2, 2, 2));
453 const TGWindow* cw = fFrame->GetClient()->GetRoot();
454 fFrame->GetClient()->SetRoot(fLeftVerticalFrame);
456 fGedEditor =
new TGedEditor();
457 fGedEditor->GetTGCanvas()->ChangeOptions(0);
458 fLeftVerticalFrame->RemoveFrame(fGedEditor);
459 fLeftVerticalFrame->AddFrame(fGedEditor,
new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 0, 0, 2, 2));
460 fLeftVerticalFrame->GetClient()->SetRoot((TGWindow*)cw);
461 fLeftVerticalFrame->MapSubwindows();
463 TGVSplitter *splitter =
new TGVSplitter(compositeFrame);
464 splitter->SetFrame(fLeftVerticalFrame, kTRUE);
465 compositeFrame->AddFrame(splitter,
new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 0,1,2,2) );
472 fRightVerticalFrame =
new TGVerticalFrame(compositeFrame, 10, 10);
473 compositeFrame->AddFrame(fRightVerticalFrame,
new TGLayoutHints(kLHintsRight | kLHintsExpandX | kLHintsExpandY));
475 fEventHandler =
new TGLEventHandler(0,
this);
483 void TGLSAViewer::SelectionChanged()
485 TGLPhysicalShape *selected =
const_cast<TGLPhysicalShape*
>(GetSelected());
488 fPShapeWrap->fPShape = selected;
489 if (fFileMenu->IsEntryChecked(kGLEditObject))
490 fGedEditor->SetModel(fPad, selected->GetLogical()->GetExternal(), kButton1Down);
492 fGedEditor->SetModel(fPad, fPShapeWrap, kButton1Down);
494 fPShapeWrap->fPShape = 0;
495 fGedEditor->SetModel(fPad,
this, kButton1Down);
502 void TGLSAViewer::Show()
505 fGedEditor->SetModel(fPad,
this, kButton1Down);
512 void TGLSAViewer::Close()
521 void TGLSAViewer::DeleteMenuBar()
523 fDeleteMenuBar=kTRUE;
529 void TGLSAViewer::DisableCloseMenuEntries()
531 fFileMenu->DeleteEntry(kGLCloseViewer);
532 fFileMenu->DeleteEntry(kGLQuitROOT);
538 void TGLSAViewer::EnableMenuBarHiding()
543 fHideMenuBar = kTRUE;
545 fMenuBar->Connect(
"ProcessedEvent(Event_t*)",
"TGLSAViewer",
this,
"HandleMenuBarHiding(Event_t*)");
546 fMenuBut->Connect(
"ProcessedEvent(Event_t*)",
"TGLSAViewer",
this,
"HandleMenuBarHiding(Event_t*)");
548 fFrame->HideFrame(fMenuBar);
549 fFrame->ShowFrame(fMenuBut);
552 fMenuHidingTimer =
new TTimer;
553 fMenuHidingTimer->Connect(
"Timeout()",
"TGLSAViewer",
this,
"MenuHidingTimeout()");
555 fFileMenu->CheckEntry(kGLHideMenus);
561 void TGLSAViewer::DisableMenuBarHiding()
566 fHideMenuBar = kFALSE;
568 fMenuBar->Disconnect(
"ProcessedEvent(Event_t*)",
this,
"HandleMenuBarHiding(Event_t*)");
569 fMenuBut->Disconnect(
"ProcessedEvent(Event_t*)",
this,
"HandleMenuBarHiding(Event_t*)");
571 fFrame->ShowFrame(fMenuBar);
572 fFrame->HideFrame(fMenuBut);
575 fMenuHidingTimer->TurnOff();
576 delete fMenuHidingTimer;
577 fMenuHidingTimer = 0;
579 fFileMenu->UnCheckEntry(kGLHideMenus);
585 void TGLSAViewer::HandleMenuBarHiding(Event_t* ev)
587 TGFrame *f = (TGFrame*) gTQSender;
591 if (ev->fType == kEnterNotify)
592 ResetMenuHidingTimer(kTRUE);
594 fMenuHidingTimer->TurnOff();
596 else if (f == fMenuBar)
598 if (ev->fType == kLeaveNotify &&
599 (ev->fX < 0 || ev->fX >= (Int_t) f->GetWidth() ||
600 ev->fY < 0 || ev->fY >= (Int_t) f->GetHeight()))
602 if (fMenuBar->GetCurrent() == 0)
603 ResetMenuHidingTimer(kFALSE);
605 fMenuBar->GetCurrent()->Connect(
"ProcessedEvent(Event_t*)",
"TGLSAViewer",
this,
"HandleMenuBarHiding(Event_t*)");
609 fMenuHidingTimer->TurnOff();
614 f->Disconnect(
"ProcessedEvent(Event_t*)",
this);
615 ResetMenuHidingTimer(kFALSE);
622 void TGLSAViewer::ResetMenuHidingTimer(Bool_t show_menu)
625 if (fMenuHidingTimer == 0)
628 fMenuHidingTimer->TurnOff();
630 fMenuHidingShowMenu = show_menu;
632 fMenuHidingTimer->SetTime(fgMenuHidingTimeout);
633 fMenuHidingTimer->Reset();
634 fMenuHidingTimer->TurnOn();
640 void TGLSAViewer::MenuHidingTimeout()
642 fMenuHidingTimer->TurnOff();
643 if (fMenuHidingShowMenu) {
644 fFrame->HideFrame(fMenuBut);
645 fFrame->ShowFrame(fMenuBar);
647 fFrame->HideFrame(fMenuBar);
648 fFrame->ShowFrame(fMenuBut);
657 void TGLSAViewer::SetMenuHidingTimeout(Long_t timeout)
659 fgMenuHidingTimeout = timeout;
665 Bool_t TGLSAViewer::ProcessFrameMessage(Long_t msg, Long_t parm1, Long_t)
667 switch (GET_MSG(msg)) {
669 switch (GET_SUBMSG(msg)) {
675 TString rootx = TROOT::GetBinDir() +
"/root -a &";
676 gSystem->Exec(rootx);
679 new TWin32SplashThread(kTRUE);
682 snprintf(str,32,
"About ROOT %s...", gROOT->GetVersion());
683 hd =
new TRootHelpDialog(
this, str, 600, 400);
684 hd->SetText(gHelpAbout);
690 case kGLHelpViewer: {
691 TRootHelpDialog * hd =
new TRootHelpDialog(fFrame,
"Help on GL Viewer...", 660, 400);
692 hd->AddText(fgHelpText1);
693 hd->AddText(fgHelpText2);
698 SetCurrentCamera(TGLViewer::kCameraPerspYOZ);
701 SetCurrentCamera(TGLViewer::kCameraPerspXOZ);
704 SetCurrentCamera(TGLViewer::kCameraPerspXOY);
707 SetCurrentCamera(TGLViewer::kCameraOrthoXOY);
710 SetCurrentCamera(TGLViewer::kCameraOrthoXOZ);
713 SetCurrentCamera(TGLViewer::kCameraOrthoZOY);
716 SetCurrentCamera(TGLViewer::kCameraOrthoZOX);
719 SetCurrentCamera(TGLViewer::kCameraOrthoXnOY);
722 SetCurrentCamera(TGLViewer::kCameraOrthoXnOZ);
725 SetCurrentCamera(TGLViewer::kCameraOrthoZnOY);
728 SetCurrentCamera(TGLViewer::kCameraOrthoZnOX);
737 SavePicture(
"viewer.eps");
740 SavePicture(
"viewer.pdf");
743 SavePicture(
"viewer.gif");
746 SavePicture(
"viewer.gif+");
749 SavePicture(
"viewer.jpg");
752 SavePicture(
"viewer.png");
757 fi.fFileTypes = gGLSaveAsTypes;
758 fi.fIniDir = StrDup(fDirName);
759 fi.fFileTypeIdx = fTypeIdx;
760 fi.fOverwrite = fOverwrite;
761 new TGFileDialog(gClient->GetDefaultRoot(), fFrame, kFDSave, &fi);
762 if (!fi.fFilename)
return kTRUE;
763 TString ft(fi.fFileTypes[fi.fFileTypeIdx+1]);
764 fDirName = fi.fIniDir;
765 fTypeIdx = fi.fFileTypeIdx;
766 fOverwrite = fi.fOverwrite;
768 TString file = fi.fFilename;
769 Bool_t match = kFALSE;
770 const char** fin = gGLSaveAsTypes; ++fin;
773 if (file.EndsWith(*fin + 1))
782 file += ft(ft.Index(
"."), ft.Length());
789 DisableMenuBarHiding();
791 EnableMenuBarHiding();
799 TTimer::SingleShot(50,
"TGLSAFrame", fFrame,
"SendCloseMessage()");
802 if (!gApplication->ReturnFromRun())
804 gApplication->Terminate(0);
822 void TGLSAViewer::ToggleEditObject()
824 if (fFileMenu->IsEntryChecked(kGLEditObject))
825 fFileMenu->UnCheckEntry(kGLEditObject);
827 fFileMenu->CheckEntry(kGLEditObject);
834 void TGLSAViewer::ToggleOrthoRotate()
836 if (fCameraMenu->IsEntryChecked(kGLOrthoRotate))
837 fCameraMenu->UnCheckEntry(kGLOrthoRotate);
839 fCameraMenu->CheckEntry(kGLOrthoRotate);
840 Bool_t state = fCameraMenu->IsEntryChecked(kGLOrthoRotate);
841 fOrthoXOYCamera.SetEnableRotate(state);
842 fOrthoXOZCamera.SetEnableRotate(state);
843 fOrthoZOYCamera.SetEnableRotate(state);
844 fOrthoXnOYCamera.SetEnableRotate(state);
845 fOrthoXnOZCamera.SetEnableRotate(state);
846 fOrthoZnOYCamera.SetEnableRotate(state);
852 void TGLSAViewer::ToggleOrthoDolly()
854 if (fCameraMenu->IsEntryChecked(kGLOrthoDolly))
855 fCameraMenu->UnCheckEntry(kGLOrthoDolly);
857 fCameraMenu->CheckEntry(kGLOrthoDolly);
858 Bool_t state = ! fCameraMenu->IsEntryChecked(kGLOrthoDolly);
859 fOrthoXOYCamera.SetDollyToZoom(state);
860 fOrthoXOZCamera.SetDollyToZoom(state);
861 fOrthoZOYCamera.SetDollyToZoom(state);