Panda3D
|
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 ©) : 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 ¶ms) { 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