Panda3D
 All Classes Functions Variables Enumerations
pgTop.cxx
00001 // Filename: pgTop.cxx
00002 // Created by:  drose (13Mar02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "pgTop.h"
00016 #include "pgMouseWatcherGroup.h"
00017 #include "pgCullTraverser.h"
00018 #include "cullBinAttrib.h"
00019 
00020 #include "omniBoundingVolume.h"
00021 
00022 TypeHandle PGTop::_type_handle;
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //     Function: PGTop::Constructor
00026 //       Access: Published
00027 //  Description: 
00028 ////////////////////////////////////////////////////////////////////
00029 PGTop::
00030 PGTop(const string &name) : 
00031   PandaNode(name)
00032 {
00033   set_cull_callback();
00034 
00035   _start_sort = 0;
00036 
00037   // A PGTop node normally has an infinite bounding volume.  Screw
00038   // culling.
00039   set_internal_bounds(new OmniBoundingVolume());
00040   set_final(true);
00041 
00042   // Also, screw state sorting.  By default, everything under PGTop
00043   // will be unsorted: rendered in scene graph order.  This is closer
00044   // to what the user wants anyway in a 2-d scene graph.
00045 
00046   set_attrib(CullBinAttrib::make("unsorted", 0));
00047 }
00048 
00049 ////////////////////////////////////////////////////////////////////
00050 //     Function: PGTop::Destructor
00051 //       Access: Public, Virtual
00052 //  Description: 
00053 ////////////////////////////////////////////////////////////////////
00054 PGTop::
00055 ~PGTop() {
00056   set_mouse_watcher((MouseWatcher *)NULL);
00057 }
00058 
00059 ////////////////////////////////////////////////////////////////////
00060 //     Function: PGTop::make_copy
00061 //       Access: Protected, Virtual
00062 //  Description: Returns a newly-allocated Node that is a shallow copy
00063 //               of this one.  It will be a different Node pointer,
00064 //               but its internal data may or may not be shared with
00065 //               that of the original Node.
00066 ////////////////////////////////////////////////////////////////////
00067 PandaNode *PGTop::
00068 make_copy() const {
00069   return new PGTop(*this);
00070 }
00071 
00072 ////////////////////////////////////////////////////////////////////
00073 //     Function: PGTop::cull_callback
00074 //       Access: Protected, Virtual
00075 //  Description: This function will be called during the cull
00076 //               traversal to perform any additional operations that
00077 //               should be performed at cull time.  This may include
00078 //               additional manipulation of render state or additional
00079 //               visible/invisible decisions, or any other arbitrary
00080 //               operation.
00081 //
00082 //               Note that this function will *not* be called unless
00083 //               set_cull_callback() is called in the constructor of
00084 //               the derived class.  It is necessary to call
00085 //               set_cull_callback() to indicated that we require
00086 //               cull_callback() to be called.
00087 //
00088 //               By the time this function is called, the node has
00089 //               already passed the bounding-volume test for the
00090 //               viewing frustum, and the node's transform and state
00091 //               have already been applied to the indicated
00092 //               CullTraverserData object.
00093 //
00094 //               The return value is true if this node should be
00095 //               visible, or false if it should be culled.
00096 ////////////////////////////////////////////////////////////////////
00097 bool PGTop::
00098 cull_callback(CullTraverser *trav, CullTraverserData &data) {
00099   // We create a new MouseWatcherGroup for the purposes of collecting
00100   // a new set of regions visible onscreen.
00101   PT(PGMouseWatcherGroup) old_watcher_group;
00102   if (_watcher_group != (PGMouseWatcherGroup *)NULL) {
00103     _watcher_group->clear_top(this);
00104     old_watcher_group = _watcher_group;
00105     _watcher_group = new PGMouseWatcherGroup(this);
00106   }
00107 
00108   // Now subsitute for the normal CullTraverser a special one of our
00109   // own choosing.  This just carries around a pointer back to the
00110   // PGTop node, for the convenience of PGItems to register themselves
00111   // as they are drawn.
00112   PGCullTraverser pg_trav(this, trav);
00113   pg_trav.local_object();
00114   pg_trav._sort_index = _start_sort;
00115   pg_trav.traverse_below(data);
00116   pg_trav.end_traverse();
00117 
00118   // Now tell the watcher about the new set of regions.  Strictly
00119   // speaking, we shouldn't do this until the frame that we're about
00120   // to render has been presented; otherwise, we may make regions
00121   // active before they are actually visible.  But no one has
00122   // complained about this so far.
00123   if (_watcher_group != (PGMouseWatcherGroup *)NULL) {
00124     nassertr(_watcher != (MouseWatcher *)NULL, false);
00125     _watcher->replace_group(old_watcher_group, _watcher_group);
00126   }
00127 
00128   // We've taken care of the traversal, thank you.
00129   return false;
00130 }
00131 
00132 ////////////////////////////////////////////////////////////////////
00133 //     Function: PGTop::is_renderable
00134 //       Access: Public, Virtual
00135 //  Description: Returns true if there is some value to visiting this
00136 //               particular node during the cull traversal for any
00137 //               camera, false otherwise.  This will be used to
00138 //               optimize the result of get_net_draw_show_mask(), so
00139 //               that any subtrees that contain only nodes for which
00140 //               is_renderable() is false need not be visited.
00141 ////////////////////////////////////////////////////////////////////
00142 bool PGTop::
00143 is_renderable() const {
00144   // We flag the PGTop as renderable, even though it technically
00145   // doesn't have anything to render, but we do need the traverser to
00146   // visit it every frame.
00147   return true;
00148 }
00149 
00150 ////////////////////////////////////////////////////////////////////
00151 //     Function: PGTop::set_mouse_watcher
00152 //       Access: Published
00153 //  Description: Sets the MouseWatcher pointer that the PGTop object
00154 //               registers its PG items with.  This must be set before
00155 //               the PG items are active.
00156 ////////////////////////////////////////////////////////////////////
00157 void PGTop::
00158 set_mouse_watcher(MouseWatcher *watcher) {
00159   if (_watcher_group != (PGMouseWatcherGroup *)NULL) {
00160     _watcher_group->clear_top(this);
00161   }
00162   if (_watcher != (MouseWatcher *)NULL) {
00163     _watcher->remove_group(_watcher_group);
00164   }
00165 
00166   _watcher = watcher;
00167   _watcher_group = (PGMouseWatcherGroup *)NULL;
00168 
00169   if (_watcher != (MouseWatcher *)NULL) {
00170     _watcher_group = new PGMouseWatcherGroup(this);
00171     _watcher->add_group(_watcher_group);
00172   }
00173 }
 All Classes Functions Variables Enumerations