00001 // Filename: animGroup.cxx 00002 // Created by: drose (21Feb99) 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 "animGroup.h" 00021 #include "animBundle.h" 00022 #include "config_chan.h" 00023 00024 #include <indent.h> 00025 #include <datagram.h> 00026 #include <datagramIterator.h> 00027 #include <bamReader.h> 00028 #include <bamWriter.h> 00029 00030 00031 #include <algorithm> 00032 00033 TypeHandle AnimGroup::_type_handle; 00034 00035 00036 //////////////////////////////////////////////////////////////////// 00037 // Function: AnimGroup::Constructor 00038 // Access: Public 00039 // Description: Creates the AnimGroup, and adds it to the indicated 00040 // parent. The only way to delete it subsequently is to 00041 // delete the entire hierarchy. 00042 //////////////////////////////////////////////////////////////////// 00043 AnimGroup:: 00044 AnimGroup(AnimGroup *parent, const string &name) : Namable(name) { 00045 nassertv(parent != NULL); 00046 00047 parent->_children.push_back(this); 00048 _root = parent->_root; 00049 } 00050 00051 00052 //////////////////////////////////////////////////////////////////// 00053 // Function: AnimGroup::get_num_children 00054 // Access: Public 00055 // Description: Returns the number of child nodes of the group. 00056 //////////////////////////////////////////////////////////////////// 00057 int AnimGroup:: 00058 get_num_children() const { 00059 return _children.size(); 00060 } 00061 00062 00063 //////////////////////////////////////////////////////////////////// 00064 // Function: AnimGroup::get_child 00065 // Access: Public 00066 // Description: Returns the nth child of the group. 00067 //////////////////////////////////////////////////////////////////// 00068 AnimGroup *AnimGroup:: 00069 get_child(int n) const { 00070 nassertr(n >= 0 && n < (int)_children.size(), NULL); 00071 return _children[n]; 00072 } 00073 00074 //////////////////////////////////////////////////////////////////// 00075 // Function: AnimGroup::find_child 00076 // Access: Public 00077 // Description: Returns the first descendant found with the indicated 00078 // name, or NULL if no such descendant exists. 00079 //////////////////////////////////////////////////////////////////// 00080 AnimGroup *AnimGroup:: 00081 find_child(const string &name) const { 00082 Children::const_iterator ci; 00083 for (ci = _children.begin(); ci != _children.end(); ++ci) { 00084 AnimGroup *child = (*ci); 00085 if (child->get_name() == name) { 00086 return child; 00087 } 00088 AnimGroup *result = child->find_child(name); 00089 if (result != (AnimGroup *)NULL) { 00090 return result; 00091 } 00092 } 00093 00094 return (AnimGroup *)NULL; 00095 } 00096 00097 //////////////////////////////////////////////////////////////////// 00098 // Function: AnimGroup::get_value_type 00099 // Access: Public, Virtual 00100 // Description: Returns the TypeHandle associated with the ValueType 00101 // we are concerned with. This is provided to allow a 00102 // bit of run-time checking that joints and channels are 00103 // matching properly in type. 00104 //////////////////////////////////////////////////////////////////// 00105 TypeHandle AnimGroup:: 00106 get_value_type() const { 00107 return TypeHandle::none(); 00108 } 00109 00110 00111 // An STL object to sort a list of children into alphabetical order. 00112 class AnimGroupAlphabeticalOrder { 00113 public: 00114 bool operator()(const PT(AnimGroup) &a, const PT(AnimGroup) &b) const { 00115 return a->get_name() < b->get_name(); 00116 } 00117 }; 00118 00119 //////////////////////////////////////////////////////////////////// 00120 // Function: AnimGroup::sort_descendants 00121 // Access: Public 00122 // Description: Sorts the children nodes at each level of the 00123 // hierarchy into alphabetical order. This should be 00124 // done after creating the hierarchy, to guarantee that 00125 // the correct names will match up together when the 00126 // AnimBundle is later bound to a PlayerRoot. 00127 //////////////////////////////////////////////////////////////////// 00128 void AnimGroup:: 00129 sort_descendants() { 00130 sort(_children.begin(), _children.end(), AnimGroupAlphabeticalOrder()); 00131 00132 Children::iterator ci; 00133 for (ci = _children.begin(); ci != _children.end(); ++ci) { 00134 (*ci)->sort_descendants(); 00135 } 00136 } 00137 00138 00139 //////////////////////////////////////////////////////////////////// 00140 // Function: AnimGroup::output 00141 // Access: Public, Virtual 00142 // Description: Writes a one-line description of the group. 00143 //////////////////////////////////////////////////////////////////// 00144 void AnimGroup:: 00145 output(ostream &out) const { 00146 out << get_type() << " " << get_name(); 00147 } 00148 00149 //////////////////////////////////////////////////////////////////// 00150 // Function: AnimGroup::write 00151 // Access: Public, Virtual 00152 // Description: Writes a brief description of the group and all of 00153 // its descendants. 00154 //////////////////////////////////////////////////////////////////// 00155 void AnimGroup:: 00156 write(ostream &out, int indent_level) const { 00157 indent(out, indent_level) << *this << " {\n"; 00158 write_descendants(out, indent_level + 2); 00159 indent(out, indent_level) << "}\n"; 00160 } 00161 00162 //////////////////////////////////////////////////////////////////// 00163 // Function: AnimGroup::write_descendants 00164 // Access: Protected 00165 // Description: Writes a brief description of all of the group's 00166 // descendants. 00167 //////////////////////////////////////////////////////////////////// 00168 void AnimGroup:: 00169 write_descendants(ostream &out, int indent_level) const { 00170 Children::const_iterator ci; 00171 00172 for (ci = _children.begin(); ci != _children.end(); ++ci) { 00173 (*ci)->write(out, indent_level); 00174 } 00175 } 00176 00177 //////////////////////////////////////////////////////////////////// 00178 // Function: AnimGroup::write_datagram 00179 // Access: Public 00180 // Description: Function to write the important information in 00181 // the particular object to a Datagram 00182 //////////////////////////////////////////////////////////////////// 00183 void AnimGroup:: 00184 write_datagram(BamWriter *manager, Datagram &me) 00185 { 00186 me.add_string(get_name()); 00187 //Write out the root 00188 manager->write_pointer(me, this->_root); 00189 me.add_uint16(_children.size()); 00190 for(int i = 0; i < (int)_children.size(); i++) 00191 { 00192 manager->write_pointer(me, _children[i]); 00193 } 00194 } 00195 00196 //////////////////////////////////////////////////////////////////// 00197 // Function: AnimGroup::fillin 00198 // Access: Protected 00199 // Description: Function that reads out of the datagram (or asks 00200 // manager to read) all of the data that is needed to 00201 // re-create this object and stores it in the appropiate 00202 // place 00203 //////////////////////////////////////////////////////////////////// 00204 void AnimGroup:: 00205 fillin(DatagramIterator& scan, BamReader* manager) 00206 { 00207 set_name(scan.get_string()); 00208 manager->read_pointer(scan); 00209 _num_children = scan.get_uint16(); 00210 for(int i = 0; i < _num_children; i++) 00211 { 00212 manager->read_pointer(scan); 00213 } 00214 } 00215 00216 //////////////////////////////////////////////////////////////////// 00217 // Function: AnimGroup::complete_pointers 00218 // Access: Public 00219 // Description: Takes in a vector of pointes to TypedWritable 00220 // objects that correspond to all the requests for 00221 // pointers that this object made to BamReader. 00222 //////////////////////////////////////////////////////////////////// 00223 int AnimGroup:: 00224 complete_pointers(TypedWritable **p_list, BamReader*) 00225 { 00226 nassertr(p_list[0] != TypedWritable::Null, 0); 00227 _root = DCAST(AnimBundle, p_list[0]); 00228 for(int i = 1; i < _num_children+1; i++) 00229 { 00230 if (p_list[i] == TypedWritable::Null) 00231 { 00232 chan_cat->warning() << get_type().get_name() 00233 << " Ignoring null child" << endl; 00234 } 00235 else 00236 { 00237 _children.push_back(DCAST(AnimGroup, p_list[i])); 00238 } 00239 } 00240 return _num_children+1; 00241 } 00242 00243 //////////////////////////////////////////////////////////////////// 00244 // Function: AnimGroup::make_AnimGroup 00245 // Access: Protected 00246 // Description: Factory method to generate a AnimGroup object 00247 //////////////////////////////////////////////////////////////////// 00248 TypedWritable* AnimGroup:: 00249 make_AnimGroup(const FactoryParams ¶ms) 00250 { 00251 AnimGroup *me = new AnimGroup; 00252 DatagramIterator scan; 00253 BamReader *manager; 00254 00255 parse_params(params, scan, manager); 00256 me->fillin(scan, manager); 00257 return me; 00258 } 00259 00260 //////////////////////////////////////////////////////////////////// 00261 // Function: AnimGroup::register_with_factory 00262 // Access: Public, Static 00263 // Description: Factory method to generate a AnimGroup object 00264 //////////////////////////////////////////////////////////////////// 00265 void AnimGroup:: 00266 register_with_read_factory(void) 00267 { 00268 BamReader::get_factory()->register_factory(get_class_type(), make_AnimGroup); 00269 } 00270 00271 00272 00273 00274 00275 00276