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

panda/src/chan/movingPartBase.cxx

Go to the documentation of this file.
00001 // Filename: movingPartBase.cxx
00002 // Created by:  drose (22Feb99)
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 
00020 #include "movingPartBase.h"
00021 #include "animControl.h"
00022 #include "animChannelBase.h"
00023 
00024 #include <indent.h>
00025 
00026 TypeHandle MovingPartBase::_type_handle;
00027 
00028 
00029 ////////////////////////////////////////////////////////////////////
00030 //     Function: MovingPartBase::Constructor
00031 //       Access: Public
00032 //  Description:
00033 ////////////////////////////////////////////////////////////////////
00034 MovingPartBase::
00035 MovingPartBase(PartGroup *parent, const string &name)
00036   : PartGroup(parent, name) {
00037 }
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: MovingPartBase::Constructor
00041 //       Access: Protected
00042 //  Description:
00043 ////////////////////////////////////////////////////////////////////
00044 MovingPartBase::
00045 MovingPartBase(void){
00046 }
00047 
00048 ////////////////////////////////////////////////////////////////////
00049 //     Function: MovingPartBase::write
00050 //       Access: Public, Virtual
00051 //  Description: Writes a brief description of the channel and all of
00052 //               its descendants.
00053 ////////////////////////////////////////////////////////////////////
00054 void MovingPartBase::
00055 write(ostream &out, int indent_level) const {
00056   indent(out, indent_level) << get_value_type() << " " << get_name();
00057   if (_children.empty()) {
00058     out << "\n";
00059   } else {
00060     out << " {\n";
00061     write_descendants(out, indent_level + 2);
00062     indent(out, indent_level) << "}\n";
00063   }
00064 }
00065 
00066 ////////////////////////////////////////////////////////////////////
00067 //     Function: MovingPartBase::write_with_value
00068 //       Access: Public, Virtual
00069 //  Description: Writes a brief description of the channel and all of
00070 //               its descendants, along with their values.
00071 ////////////////////////////////////////////////////////////////////
00072 void MovingPartBase::
00073 write_with_value(ostream &out, int indent_level) const {
00074   indent(out, indent_level) << get_value_type() << " " << get_name() << "\n";
00075   indent(out, indent_level);
00076   output_value(out);
00077 
00078   if (_children.empty()) {
00079     out << "\n";
00080   } else {
00081     out << " {\n";
00082     write_descendants_with_value(out, indent_level + 2);
00083     indent(out, indent_level) << "}\n";
00084   }
00085 }
00086 
00087 ////////////////////////////////////////////////////////////////////
00088 //     Function: MovingPartBase::do_update
00089 //       Access: Public, Virtual
00090 //  Description: Recursively update this particular part and all of
00091 //               its descendents for the current frame.  This is not
00092 //               really public and is not intended to be called
00093 //               directly; it is called from the top of the tree by
00094 //               PartBundle::update().
00095 //
00096 //               The return value is true if any part has changed,
00097 //               false otherwise.
00098 ////////////////////////////////////////////////////////////////////
00099 bool MovingPartBase::
00100 do_update(PartBundle *root, PartGroup *parent,
00101           bool parent_changed, bool anim_changed) {
00102   bool any_changed = false;
00103   bool needs_update = anim_changed;
00104 
00105   // See if any of the channel values have changed since last time.
00106 
00107   PartBundle::control_iterator bci;
00108   for (bci = root->control_begin();
00109        !needs_update && bci != root->control_end();
00110        ++bci) {
00111     AnimControl *control = (*bci);
00112     int channel_index = control->get_channel_index();
00113     nassertr(channel_index >= 0 && channel_index < (int)_channels.size(), false);
00114     AnimChannelBase *channel = _channels[channel_index];
00115     nassertr(channel != (AnimChannelBase*)0L, false);
00116 
00117     needs_update = control->channel_has_changed(channel);
00118   }
00119 
00120   if (needs_update) {
00121     // Ok, get the latest value.
00122     get_blend_value(root);
00123   }
00124 
00125   if (parent_changed || needs_update) {
00126     any_changed = update_internals(parent, needs_update, parent_changed);
00127   }
00128 
00129   // Now recurse.
00130   Children::iterator ci;
00131   for (ci = _children.begin(); ci != _children.end(); ++ci) {
00132     if ((*ci)->do_update(root, this, parent_changed || needs_update,
00133                          anim_changed)) {
00134       any_changed = true;
00135     }
00136   }
00137 
00138   return any_changed;
00139 }
00140 
00141 
00142 ////////////////////////////////////////////////////////////////////
00143 //     Function: MovingPartBase::update_internals
00144 //       Access: Public, Virtual
00145 //  Description: This is called by do_update() whenever the part or
00146 //               some ancestor has changed values.  It is a hook for
00147 //               derived classes to update whatever cache they may
00148 //               have that depends on these.
00149 //
00150 //               The return value is true if the part has changed as a
00151 //               result of the update, or false otherwise.
00152 ////////////////////////////////////////////////////////////////////
00153 bool MovingPartBase::
00154 update_internals(PartGroup *, bool, bool) {
00155   return false;
00156 }
00157 
00158 ////////////////////////////////////////////////////////////////////
00159 //     Function: MovingPartBase::pick_channel_index
00160 //       Access: Protected
00161 //  Description: Walks the part hierarchy, looking for a suitable
00162 //               channel index number to use.  Available index numbers
00163 //               are the elements of the holes set, as well as next to
00164 //               infinity.
00165 ////////////////////////////////////////////////////////////////////
00166 void MovingPartBase::
00167 pick_channel_index(plist<int> &holes, int &next) const {
00168   // Verify each of the holes.
00169 
00170   plist<int>::iterator ii, ii_next;
00171   ii = holes.begin();
00172   while (ii != holes.end()) {
00173     ii_next = ii;
00174     ++ii_next;
00175 
00176     int hole = (*ii);
00177     nassertv(hole >= 0 && hole < next);
00178     if (hole < (int)_channels.size() ||
00179         _channels[hole] != (AnimChannelBase *)NULL) {
00180       // We can't accept this hole; we're using it!
00181       holes.erase(ii);
00182     }
00183     ii = ii_next;
00184   }
00185 
00186   // Now do we have any more to restrict?
00187   if (next < (int)_channels.size()) {
00188     int i;
00189     for (i = next; i < (int)_channels.size(); i++) {
00190       if (_channels[i] == (AnimChannelBase*)0L) {
00191         // Here's a hole we do have.
00192         holes.push_back(i);
00193       }
00194     }
00195     next = _channels.size();
00196   }
00197 
00198   PartGroup::pick_channel_index(holes, next);
00199 }
00200 
00201 
00202 
00203 ////////////////////////////////////////////////////////////////////
00204 //     Function: MovingPartBase::bind_hierarchy
00205 //       Access: Protected, Virtual
00206 //  Description: Binds the indicated anim hierarchy to the part
00207 //               hierarchy, at the given channel index number.
00208 ////////////////////////////////////////////////////////////////////
00209 void MovingPartBase::
00210 bind_hierarchy(AnimGroup *anim, int channel_index) {
00211   while ((int)_channels.size() <= channel_index) {
00212     _channels.push_back((AnimChannelBase*)0L);
00213   }
00214 
00215   nassertv(_channels[channel_index] == (AnimChannelBase*)0L);
00216 
00217   if (anim == (AnimGroup*)0L) {
00218     // If we're binding to the NULL anim, it means actually to create
00219     // a default AnimChannel that just returns the part's initial
00220     // value.
00221     _channels[channel_index] = make_initial_channel();
00222   } else {
00223     _channels[channel_index] = DCAST(AnimChannelBase, anim);
00224   }
00225 
00226   PartGroup::bind_hierarchy(anim, channel_index);
00227 }

Generated on Fri May 2 00:35:08 2003 for Panda by doxygen1.3