Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/framework/pandaFramework.cxx

Go to the documentation of this file.
00001 // Filename: pandaFramework.cxx
00002 // Created by:  drose (02Apr02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "pandaFramework.h"
00020 #include "clockObject.h"
00021 #include "pStatClient.h"
00022 #include "eventQueue.h"
00023 #include "dataGraphTraverser.h"
00024 #include "collisionNode.h"
00025 #include "config_framework.h"
00026 #include "graphicsPipeSelection.h"
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: PandaFramework::Constructor
00030 //       Access: Public
00031 //  Description: 
00032 ////////////////////////////////////////////////////////////////////
00033 PandaFramework::
00034 PandaFramework() :
00035   _event_handler(EventQueue::get_global_event_queue())
00036 {
00037   _is_open = false;
00038   _made_default_pipe = false;
00039   _data_root = NodePath("data");
00040   _window_title = "Panda";
00041   _start_time = 0.0;
00042   _frame_count = 0;
00043   _wireframe_enabled = false;
00044   _texture_enabled = true;
00045   _two_sided_enabled = false;
00046   _lighting_enabled = false;
00047   _background_type = WindowFramework::BT_gray;
00048   _default_keys_enabled = false;
00049   _exit_flag = false;
00050 }
00051 
00052 ////////////////////////////////////////////////////////////////////
00053 //     Function: PandaFramework::Destructor
00054 //       Access: Public, Virtual
00055 //  Description: 
00056 ////////////////////////////////////////////////////////////////////
00057 PandaFramework::
00058 ~PandaFramework() {
00059   if (_is_open) {
00060     close_framework();
00061   }
00062 }
00063 
00064 ////////////////////////////////////////////////////////////////////
00065 //     Function: PandaFramework::open_framework
00066 //       Access: Public
00067 //  Description: Should be called once at the beginning of the
00068 //               application to initialize Panda (and the framework)
00069 //               for use.  The command-line arguments should be passed
00070 //               in so Panda can remove any arguments that it
00071 //               recognizes as special control parameters.
00072 ////////////////////////////////////////////////////////////////////
00073 void PandaFramework::
00074 open_framework(int &argc, char **&argv) {
00075   if (_is_open) {
00076     return;
00077   }
00078 
00079   _is_open = true;
00080 
00081   reset_frame_rate();
00082 }
00083 
00084 ////////////////////////////////////////////////////////////////////
00085 //     Function: PandaFramework::close_framework
00086 //       Access: Public
00087 //  Description: Should be called at the end of an application to
00088 //               close Panda.  This is optional, as the destructor
00089 //               will do the same thing.
00090 ////////////////////////////////////////////////////////////////////
00091 void PandaFramework::
00092 close_framework() {
00093   if (!_is_open) {
00094     return;
00095   }
00096 
00097   close_all_windows();
00098   // Also close down any other windows that might have been opened.
00099   _engine.remove_all_windows();
00100   _event_handler.remove_all_hooks();
00101 
00102   _is_open = false;
00103   _made_default_pipe = false;
00104   _default_pipe.clear();
00105 
00106   _start_time = 0.0;
00107   _frame_count = 0;
00108   _wireframe_enabled = false;
00109   _two_sided_enabled = false;
00110   _lighting_enabled = false;
00111   _default_keys_enabled = false;
00112   _exit_flag = false;
00113 }
00114 
00115 ////////////////////////////////////////////////////////////////////
00116 //     Function: PandaFramework::get_default_pipe
00117 //       Access: Public
00118 //  Description: Returns the default pipe.  This is the GraphicsPipe
00119 //               that all windows in the framework will be created on,
00120 //               unless otherwise specified in open_window().  It is
00121 //               usually the primary graphics interface on the local
00122 //               machine.
00123 //
00124 //               If the default pipe has not yet been created, this
00125 //               creates it.
00126 //
00127 //               The return value is the default pipe, or NULL if no
00128 //               default pipe could be created.
00129 ////////////////////////////////////////////////////////////////////
00130 GraphicsPipe *PandaFramework::
00131 get_default_pipe() {
00132   nassertr(_is_open, NULL);
00133   if (!_made_default_pipe) {
00134     make_default_pipe();
00135     _made_default_pipe = true;
00136   }
00137   return _default_pipe;
00138 }
00139 
00140 ////////////////////////////////////////////////////////////////////
00141 //     Function: PandaFramework::get_default_window_props
00142 //       Access: Public, Virtual
00143 //  Description: Fills in the indicated window properties structure
00144 //               according to the normal window properties for this
00145 //               application.
00146 ////////////////////////////////////////////////////////////////////
00147 void PandaFramework::
00148 get_default_window_props(WindowProperties &props) {
00149   props.set_open(true);
00150   props.set_size(win_width, win_height);
00151   props.set_fullscreen(fullscreen);
00152   props.set_undecorated(undecorated);
00153   props.set_cursor_hidden(cursor_hidden);
00154   props.set_title(_window_title);
00155 }
00156 
00157 ////////////////////////////////////////////////////////////////////
00158 //     Function: PandaFramework::open_window
00159 //       Access: Public
00160 //  Description: Opens a new window, using the default parameters.
00161 //               Returns the new WindowFramework if successful, or
00162 //               NULL if not.
00163 ////////////////////////////////////////////////////////////////////
00164 WindowFramework *PandaFramework::
00165 open_window(GraphicsPipe *pipe) {
00166   nassertr(_is_open, NULL);
00167 
00168   WindowProperties props;
00169   get_default_window_props(props);
00170 
00171   return open_window(props, pipe);
00172 }
00173 
00174 ////////////////////////////////////////////////////////////////////
00175 //     Function: PandaFramework::open_window
00176 //       Access: Public
00177 //  Description: Opens a new window using the indicated properties.
00178 //               (You may initialize the properties to their default
00179 //               values by calling get_default_window_props() first.)
00180 //
00181 //               Returns the new WindowFramework if successful, or
00182 //               NULL if not.
00183 ////////////////////////////////////////////////////////////////////
00184 WindowFramework *PandaFramework::
00185 open_window(const WindowProperties &props, GraphicsPipe *pipe) {
00186   if (pipe == (GraphicsPipe *)NULL) {
00187     pipe = get_default_pipe();
00188     if (pipe == (GraphicsPipe *)NULL) {
00189       // Can't get a pipe.
00190       return NULL;
00191     }
00192   }
00193 
00194   nassertr(_is_open, NULL);
00195   PT(WindowFramework) wf = make_window_framework();
00196   wf->set_wireframe(get_wireframe());
00197   wf->set_texture(get_texture());
00198   wf->set_two_sided(get_two_sided());
00199   wf->set_lighting(get_lighting());
00200   wf->set_background_type(get_background_type());
00201 
00202   GraphicsWindow *win = wf->open_window(props, &_engine, pipe);
00203   if (win == (GraphicsWindow *)NULL) {
00204     // Oops, couldn't make an actual window.
00205     delete wf;
00206     return NULL;
00207   }
00208 
00209   _windows.push_back(wf);
00210   return wf;
00211 }
00212 
00213 ////////////////////////////////////////////////////////////////////
00214 //     Function: PandaFramework::find_window
00215 //       Access: Public
00216 //  Description: Returns the index of the WindowFramework object that
00217 //               references the indicated GraphicsWindow pointer, or
00218 //               -1 if none do.
00219 ////////////////////////////////////////////////////////////////////
00220 int PandaFramework::
00221 find_window(const GraphicsWindow *win) const {
00222   int n;
00223   for (n = 0; n < (int)_windows.size(); n++) {
00224     if (_windows[n]->get_graphics_window() == win) {
00225       return n;
00226     }
00227   }
00228 
00229   return -1;
00230 }
00231 
00232 ////////////////////////////////////////////////////////////////////
00233 //     Function: PandaFramework::find_window
00234 //       Access: Public
00235 //  Description: Returns the index of the given WindowFramework
00236 //               object, or -1 if the object does not represent a
00237 //               window opened with this PandaFramework.
00238 ////////////////////////////////////////////////////////////////////
00239 int PandaFramework::
00240 find_window(const WindowFramework *wf) const {
00241   int n;
00242   for (n = 0; n < (int)_windows.size(); n++) {
00243     if (_windows[n] == wf) {
00244       return n;
00245     }
00246   }
00247 
00248   return -1;
00249 }
00250 
00251 
00252 ////////////////////////////////////////////////////////////////////
00253 //     Function: PandaFramework::close_window
00254 //       Access: Public
00255 //  Description: Closes the nth window and removes it from the list.
00256 ////////////////////////////////////////////////////////////////////
00257 void PandaFramework::
00258 close_window(int n) {
00259   nassertv(n >= 0 && n < (int)_windows.size());
00260   WindowFramework *wf = _windows[n];
00261 
00262   GraphicsWindow *win = wf->get_graphics_window();
00263   if (win != (GraphicsWindow *)NULL) {
00264     _engine.remove_window(win);
00265   }
00266   
00267   wf->close_window();
00268   _windows.erase(_windows.begin() + n);
00269 }
00270 
00271 ////////////////////////////////////////////////////////////////////
00272 //     Function: PandaFramework::close_all_windows
00273 //       Access: Public
00274 //  Description: Closes all currently open windows and empties the
00275 //               list of windows.
00276 ////////////////////////////////////////////////////////////////////
00277 void PandaFramework::
00278 close_all_windows() {
00279   Windows::iterator wi;
00280   for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
00281     WindowFramework *wf = (*wi);
00282 
00283     GraphicsWindow *win = wf->get_graphics_window();
00284     if (win != (GraphicsWindow *)NULL) {
00285       _engine.remove_window(win);
00286     }
00287     
00288     wf->close_window();
00289   }
00290 
00291   _windows.clear();
00292 }
00293 
00294 ////////////////////////////////////////////////////////////////////
00295 //     Function: PandaFramework::all_windows_closed
00296 //       Access: Public
00297 //  Description: Returns true if all of the opened windows have been
00298 //               closed by the user, false otherwise.
00299 ////////////////////////////////////////////////////////////////////
00300 bool PandaFramework::
00301 all_windows_closed() const {
00302   Windows::const_iterator wi;
00303   for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
00304     WindowFramework *wf = (*wi);
00305     if (wf->get_graphics_window()->get_properties().get_open()) {
00306       return false;
00307     }
00308   }
00309 
00310   return true;
00311 }
00312 
00313 ////////////////////////////////////////////////////////////////////
00314 //     Function: PandaFramework::get_models
00315 //       Access: Public
00316 //  Description: Returns the root of the scene graph normally reserved
00317 //               for parenting models and such.  This scene graph may
00318 //               be instanced to each window's render tree as the
00319 //               window is created.
00320 ////////////////////////////////////////////////////////////////////
00321 const NodePath &PandaFramework::
00322 get_models() {
00323   if (_models.is_empty()) {
00324     _models = NodePath("models");
00325   }
00326   return _models;
00327 }
00328 
00329 ////////////////////////////////////////////////////////////////////
00330 //     Function: PandaFramework::report_frame_rate
00331 //       Access: Public
00332 //  Description: Reports the currently measured average frame rate to
00333 //               the indicated ostream.
00334 ////////////////////////////////////////////////////////////////////
00335 void PandaFramework::
00336 report_frame_rate(ostream &out) const {
00337   double now = ClockObject::get_global_clock()->get_frame_time();
00338   double delta = now - _start_time;
00339   
00340   int frame_count = ClockObject::get_global_clock()->get_frame_count();
00341   int num_frames = frame_count - _frame_count;
00342   if (num_frames > 0) {
00343     out << num_frames << " frames in " << delta << " seconds.\n";
00344     double fps = ((double)num_frames) / delta;
00345     out << fps << " fps average (" << 1000.0 / fps << "ms)\n";
00346   }
00347 }
00348 
00349 ////////////////////////////////////////////////////////////////////
00350 //     Function: PandaFramework::reset_frame_rate
00351 //       Access: Public
00352 //  Description: Resets the frame rate computation.
00353 ////////////////////////////////////////////////////////////////////
00354 void PandaFramework::
00355 reset_frame_rate() {
00356   _start_time = ClockObject::get_global_clock()->get_frame_time();
00357   _frame_count = ClockObject::get_global_clock()->get_frame_count();
00358 }
00359 
00360 ////////////////////////////////////////////////////////////////////
00361 //     Function: PandaFramework::set_wireframe
00362 //       Access: Public
00363 //  Description: Sets the wireframe state on all windows.
00364 ////////////////////////////////////////////////////////////////////
00365 void PandaFramework::
00366 set_wireframe(bool enable) {
00367   Windows::iterator wi;
00368   for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
00369     WindowFramework *wf = (*wi);
00370     wf->set_wireframe(enable);
00371   }
00372 
00373   _wireframe_enabled = enable;
00374 }
00375 
00376 ////////////////////////////////////////////////////////////////////
00377 //     Function: PandaFramework::set_texture
00378 //       Access: Public
00379 //  Description: Sets the texture state on all windows.
00380 ////////////////////////////////////////////////////////////////////
00381 void PandaFramework::
00382 set_texture(bool enable) {
00383   Windows::iterator wi;
00384   for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
00385     WindowFramework *wf = (*wi);
00386     wf->set_texture(enable);
00387   }
00388 
00389   _texture_enabled = enable;
00390 }
00391 
00392 ////////////////////////////////////////////////////////////////////
00393 //     Function: PandaFramework::set_two_sided
00394 //       Access: Public
00395 //  Description: Sets the two_sided state on all windows.
00396 ////////////////////////////////////////////////////////////////////
00397 void PandaFramework::
00398 set_two_sided(bool enable) {
00399   Windows::iterator wi;
00400   for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
00401     WindowFramework *wf = (*wi);
00402     wf->set_two_sided(enable);
00403   }
00404 
00405   _two_sided_enabled = enable;
00406 }
00407 
00408 ////////////////////////////////////////////////////////////////////
00409 //     Function: PandaFramework::set_lighting
00410 //       Access: Public
00411 //  Description: Sets the lighting state on all windows.
00412 ////////////////////////////////////////////////////////////////////
00413 void PandaFramework::
00414 set_lighting(bool enable) {
00415   Windows::iterator wi;
00416   for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
00417     WindowFramework *wf = (*wi);
00418     wf->set_lighting(enable);
00419   }
00420 
00421   _lighting_enabled = enable;
00422 }
00423 
00424 ////////////////////////////////////////////////////////////////////
00425 //     Function: BackgroundFramework::set_background_type
00426 //       Access: Public
00427 //  Description: Sets the background type of all windows.
00428 ////////////////////////////////////////////////////////////////////
00429 void PandaFramework::
00430 set_background_type(WindowFramework::BackgroundType type) {
00431   Windows::iterator wi;
00432   for (wi = _windows.begin(); wi != _windows.end(); ++wi) {
00433     WindowFramework *wf = (*wi);
00434     wf->set_background_type(type);
00435   }
00436 
00437   _background_type = type;
00438 }
00439 
00440 ////////////////////////////////////////////////////////////////////
00441 //     Function: PandaFramework::hide_collision_solids
00442 //       Access: Public
00443 //  Description: Hides any collision solids which are visible in the
00444 //               indicated scene graph.  Returns the number of
00445 //               collision solids hidden.
00446 ////////////////////////////////////////////////////////////////////
00447 int PandaFramework::
00448 hide_collision_solids(NodePath node) {
00449   int num_changed = 0;
00450 
00451   if (node.node()->is_of_type(CollisionNode::get_class_type())) {
00452     if (!node.is_hidden()) {
00453       node.hide();
00454       num_changed++;
00455     }
00456   }
00457 
00458   int num_children = node.get_num_children();
00459   for (int i = 0; i < num_children; i++) {
00460     num_changed += hide_collision_solids(node.get_child(i));
00461   }
00462 
00463   return num_changed;
00464 }
00465 
00466 ////////////////////////////////////////////////////////////////////
00467 //     Function: PandaFramework::show_collision_solids
00468 //       Access: Public
00469 //  Description: Shows any collision solids which are directly hidden
00470 //               in the indicated scene graph.  Returns the number of
00471 //               collision solids shown.
00472 ////////////////////////////////////////////////////////////////////
00473 int PandaFramework::
00474 show_collision_solids(NodePath node) {
00475   int num_changed = 0;
00476 
00477   if (node.node()->is_of_type(CollisionNode::get_class_type())) {
00478     if (node.get_hidden_ancestor() == node) {
00479       node.show();
00480       num_changed++;
00481     }
00482   }
00483 
00484   int num_children = node.get_num_children();
00485   for (int i = 0; i < num_children; i++) {
00486     num_changed += show_collision_solids(node.get_child(i));
00487   }
00488 
00489   return num_changed;
00490 }
00491 
00492 ////////////////////////////////////////////////////////////////////
00493 //     Function: PandaFramework::set_highlight
00494 //       Access: Public
00495 //  Description: Sets the indicated node (normally a node within the
00496 //               get_models() tree) up as the highlighted node.
00497 //               Certain operations affect the highlighted node only.
00498 ////////////////////////////////////////////////////////////////////
00499 void PandaFramework::
00500 set_highlight(const NodePath &node) {
00501   clear_highlight();
00502   _highlight = node;
00503   if (!_highlight.is_empty()) {
00504     framework_cat.info(false) << _highlight << "\n";
00505     _highlight.show_bounds();
00506   }
00507 }
00508 
00509 ////////////////////////////////////////////////////////////////////
00510 //     Function: PandaFramework::clear_highlight
00511 //       Access: Public
00512 //  Description: Unhighlights the currently highlighted node, if any.
00513 ////////////////////////////////////////////////////////////////////
00514 void PandaFramework::
00515 clear_highlight() {
00516   if (!_highlight.is_empty()) {
00517     _highlight.hide_bounds();
00518     _highlight = NodePath();
00519   }
00520 }
00521 
00522 ////////////////////////////////////////////////////////////////////
00523 //     Function: PandaFramework::enable_default_keys
00524 //       Access: Public
00525 //  Description: Sets callbacks on the event handler to handle all of
00526 //               the normal viewer keys, like t to toggle texture, ESC
00527 //               or q to quit, etc.
00528 ////////////////////////////////////////////////////////////////////
00529 void PandaFramework::
00530 enable_default_keys() {
00531   if (!_default_keys_enabled) {
00532     do_enable_default_keys();
00533     _default_keys_enabled = true;
00534   }
00535 }
00536 
00537 ////////////////////////////////////////////////////////////////////
00538 //     Function: PandaFramework::do_frame
00539 //       Access: Public, Virtual
00540 //  Description: Renders one frame and performs all associated
00541 //               processing.  Returns true if we should continue
00542 //               rendering, false if we should exit.  This is normally
00543 //               called only from main_loop().
00544 ////////////////////////////////////////////////////////////////////
00545 bool PandaFramework::
00546 do_frame() {
00547   nassertr(_is_open, false);
00548   DataGraphTraverser dg_trav;
00549   dg_trav.traverse(_data_root.node());
00550   _event_handler.process_events();
00551   _engine.render_frame();
00552 
00553   return !_exit_flag;
00554 }
00555 
00556 ////////////////////////////////////////////////////////////////////
00557 //     Function: PandaFramework::main_loop
00558 //       Access: Public
00559 //  Description: Called to yield control to the panda framework.  This
00560 //               function does not return until set_exit_flag() has
00561 //               been called.
00562 ////////////////////////////////////////////////////////////////////
00563 void PandaFramework::
00564 main_loop() {
00565   while (do_frame()) {
00566   }
00567 }
00568 
00569 ////////////////////////////////////////////////////////////////////
00570 //     Function: PandaFramework::make_window_framework
00571 //       Access: Protected, Virtual
00572 //  Description: Creates a new WindowFramework object.  This is
00573 //               provided as a hook so derived PandaFramework classes
00574 //               can create custom WindowFramework objects.
00575 ////////////////////////////////////////////////////////////////////
00576 PT(WindowFramework) PandaFramework::
00577 make_window_framework() {
00578   return new WindowFramework(this);
00579 }
00580 
00581 ////////////////////////////////////////////////////////////////////
00582 //     Function: PandaFramework::make_default_pipe
00583 //       Access: Protected, Virtual
00584 //  Description: Creates the default GraphicsPipe that will contain
00585 //               all windows that are not opened on a specific pipe.
00586 ////////////////////////////////////////////////////////////////////
00587 void PandaFramework::
00588 make_default_pipe() {
00589   // This depends on the shared library or libraries (DLL's to you
00590   // Windows folks) that have been loaded in at runtime from the
00591   // load-display and/or aux-display Configrc variables.
00592   GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr();
00593   selection->print_pipe_types();
00594   _default_pipe = selection->make_default_pipe();
00595 
00596   if (_default_pipe == (GraphicsPipe*)NULL) {
00597     nout << "No graphics pipe is available!  Check your Configrc!\n";
00598   }
00599 }
00600 
00601 ////////////////////////////////////////////////////////////////////
00602 //     Function: PandaFramework::do_enable_default_keys
00603 //       Access: Protected, Virtual
00604 //  Description: The implementation of enable_default_keys().
00605 ////////////////////////////////////////////////////////////////////
00606 void PandaFramework::
00607 do_enable_default_keys() {
00608   _event_handler.add_hook("escape", event_esc, this);
00609   _event_handler.add_hook("q", event_esc, this);
00610   _event_handler.add_hook("f", event_f, this);
00611   _event_handler.add_hook("w", event_w, this);
00612   _event_handler.add_hook("t", event_t, this);
00613   _event_handler.add_hook("b", event_b, this);
00614   _event_handler.add_hook("i", event_i, this);
00615   _event_handler.add_hook("l", event_l, this);
00616   _event_handler.add_hook("c", event_c, this);
00617   _event_handler.add_hook("shift-c", event_C, this);
00618   _event_handler.add_hook("shift-b", event_B, this);
00619   _event_handler.add_hook("shift-l", event_L, this);
00620   _event_handler.add_hook("h", event_h, this);
00621   _event_handler.add_hook("arrow_up", event_arrow_up, this);
00622   _event_handler.add_hook("arrow_down", event_arrow_down, this);
00623   _event_handler.add_hook("arrow_left", event_arrow_left, this);
00624   _event_handler.add_hook("arrow_right", event_arrow_right, this);
00625   _event_handler.add_hook("shift-s", event_S, this);
00626   _event_handler.add_hook(",", event_comma, this);
00627   _event_handler.add_hook("window-event", event_window_event, this);
00628 }
00629 
00630 ////////////////////////////////////////////////////////////////////
00631 //     Function: PandaFramework::event_esc
00632 //       Access: Protected, Static
00633 //  Description: Default handler for ESC or q key: close the current
00634 //               window (and exit the application if that was the last
00635 //               window).
00636 ////////////////////////////////////////////////////////////////////
00637 void PandaFramework::
00638 event_esc(CPT_Event event, void *data) { 
00639   if (event->get_num_parameters() == 1) {
00640     EventParameter param = event->get_parameter(0);
00641     WindowFramework *wf;
00642     DCAST_INTO_V(wf, param.get_ptr());
00643 
00644     PandaFramework *self = (PandaFramework *)data;
00645     self->close_window(wf);
00646 
00647     // If we closed the last window, shut down.
00648     if (self->_windows.empty()) {
00649       self->_exit_flag = true;
00650     }
00651   }
00652 }
00653 
00654 ////////////////////////////////////////////////////////////////////
00655 //     Function: PandaFramework::event_f
00656 //       Access: Protected, Static
00657 //  Description: Default handler for f key: report and reset frame
00658 //               rate.
00659 ////////////////////////////////////////////////////////////////////
00660 void PandaFramework::
00661 event_f(CPT_Event, void *data) {
00662   PandaFramework *self = (PandaFramework *)data;
00663   self->report_frame_rate(nout);
00664   self->reset_frame_rate();
00665 }
00666 
00667 ////////////////////////////////////////////////////////////////////
00668 //     Function: PandaFramework::event_w
00669 //       Access: Protected, Static
00670 //  Description: Default handler for w key: toggle wireframe.
00671 ////////////////////////////////////////////////////////////////////
00672 void PandaFramework::
00673 event_w(CPT_Event event, void *) {
00674   if (event->get_num_parameters() == 1) {
00675     EventParameter param = event->get_parameter(0);
00676     WindowFramework *wf;
00677     DCAST_INTO_V(wf, param.get_ptr());
00678 
00679     wf->set_wireframe(!wf->get_wireframe());
00680   }
00681 }
00682 
00683 ////////////////////////////////////////////////////////////////////
00684 //     Function: PandaFramework::event_t
00685 //       Access: Protected, Static
00686 //  Description: Default handler for t key: toggle texture.
00687 ////////////////////////////////////////////////////////////////////
00688 void PandaFramework::
00689 event_t(CPT_Event event, void *) {
00690   if (event->get_num_parameters() == 1) {
00691     EventParameter param = event->get_parameter(0);
00692     WindowFramework *wf;
00693     DCAST_INTO_V(wf, param.get_ptr());
00694 
00695     wf->set_texture(!wf->get_texture());
00696   }
00697 }
00698 
00699 ////////////////////////////////////////////////////////////////////
00700 //     Function: PandaFramework::event_b
00701 //       Access: Protected, Static
00702 //  Description: Default handler for b key: toggle backface (two-sided
00703 //               rendering).
00704 ////////////////////////////////////////////////////////////////////
00705 void PandaFramework::
00706 event_b(CPT_Event event, void *) {
00707   if (event->get_num_parameters() == 1) {
00708     EventParameter param = event->get_parameter(0);
00709     WindowFramework *wf;
00710     DCAST_INTO_V(wf, param.get_ptr());
00711 
00712     wf->set_two_sided(!wf->get_two_sided());
00713   }
00714 }
00715 
00716 ////////////////////////////////////////////////////////////////////
00717 //     Function: PandaFramework::event_i
00718 //       Access: Protected, Static
00719 //  Description: Default handler for i key: invert one-sided faces.
00720 ////////////////////////////////////////////////////////////////////
00721 void PandaFramework::
00722 event_i(CPT_Event event, void *) {
00723   if (event->get_num_parameters() == 1) {
00724     EventParameter param = event->get_parameter(0);
00725     WindowFramework *wf;
00726     DCAST_INTO_V(wf, param.get_ptr());
00727 
00728     wf->set_one_sided_reverse(!wf->get_one_sided_reverse());
00729   }
00730 }
00731 
00732 ////////////////////////////////////////////////////////////////////
00733 //     Function: PandaFramework::event_l
00734 //       Access: Protected, Static
00735 //  Description: Default handler for l key: toggle lighting.
00736 ////////////////////////////////////////////////////////////////////
00737 void PandaFramework::
00738 event_l(CPT_Event event, void *) {
00739   if (event->get_num_parameters() == 1) {
00740     EventParameter param = event->get_parameter(0);
00741     WindowFramework *wf;
00742     DCAST_INTO_V(wf, param.get_ptr());
00743 
00744     wf->set_lighting(!wf->get_lighting());
00745   }
00746 }
00747 
00748 ////////////////////////////////////////////////////////////////////
00749 //     Function: PandaFramework::event_c
00750 //       Access: Protected, Static
00751 //  Description: Default handler for c key: center the trackball over
00752 //               the scene, or over the highlighted part of the scene.
00753 ////////////////////////////////////////////////////////////////////
00754 void PandaFramework::
00755 event_c(CPT_Event event, void *data) {
00756   if (event->get_num_parameters() == 1) {
00757     EventParameter param = event->get_parameter(0);
00758     WindowFramework *wf;
00759     DCAST_INTO_V(wf, param.get_ptr());
00760 
00761     PandaFramework *self = (PandaFramework *)data;
00762 
00763     NodePath node = self->get_highlight();
00764     if (node.is_empty()) {
00765       node = self->get_models();
00766     }
00767     wf->center_trackball(node);
00768   }
00769 }
00770 
00771 ////////////////////////////////////////////////////////////////////
00772 //     Function: PandaFramework::event_C
00773 //       Access: Protected, Static
00774 //  Description: Default handler for shift-C key: toggle the showing
00775 //               of collision solids.
00776 ////////////////////////////////////////////////////////////////////
00777 void PandaFramework::
00778 event_C(CPT_Event, void *data) {
00779   PandaFramework *self = (PandaFramework *)data;
00780 
00781   NodePath node = self->get_highlight();
00782   if (node.is_empty()) {
00783     node = self->get_models();
00784   }
00785 
00786   if (self->hide_collision_solids(node) == 0) {
00787     self->show_collision_solids(node);
00788   }
00789 }
00790 
00791 ////////////////////////////////////////////////////////////////////
00792 //     Function: PandaFramework::event_B
00793 //       Access: Protected, Static
00794 //  Description: Default handler for shift-B key: describe the
00795 //               bounding volume of the currently selected object, or
00796 //               the entire scene.
00797 ////////////////////////////////////////////////////////////////////
00798 void PandaFramework::
00799 event_B(CPT_Event, void *data) {
00800   PandaFramework *self = (PandaFramework *)data;
00801 
00802   NodePath node = self->get_highlight();
00803   if (node.is_empty()) {
00804     node = self->get_models();
00805   }
00806 
00807   node.get_bounds()->write(nout);
00808 }
00809 
00810 ////////////////////////////////////////////////////////////////////
00811 //     Function: PandaFramework::event_L
00812 //       Access: Protected, Static
00813 //  Description: Default handler for shift-L key: list the contents of
00814 //               the scene graph, or the highlighted node.
00815 ////////////////////////////////////////////////////////////////////
00816 void PandaFramework::
00817 event_L(CPT_Event, void *data) {
00818   PandaFramework *self = (PandaFramework *)data;
00819 
00820   NodePath node = self->get_highlight();
00821   if (node.is_empty()) {
00822     node = self->get_models();
00823   }
00824 
00825   node.ls();
00826 }
00827 
00828 ////////////////////////////////////////////////////////////////////
00829 //     Function: PandaFramework::event_h
00830 //       Access: Protected, Static
00831 //  Description: Default handler for h key: toggle highlight mode.  In
00832 //               this mode, you can walk the scene graph with the
00833 //               arrow keys to highlight different nodes.
00834 ////////////////////////////////////////////////////////////////////
00835 void PandaFramework::
00836 event_h(CPT_Event, void *data) {
00837   PandaFramework *self = (PandaFramework *)data;
00838   
00839   if (self->has_highlight()) {
00840     self->clear_highlight();
00841   } else {
00842     self->set_highlight(self->get_models());
00843   }
00844 }
00845 
00846 ////////////////////////////////////////////////////////////////////
00847 //     Function: PandaFramework::event_arrow_up
00848 //       Access: Protected, Static
00849 //  Description: Default handler for up arrow key: in highlight mode,
00850 //               move the highlight to the node's parent.
00851 ////////////////////////////////////////////////////////////////////
00852 void PandaFramework::
00853 event_arrow_up(CPT_Event, void *data) {
00854   PandaFramework *self = (PandaFramework *)data;
00855 
00856   if (self->has_highlight()) {
00857     NodePath node = self->get_highlight();
00858     if (node.has_parent() && node != self->get_models()) {
00859       self->set_highlight(node.get_parent());
00860     }
00861   }
00862 }
00863 
00864 ////////////////////////////////////////////////////////////////////
00865 //     Function: PandaFramework::event_arrow_down
00866 //       Access: Protected, Static
00867 //  Description: Default handler for up arrow key: in highlight mode,
00868 //               move the highlight to the node's first child.
00869 ////////////////////////////////////////////////////////////////////
00870 void PandaFramework::
00871 event_arrow_down(CPT_Event, void *data) {
00872   PandaFramework *self = (PandaFramework *)data;
00873 
00874   if (self->has_highlight()) {
00875     NodePath node = self->get_highlight();
00876     if (node.get_num_children() > 0) {
00877       self->set_highlight(node.get_child(0));
00878     }
00879   }
00880 }
00881 
00882 ////////////////////////////////////////////////////////////////////
00883 //     Function: PandaFramework::event_arrow_left
00884 //       Access: Protected, Static
00885 //  Description: Default handler for up arrow key: in highlight mode,
00886 //               move the highlight to the node's nearest sibling on
00887 //               the left.
00888 ////////////////////////////////////////////////////////////////////
00889 void PandaFramework::
00890 event_arrow_left(CPT_Event, void *data) {
00891   PandaFramework *self = (PandaFramework *)data;
00892 
00893   if (self->has_highlight()) {
00894     NodePath node = self->get_highlight();
00895     NodePath parent = node.get_parent();
00896     if (node.has_parent() && node != self->get_models()) {
00897       int index = parent.node()->find_child(node.node());
00898       nassertv(index >= 0);
00899       int sibling = index - 1;
00900       if (sibling >= 0) {
00901         self->set_highlight(NodePath(parent, parent.node()->get_child(sibling)));
00902       }
00903     }
00904   }
00905 }
00906 
00907 ////////////////////////////////////////////////////////////////////
00908 //     Function: PandaFramework::event_arrow_right
00909 //       Access: Protected, Static
00910 //  Description: Default handler for up arrow key: in highlight mode,
00911 //               move the highlight to the node's nearest sibling on
00912 //               the right.
00913 ////////////////////////////////////////////////////////////////////
00914 void PandaFramework::
00915 event_arrow_right(CPT_Event, void *data) {
00916   PandaFramework *self = (PandaFramework *)data;
00917 
00918   if (self->has_highlight()) {
00919     NodePath node = self->get_highlight();
00920     NodePath parent = node.get_parent();
00921     if (node.has_parent() && node != self->get_models()) {
00922       int index = parent.node()->find_child(node.node());
00923       nassertv(index >= 0);
00924       int num_children = parent.node()->get_num_children();
00925       int sibling = index + 1;
00926       if (sibling < num_children) {
00927         self->set_highlight(NodePath(parent, parent.node()->get_child(sibling)));
00928       }
00929     }
00930   }
00931 }
00932 
00933 ////////////////////////////////////////////////////////////////////
00934 //     Function: PandaFramework::event_S
00935 //       Access: Protected, Static
00936 //  Description: Default handler for shift-S key: activate stats.
00937 ////////////////////////////////////////////////////////////////////
00938 void PandaFramework::
00939 event_S(CPT_Event, void *data) {
00940 #ifdef DO_PSTATS
00941   nout << "Connecting to stats host" << endl;
00942   PStatClient::connect();
00943 #else
00944   nout << "Stats host not supported." << endl;
00945 #endif
00946 }
00947 
00948 ////////////////////////////////////////////////////////////////////
00949 //     Function: PandaFramework::event_comma
00950 //       Access: Protected, Static
00951 //  Description: Default handler for comma key: rotate background color.
00952 ////////////////////////////////////////////////////////////////////
00953 void PandaFramework::
00954 event_comma(CPT_Event event, void *) {
00955   if (event->get_num_parameters() == 1) {
00956     EventParameter param = event->get_parameter(0);
00957     WindowFramework *wf;
00958     DCAST_INTO_V(wf, param.get_ptr());
00959 
00960     switch (wf->get_background_type()) {
00961     case WindowFramework::BT_other:
00962       break;
00963       
00964     case WindowFramework::BT_none:
00965       wf->set_background_type(WindowFramework::BT_default);
00966       break;
00967       
00968     default:
00969       wf->set_background_type((WindowFramework::BackgroundType)(wf->get_background_type() + 1));
00970     }
00971   }
00972 }
00973 
00974 ////////////////////////////////////////////////////////////////////
00975 //     Function: PandaFramework::event_window_event
00976 //       Access: Protected, Static
00977 //  Description: Default handler for window events: window resized or
00978 //               closed, etc.
00979 ////////////////////////////////////////////////////////////////////
00980 void PandaFramework::
00981 event_window_event(CPT_Event event, void *data) {
00982   PandaFramework *self = (PandaFramework *)data;
00983   if (event->get_num_parameters() == 1) {
00984     // The parameter of the window event is the window itself, rather
00985     // than the window framework object (which is the parameter of all
00986     // of the keyboard events).
00987     EventParameter param = event->get_parameter(0);
00988     const GraphicsWindow *win;
00989     DCAST_INTO_V(win, param.get_ptr());
00990 
00991     // Is this a window we've heard about?
00992     int window_index = self->find_window(win);
00993     if (window_index == -1) {
00994       framework_cat.debug()
00995         << "Ignoring message from unknown window.\n";
00996     } else {
00997       if (!win->get_properties().get_open()) {
00998         // If the last window was closed, exit the application.
00999         if (self->all_windows_closed() && !self->_exit_flag) {
01000           framework_cat.info()
01001             << "Last window was closed by user.\n";
01002           self->_exit_flag = true;
01003         }
01004       }
01005     }
01006   }
01007 }

Generated on Fri May 2 00:38:53 2003 for Panda by doxygen1.3