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