Panda3D

animGroup.cxx

00001 // Filename: animGroup.cxx
00002 // Created by:  drose (21Feb99)
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 
00016 #include "animGroup.h"
00017 #include "animBundle.h"
00018 #include "config_chan.h"
00019 
00020 #include "indent.h"
00021 #include "datagram.h"
00022 #include "datagramIterator.h"
00023 #include "bamReader.h"
00024 #include "bamWriter.h"
00025 
00026 
00027 #include <algorithm>
00028 
00029 TypeHandle AnimGroup::_type_handle;
00030 
00031 
00032 ////////////////////////////////////////////////////////////////////
00033 //     Function: AnimGroup::Default Constructor
00034 //       Access: Protected
00035 //  Description: The default constructor is protected: don't try to
00036 //               create an AnimGroup without a parent.  To create an
00037 //               AnimChannel hierarchy, you must first create an
00038 //               AnimBundle, and use that to create any subsequent
00039 //               children.
00040 ////////////////////////////////////////////////////////////////////
00041 AnimGroup::
00042 AnimGroup(const string &name) : 
00043   Namable(name),
00044   _children(get_class_type()),
00045   _root(NULL)
00046 {
00047 }
00048 
00049 ////////////////////////////////////////////////////////////////////
00050 //     Function: AnimGroup::Copy Constructor
00051 //       Access: Protected
00052 //  Description: Creates a new AnimGroup, just like this one, without
00053 //               copying any children.  The new copy is added to the
00054 //               indicated parent.  Intended to be called by
00055 //               make_copy() only.
00056 ////////////////////////////////////////////////////////////////////
00057 AnimGroup::
00058 AnimGroup(AnimGroup *parent, const AnimGroup &copy) : 
00059   Namable(copy),
00060   _children(get_class_type())
00061 {
00062   if (parent != (AnimGroup *)NULL) {
00063     parent->_children.push_back(this);
00064     _root = parent->_root;
00065   } else {
00066     _root = NULL;
00067   }
00068 }
00069 
00070 ////////////////////////////////////////////////////////////////////
00071 //     Function: AnimGroup::Constructor
00072 //       Access: Public
00073 //  Description: Creates the AnimGroup, and adds it to the indicated
00074 //               parent.  The only way to delete it subsequently is to
00075 //               delete the entire hierarchy.
00076 ////////////////////////////////////////////////////////////////////
00077 AnimGroup::
00078 AnimGroup(AnimGroup *parent, const string &name) : 
00079   Namable(name),
00080   _children(get_class_type())
00081  {
00082   nassertv(parent != NULL);
00083 
00084   parent->_children.push_back(this);
00085   _root = parent->_root;
00086 }
00087 
00088 ////////////////////////////////////////////////////////////////////
00089 //     Function: AnimGroup::Destructor
00090 //       Access: Public, Virtual
00091 //  Description: 
00092 ////////////////////////////////////////////////////////////////////
00093 AnimGroup::
00094 ~AnimGroup() {
00095 }
00096 
00097 
00098 ////////////////////////////////////////////////////////////////////
00099 //     Function: AnimGroup::get_num_children
00100 //       Access: Public
00101 //  Description: Returns the number of child nodes of the group.
00102 ////////////////////////////////////////////////////////////////////
00103 int AnimGroup::
00104 get_num_children() const {
00105   return _children.size();
00106 }
00107 
00108 
00109 ////////////////////////////////////////////////////////////////////
00110 //     Function: AnimGroup::get_child
00111 //       Access: Public
00112 //  Description: Returns the nth child of the group.
00113 ////////////////////////////////////////////////////////////////////
00114 AnimGroup *AnimGroup::
00115 get_child(int n) const {
00116   nassertr(n >= 0 && n < (int)_children.size(), NULL);
00117   return _children[n];
00118 }
00119 
00120 ////////////////////////////////////////////////////////////////////
00121 //     Function: AnimGroup::get_child_named
00122 //       Access: Public
00123 //  Description: Returns the first child found with the indicated
00124 //               name, or NULL if no such child exists.  This method
00125 //               searches only the children of this particular
00126 //               AnimGroup; it does not recursively search the entire
00127 //               graph.  See also find_child().
00128 ////////////////////////////////////////////////////////////////////
00129 AnimGroup *AnimGroup::
00130 get_child_named(const string &name) const {
00131   Children::const_iterator ci;
00132   for (ci = _children.begin(); ci != _children.end(); ++ci) {
00133     AnimGroup *child = (*ci);
00134     if (child->get_name() == name) {
00135       return child;
00136     }
00137   }
00138 
00139   return (AnimGroup *)NULL;
00140 }
00141 
00142 ////////////////////////////////////////////////////////////////////
00143 //     Function: AnimGroup::find_child
00144 //       Access: Public
00145 //  Description: Returns the first descendant found with the indicated
00146 //               name, or NULL if no such descendant exists.  This
00147 //               method searches the entire graph beginning at this
00148 //               AnimGroup; see also get_child_named().
00149 ////////////////////////////////////////////////////////////////////
00150 AnimGroup *AnimGroup::
00151 find_child(const string &name) const {
00152   Children::const_iterator ci;
00153   for (ci = _children.begin(); ci != _children.end(); ++ci) {
00154     AnimGroup *child = (*ci);
00155     if (child->get_name() == name) {
00156       return child;
00157     }
00158     AnimGroup *result = child->find_child(name);
00159     if (result != (AnimGroup *)NULL) {
00160       return result;
00161     }
00162   }
00163 
00164   return (AnimGroup *)NULL;
00165 }
00166 
00167 ////////////////////////////////////////////////////////////////////
00168 //     Function: AnimGroup::get_value_type
00169 //       Access: Public, Virtual
00170 //  Description: Returns the TypeHandle associated with the ValueType
00171 //               we are concerned with.  This is provided to allow a
00172 //               bit of run-time checking that joints and channels are
00173 //               matching properly in type.
00174 ////////////////////////////////////////////////////////////////////
00175 TypeHandle AnimGroup::
00176 get_value_type() const {
00177   return TypeHandle::none();
00178 }
00179 
00180 
00181 // An STL object to sort a list of children into alphabetical order.
00182 class AnimGroupAlphabeticalOrder {
00183 public:
00184   bool operator()(const PT(AnimGroup) &a, const PT(AnimGroup) &b) const {
00185     return a->get_name() < b->get_name();
00186   }
00187 };
00188 
00189 ////////////////////////////////////////////////////////////////////
00190 //     Function: AnimGroup::sort_descendants
00191 //       Access: Public
00192 //  Description: Sorts the children nodes at each level of the
00193 //               hierarchy into alphabetical order.  This should be
00194 //               done after creating the hierarchy, to guarantee that
00195 //               the correct names will match up together when the
00196 //               AnimBundle is later bound to a PlayerRoot.
00197 ////////////////////////////////////////////////////////////////////
00198 void AnimGroup::
00199 sort_descendants() {
00200   sort(_children.begin(), _children.end(), AnimGroupAlphabeticalOrder());
00201 
00202   Children::iterator ci;
00203   for (ci = _children.begin(); ci != _children.end(); ++ci) {
00204     (*ci)->sort_descendants();
00205   }
00206 }
00207 
00208 
00209 ////////////////////////////////////////////////////////////////////
00210 //     Function: AnimGroup::output
00211 //       Access: Public, Virtual
00212 //  Description: Writes a one-line description of the group.
00213 ////////////////////////////////////////////////////////////////////
00214 void AnimGroup::
00215 output(ostream &out) const {
00216   out << get_type() << " " << get_name();
00217 }
00218 
00219 ////////////////////////////////////////////////////////////////////
00220 //     Function: AnimGroup::write
00221 //       Access: Public, Virtual
00222 //  Description: Writes a brief description of the group and all of
00223 //               its descendants.
00224 ////////////////////////////////////////////////////////////////////
00225 void AnimGroup::
00226 write(ostream &out, int indent_level) const {
00227   indent(out, indent_level) << *this;
00228   if (!_children.empty()) {
00229     out << " {\n";
00230     write_descendants(out, indent_level + 2);
00231     indent(out, indent_level) << "}";
00232   }
00233   out << "\n";
00234 }
00235 
00236 ////////////////////////////////////////////////////////////////////
00237 //     Function: AnimGroup::write_descendants
00238 //       Access: Protected
00239 //  Description: Writes a brief description of all of the group's
00240 //               descendants.
00241 ////////////////////////////////////////////////////////////////////
00242 void AnimGroup::
00243 write_descendants(ostream &out, int indent_level) const {
00244   Children::const_iterator ci;
00245 
00246   for (ci = _children.begin(); ci != _children.end(); ++ci) {
00247     (*ci)->write(out, indent_level);
00248   }
00249 }
00250 
00251 ////////////////////////////////////////////////////////////////////
00252 //     Function: AnimGroup::make_copy
00253 //       Access: Protected, Virtual
00254 //  Description: Returns a copy of this object, and attaches it to the
00255 //               indicated parent (which may be NULL only if this is
00256 //               an AnimBundle).  Intended to be called by
00257 //               copy_subtree() only.
00258 ////////////////////////////////////////////////////////////////////
00259 AnimGroup *AnimGroup::
00260 make_copy(AnimGroup *parent) const {
00261   return new AnimGroup(parent, *this);
00262 }
00263 
00264 
00265 ////////////////////////////////////////////////////////////////////
00266 //     Function: AnimGroup::copy_subtree
00267 //       Access: Protected
00268 //  Description: Returns a full copy of the subtree at this node and
00269 //               below.
00270 ////////////////////////////////////////////////////////////////////
00271 PT(AnimGroup) AnimGroup::
00272 copy_subtree(AnimGroup *parent) const {
00273   PT(AnimGroup) new_group = make_copy(parent);
00274   nassertr(new_group->get_type() == get_type(), (AnimGroup *)this);
00275 
00276   Children::const_iterator ci;
00277   for (ci = _children.begin(); ci != _children.end(); ++ci) {
00278     (*ci)->copy_subtree(new_group);
00279   }
00280 
00281   return new_group;
00282 }
00283 
00284 ////////////////////////////////////////////////////////////////////
00285 //     Function: AnimGroup::write_datagram
00286 //       Access: Public
00287 //  Description: Function to write the important information in
00288 //               the particular object to a Datagram
00289 ////////////////////////////////////////////////////////////////////
00290 void AnimGroup::
00291 write_datagram(BamWriter *manager, Datagram &me) {
00292   me.add_string(get_name());
00293   //Write out the root
00294   manager->write_pointer(me, this->_root);
00295   me.add_uint16(_children.size());
00296   for(int i = 0; i < (int)_children.size(); i++) {
00297     manager->write_pointer(me, _children[i]);
00298   }
00299 }
00300 
00301 ////////////////////////////////////////////////////////////////////
00302 //     Function: AnimGroup::fillin
00303 //       Access: Protected
00304 //  Description: Function that reads out of the datagram (or asks
00305 //               manager to read) all of the data that is needed to
00306 //               re-create this object and stores it in the appropiate
00307 //               place
00308 ////////////////////////////////////////////////////////////////////
00309 void AnimGroup::
00310 fillin(DatagramIterator &scan, BamReader *manager) {
00311   set_name(scan.get_string());
00312   manager->read_pointer(scan);
00313   _num_children = scan.get_uint16();
00314   for(int i = 0; i < _num_children; i++)
00315   {
00316     manager->read_pointer(scan);
00317   }
00318 }
00319 
00320 ////////////////////////////////////////////////////////////////////
00321 //     Function: AnimGroup::complete_pointers
00322 //       Access: Public
00323 //  Description: Takes in a vector of pointes to TypedWritable
00324 //               objects that correspond to all the requests for
00325 //               pointers that this object made to BamReader.
00326 ////////////////////////////////////////////////////////////////////
00327 int AnimGroup::
00328 complete_pointers(TypedWritable **p_list, BamReader *) {
00329   _root = DCAST(AnimBundle, p_list[0]);
00330   for (int i = 1; i < _num_children+1; i++) {
00331     if (p_list[i] == TypedWritable::Null) {
00332       chan_cat->warning() << get_type().get_name()
00333                           << " Ignoring null child" << endl;
00334     } else {
00335       _children.push_back(DCAST(AnimGroup, p_list[i]));
00336     }
00337   }
00338   return _num_children+1;
00339 }
00340 
00341 ////////////////////////////////////////////////////////////////////
00342 //     Function: AnimGroup::make_AnimGroup
00343 //       Access: Protected
00344 //  Description: Factory method to generate a AnimGroup object
00345 ////////////////////////////////////////////////////////////////////
00346 TypedWritable* AnimGroup::
00347 make_AnimGroup(const FactoryParams &params) {
00348   AnimGroup *me = new AnimGroup;
00349   DatagramIterator scan;
00350   BamReader *manager;
00351 
00352   parse_params(params, scan, manager);
00353   me->fillin(scan, manager);
00354   return me;
00355 }
00356 
00357 ////////////////////////////////////////////////////////////////////
00358 //     Function: AnimGroup::register_with_factory
00359 //       Access: Public, Static
00360 //  Description: Factory method to generate a AnimGroup object
00361 ////////////////////////////////////////////////////////////////////
00362 void AnimGroup::
00363 register_with_read_factory() {
00364   BamReader::get_factory()->register_factory(get_class_type(), make_AnimGroup);
00365 }
00366 
00367 
00368 
00369 
00370 
00371 
00372 
 All Classes Functions Variables Enumerations