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: Published
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: Published, Virtual
00091 //  Description: 
00092 ////////////////////////////////////////////////////////////////////
00093 AnimGroup::
00094 ~AnimGroup() {
00095 }
00096 
00097 
00098 ////////////////////////////////////////////////////////////////////
00099 //     Function: AnimGroup::get_num_children
00100 //       Access: Published
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: Published
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: Published
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: Published
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 // An STL object to sort a list of children into alphabetical order.
00168 class AnimGroupAlphabeticalOrder {
00169 public:
00170   bool operator()(const PT(AnimGroup) &a, const PT(AnimGroup) &b) const {
00171     return a->get_name() < b->get_name();
00172   }
00173 };
00174 
00175 ////////////////////////////////////////////////////////////////////
00176 //     Function: AnimGroup::sort_descendants
00177 //       Access: Published
00178 //  Description: Sorts the children nodes at each level of the
00179 //               hierarchy into alphabetical order.  This should be
00180 //               done after creating the hierarchy, to guarantee that
00181 //               the correct names will match up together when the
00182 //               AnimBundle is later bound to a PlayerRoot.
00183 ////////////////////////////////////////////////////////////////////
00184 void AnimGroup::
00185 sort_descendants() {
00186   sort(_children.begin(), _children.end(), AnimGroupAlphabeticalOrder());
00187 
00188   Children::iterator ci;
00189   for (ci = _children.begin(); ci != _children.end(); ++ci) {
00190     (*ci)->sort_descendants();
00191   }
00192 }
00193 
00194 
00195 ////////////////////////////////////////////////////////////////////
00196 //     Function: AnimGroup::get_value_type
00197 //       Access: Public, Virtual
00198 //  Description: Returns the TypeHandle associated with the ValueType
00199 //               we are concerned with.  This is provided to allow a
00200 //               bit of run-time checking that joints and channels are
00201 //               matching properly in type.
00202 ////////////////////////////////////////////////////////////////////
00203 TypeHandle AnimGroup::
00204 get_value_type() const {
00205   return TypeHandle::none();
00206 }
00207 
00208 ////////////////////////////////////////////////////////////////////
00209 //     Function: AnimGroup::output
00210 //       Access: Published, Virtual
00211 //  Description: Writes a one-line description of the group.
00212 ////////////////////////////////////////////////////////////////////
00213 void AnimGroup::
00214 output(ostream &out) const {
00215   out << get_type() << " " << get_name();
00216 }
00217 
00218 ////////////////////////////////////////////////////////////////////
00219 //     Function: AnimGroup::write
00220 //       Access: Published, Virtual
00221 //  Description: Writes a brief description of the group and all of
00222 //               its descendants.
00223 ////////////////////////////////////////////////////////////////////
00224 void AnimGroup::
00225 write(ostream &out, int indent_level) const {
00226   indent(out, indent_level) << *this;
00227   if (!_children.empty()) {
00228     out << " {\n";
00229     write_descendants(out, indent_level + 2);
00230     indent(out, indent_level) << "}";
00231   }
00232   out << "\n";
00233 }
00234 
00235 ////////////////////////////////////////////////////////////////////
00236 //     Function: AnimGroup::write_descendants
00237 //       Access: Protected
00238 //  Description: Writes a brief description of all of the group's
00239 //               descendants.
00240 ////////////////////////////////////////////////////////////////////
00241 void AnimGroup::
00242 write_descendants(ostream &out, int indent_level) const {
00243   Children::const_iterator ci;
00244 
00245   for (ci = _children.begin(); ci != _children.end(); ++ci) {
00246     (*ci)->write(out, indent_level);
00247   }
00248 }
00249 
00250 ////////////////////////////////////////////////////////////////////
00251 //     Function: AnimGroup::make_copy
00252 //       Access: Protected, Virtual
00253 //  Description: Returns a copy of this object, and attaches it to the
00254 //               indicated parent (which may be NULL only if this is
00255 //               an AnimBundle).  Intended to be called by
00256 //               copy_subtree() only.
00257 ////////////////////////////////////////////////////////////////////
00258 AnimGroup *AnimGroup::
00259 make_copy(AnimGroup *parent) const {
00260   return new AnimGroup(parent, *this);
00261 }
00262 
00263 
00264 ////////////////////////////////////////////////////////////////////
00265 //     Function: AnimGroup::copy_subtree
00266 //       Access: Protected
00267 //  Description: Returns a full copy of the subtree at this node and
00268 //               below.
00269 ////////////////////////////////////////////////////////////////////
00270 PT(AnimGroup) AnimGroup::
00271 copy_subtree(AnimGroup *parent) const {
00272   PT(AnimGroup) new_group = make_copy(parent);
00273   nassertr(new_group->get_type() == get_type(), (AnimGroup *)this);
00274 
00275   Children::const_iterator ci;
00276   for (ci = _children.begin(); ci != _children.end(); ++ci) {
00277     (*ci)->copy_subtree(new_group);
00278   }
00279 
00280   return new_group;
00281 }
00282 
00283 ////////////////////////////////////////////////////////////////////
00284 //     Function: AnimGroup::write_datagram
00285 //       Access: Public
00286 //  Description: Function to write the important information in
00287 //               the particular object to a Datagram
00288 ////////////////////////////////////////////////////////////////////
00289 void AnimGroup::
00290 write_datagram(BamWriter *manager, Datagram &me) {
00291   me.add_string(get_name());
00292   //Write out the root
00293   manager->write_pointer(me, this->_root);
00294   me.add_uint16(_children.size());
00295   for(int i = 0; i < (int)_children.size(); i++) {
00296     manager->write_pointer(me, _children[i]);
00297   }
00298 }
00299 
00300 ////////////////////////////////////////////////////////////////////
00301 //     Function: AnimGroup::fillin
00302 //       Access: Protected
00303 //  Description: Function that reads out of the datagram (or asks
00304 //               manager to read) all of the data that is needed to
00305 //               re-create this object and stores it in the appropiate
00306 //               place
00307 ////////////////////////////////////////////////////////////////////
00308 void AnimGroup::
00309 fillin(DatagramIterator &scan, BamReader *manager) {
00310   set_name(scan.get_string());
00311   manager->read_pointer(scan);
00312   _num_children = scan.get_uint16();
00313   for(int i = 0; i < _num_children; i++)
00314   {
00315     manager->read_pointer(scan);
00316   }
00317 }
00318 
00319 ////////////////////////////////////////////////////////////////////
00320 //     Function: AnimGroup::complete_pointers
00321 //       Access: Public
00322 //  Description: Takes in a vector of pointes to TypedWritable
00323 //               objects that correspond to all the requests for
00324 //               pointers that this object made to BamReader.
00325 ////////////////////////////////////////////////////////////////////
00326 int AnimGroup::
00327 complete_pointers(TypedWritable **p_list, BamReader *) {
00328   _root = DCAST(AnimBundle, p_list[0]);
00329   for (int i = 1; i < _num_children+1; i++) {
00330     if (p_list[i] == TypedWritable::Null) {
00331       chan_cat->warning() << get_type().get_name()
00332                           << " Ignoring null child" << endl;
00333     } else {
00334       _children.push_back(DCAST(AnimGroup, p_list[i]));
00335     }
00336   }
00337   return _num_children+1;
00338 }
00339 
00340 ////////////////////////////////////////////////////////////////////
00341 //     Function: AnimGroup::make_AnimGroup
00342 //       Access: Protected
00343 //  Description: Factory method to generate a AnimGroup object
00344 ////////////////////////////////////////////////////////////////////
00345 TypedWritable* AnimGroup::
00346 make_AnimGroup(const FactoryParams &params) {
00347   AnimGroup *me = new AnimGroup;
00348   DatagramIterator scan;
00349   BamReader *manager;
00350 
00351   parse_params(params, scan, manager);
00352   me->fillin(scan, manager);
00353   return me;
00354 }
00355 
00356 ////////////////////////////////////////////////////////////////////
00357 //     Function: AnimGroup::register_with_factory
00358 //       Access: Public, Static
00359 //  Description: Factory method to generate a AnimGroup object
00360 ////////////////////////////////////////////////////////////////////
00361 void AnimGroup::
00362 register_with_read_factory() {
00363   BamReader::get_factory()->register_factory(get_class_type(), make_AnimGroup);
00364 }
00365 
00366 
00367 
00368 
00369 
00370 
00371 
 All Classes Functions Variables Enumerations