Panda3D
 All Classes Functions Variables Enumerations
animGroup.cxx
1 // Filename: animGroup.cxx
2 // Created by: drose (21Feb99)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 #include "animGroup.h"
17 #include "animBundle.h"
18 #include "config_chan.h"
19 
20 #include "indent.h"
21 #include "datagram.h"
22 #include "datagramIterator.h"
23 #include "bamReader.h"
24 #include "bamWriter.h"
25 
26 
27 #include <algorithm>
28 
29 TypeHandle AnimGroup::_type_handle;
30 
31 
32 ////////////////////////////////////////////////////////////////////
33 // Function: AnimGroup::Default Constructor
34 // Access: Protected
35 // Description: The default constructor is protected: don't try to
36 // create an AnimGroup without a parent. To create an
37 // AnimChannel hierarchy, you must first create an
38 // AnimBundle, and use that to create any subsequent
39 // children.
40 ////////////////////////////////////////////////////////////////////
41 AnimGroup::
42 AnimGroup(const string &name) :
43  Namable(name),
44  _children(get_class_type()),
45  _root(NULL)
46 {
47 }
48 
49 ////////////////////////////////////////////////////////////////////
50 // Function: AnimGroup::Copy Constructor
51 // Access: Protected
52 // Description: Creates a new AnimGroup, just like this one, without
53 // copying any children. The new copy is added to the
54 // indicated parent. Intended to be called by
55 // make_copy() only.
56 ////////////////////////////////////////////////////////////////////
57 AnimGroup::
58 AnimGroup(AnimGroup *parent, const AnimGroup &copy) :
59  Namable(copy),
60  _children(get_class_type())
61 {
62  if (parent != (AnimGroup *)NULL) {
63  parent->_children.push_back(this);
64  _root = parent->_root;
65  } else {
66  _root = NULL;
67  }
68 }
69 
70 ////////////////////////////////////////////////////////////////////
71 // Function: AnimGroup::Constructor
72 // Access: Published
73 // Description: Creates the AnimGroup, and adds it to the indicated
74 // parent. The only way to delete it subsequently is to
75 // delete the entire hierarchy.
76 ////////////////////////////////////////////////////////////////////
77 AnimGroup::
78 AnimGroup(AnimGroup *parent, const string &name) :
79  Namable(name),
80  _children(get_class_type())
81  {
82  nassertv(parent != NULL);
83 
84  parent->_children.push_back(this);
85  _root = parent->_root;
86 }
87 
88 ////////////////////////////////////////////////////////////////////
89 // Function: AnimGroup::Destructor
90 // Access: Published, Virtual
91 // Description:
92 ////////////////////////////////////////////////////////////////////
93 AnimGroup::
94 ~AnimGroup() {
95 }
96 
97 
98 ////////////////////////////////////////////////////////////////////
99 // Function: AnimGroup::get_num_children
100 // Access: Published
101 // Description: Returns the number of child nodes of the group.
102 ////////////////////////////////////////////////////////////////////
103 int AnimGroup::
105  return _children.size();
106 }
107 
108 
109 ////////////////////////////////////////////////////////////////////
110 // Function: AnimGroup::get_child
111 // Access: Published
112 // Description: Returns the nth child of the group.
113 ////////////////////////////////////////////////////////////////////
115 get_child(int n) const {
116  nassertr(n >= 0 && n < (int)_children.size(), NULL);
117  return _children[n];
118 }
119 
120 ////////////////////////////////////////////////////////////////////
121 // Function: AnimGroup::get_child_named
122 // Access: Published
123 // Description: Returns the first child found with the indicated
124 // name, or NULL if no such child exists. This method
125 // searches only the children of this particular
126 // AnimGroup; it does not recursively search the entire
127 // graph. See also find_child().
128 ////////////////////////////////////////////////////////////////////
130 get_child_named(const string &name) const {
131  Children::const_iterator ci;
132  for (ci = _children.begin(); ci != _children.end(); ++ci) {
133  AnimGroup *child = (*ci);
134  if (child->get_name() == name) {
135  return child;
136  }
137  }
138 
139  return (AnimGroup *)NULL;
140 }
141 
142 ////////////////////////////////////////////////////////////////////
143 // Function: AnimGroup::find_child
144 // Access: Published
145 // Description: Returns the first descendant found with the indicated
146 // name, or NULL if no such descendant exists. This
147 // method searches the entire graph beginning at this
148 // AnimGroup; see also get_child_named().
149 ////////////////////////////////////////////////////////////////////
151 find_child(const string &name) const {
152  Children::const_iterator ci;
153  for (ci = _children.begin(); ci != _children.end(); ++ci) {
154  AnimGroup *child = (*ci);
155  if (child->get_name() == name) {
156  return child;
157  }
158  AnimGroup *result = child->find_child(name);
159  if (result != (AnimGroup *)NULL) {
160  return result;
161  }
162  }
163 
164  return (AnimGroup *)NULL;
165 }
166 
167 // An STL object to sort a list of children into alphabetical order.
169 public:
170  bool operator()(const PT(AnimGroup) &a, const PT(AnimGroup) &b) const {
171  return a->get_name() < b->get_name();
172  }
173 };
174 
175 ////////////////////////////////////////////////////////////////////
176 // Function: AnimGroup::sort_descendants
177 // Access: Published
178 // Description: Sorts the children nodes at each level of the
179 // hierarchy into alphabetical order. This should be
180 // done after creating the hierarchy, to guarantee that
181 // the correct names will match up together when the
182 // AnimBundle is later bound to a PlayerRoot.
183 ////////////////////////////////////////////////////////////////////
184 void AnimGroup::
186  sort(_children.begin(), _children.end(), AnimGroupAlphabeticalOrder());
187 
188  Children::iterator ci;
189  for (ci = _children.begin(); ci != _children.end(); ++ci) {
190  (*ci)->sort_descendants();
191  }
192 }
193 
194 
195 ////////////////////////////////////////////////////////////////////
196 // Function: AnimGroup::get_value_type
197 // Access: Public, Virtual
198 // Description: Returns the TypeHandle associated with the ValueType
199 // we are concerned with. This is provided to allow a
200 // bit of run-time checking that joints and channels are
201 // matching properly in type.
202 ////////////////////////////////////////////////////////////////////
204 get_value_type() const {
205  return TypeHandle::none();
206 }
207 
208 ////////////////////////////////////////////////////////////////////
209 // Function: AnimGroup::output
210 // Access: Published, Virtual
211 // Description: Writes a one-line description of the group.
212 ////////////////////////////////////////////////////////////////////
213 void AnimGroup::
214 output(ostream &out) const {
215  out << get_type() << " " << get_name();
216 }
217 
218 ////////////////////////////////////////////////////////////////////
219 // Function: AnimGroup::write
220 // Access: Published, Virtual
221 // Description: Writes a brief description of the group and all of
222 // its descendants.
223 ////////////////////////////////////////////////////////////////////
224 void AnimGroup::
225 write(ostream &out, int indent_level) const {
226  indent(out, indent_level) << *this;
227  if (!_children.empty()) {
228  out << " {\n";
229  write_descendants(out, indent_level + 2);
230  indent(out, indent_level) << "}";
231  }
232  out << "\n";
233 }
234 
235 ////////////////////////////////////////////////////////////////////
236 // Function: AnimGroup::write_descendants
237 // Access: Protected
238 // Description: Writes a brief description of all of the group's
239 // descendants.
240 ////////////////////////////////////////////////////////////////////
241 void AnimGroup::
242 write_descendants(ostream &out, int indent_level) const {
243  Children::const_iterator ci;
244 
245  for (ci = _children.begin(); ci != _children.end(); ++ci) {
246  (*ci)->write(out, indent_level);
247  }
248 }
249 
250 ////////////////////////////////////////////////////////////////////
251 // Function: AnimGroup::make_copy
252 // Access: Protected, Virtual
253 // Description: Returns a copy of this object, and attaches it to the
254 // indicated parent (which may be NULL only if this is
255 // an AnimBundle). Intended to be called by
256 // copy_subtree() only.
257 ////////////////////////////////////////////////////////////////////
258 AnimGroup *AnimGroup::
259 make_copy(AnimGroup *parent) const {
260  return new AnimGroup(parent, *this);
261 }
262 
263 
264 ////////////////////////////////////////////////////////////////////
265 // Function: AnimGroup::copy_subtree
266 // Access: Protected
267 // Description: Returns a full copy of the subtree at this node and
268 // below.
269 ////////////////////////////////////////////////////////////////////
270 PT(AnimGroup) AnimGroup::
271 copy_subtree(AnimGroup *parent) const {
272  PT(AnimGroup) new_group = make_copy(parent);
273  nassertr(new_group->get_type() == get_type(), (AnimGroup *)this);
274 
275  Children::const_iterator ci;
276  for (ci = _children.begin(); ci != _children.end(); ++ci) {
277  (*ci)->copy_subtree(new_group);
278  }
279 
280  return new_group;
281 }
282 
283 ////////////////////////////////////////////////////////////////////
284 // Function: AnimGroup::write_datagram
285 // Access: Public
286 // Description: Function to write the important information in
287 // the particular object to a Datagram
288 ////////////////////////////////////////////////////////////////////
289 void AnimGroup::
291  me.add_string(get_name());
292  //Write out the root
293  manager->write_pointer(me, this->_root);
294  me.add_uint16(_children.size());
295  for(int i = 0; i < (int)_children.size(); i++) {
296  manager->write_pointer(me, _children[i]);
297  }
298 }
299 
300 ////////////////////////////////////////////////////////////////////
301 // Function: AnimGroup::fillin
302 // Access: Protected
303 // Description: Function that reads out of the datagram (or asks
304 // manager to read) all of the data that is needed to
305 // re-create this object and stores it in the appropiate
306 // place
307 ////////////////////////////////////////////////////////////////////
308 void AnimGroup::
309 fillin(DatagramIterator &scan, BamReader *manager) {
310  set_name(scan.get_string());
311  manager->read_pointer(scan);
312  _num_children = scan.get_uint16();
313  for(int i = 0; i < _num_children; i++)
314  {
315  manager->read_pointer(scan);
316  }
317 }
318 
319 ////////////////////////////////////////////////////////////////////
320 // Function: AnimGroup::complete_pointers
321 // Access: Public
322 // Description: Takes in a vector of pointes to TypedWritable
323 // objects that correspond to all the requests for
324 // pointers that this object made to BamReader.
325 ////////////////////////////////////////////////////////////////////
326 int AnimGroup::
328  _root = DCAST(AnimBundle, p_list[0]);
329  for (int i = 1; i < _num_children+1; i++) {
330  if (p_list[i] == TypedWritable::Null) {
331  chan_cat->warning() << get_type().get_name()
332  << " Ignoring null child" << endl;
333  } else {
334  _children.push_back(DCAST(AnimGroup, p_list[i]));
335  }
336  }
337  return _num_children+1;
338 }
339 
340 ////////////////////////////////////////////////////////////////////
341 // Function: AnimGroup::make_AnimGroup
342 // Access: Protected
343 // Description: Factory method to generate a AnimGroup object
344 ////////////////////////////////////////////////////////////////////
347  AnimGroup *me = new AnimGroup;
348  DatagramIterator scan;
349  BamReader *manager;
350 
351  parse_params(params, scan, manager);
352  me->fillin(scan, manager);
353  return me;
354 }
355 
356 ////////////////////////////////////////////////////////////////////
357 // Function: AnimGroup::register_with_factory
358 // Access: Public, Static
359 // Description: Factory method to generate a AnimGroup object
360 ////////////////////////////////////////////////////////////////////
361 void AnimGroup::
364 }
365 
366 
367 
368 
369 
370 
371 
AnimGroup * find_child(const string &name) const
Returns the first descendant found with the indicated name, or NULL if no such descendant exists...
Definition: animGroup.cxx:151
void add_string(const string &str)
Adds a variable-length string to the datagram.
Definition: datagram.I:351
int get_num_children() const
Returns the number of child nodes of the group.
Definition: animGroup.cxx:104
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Takes in a vector of pointes to TypedWritable objects that correspond to all the requests for pointer...
Definition: animGroup.cxx:327
static TypeHandle none()
Returns a special zero-valued TypeHandle that is used to indicate no type.
Definition: typeHandle.I:274
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
static void register_with_read_factory()
Factory method to generate a AnimGroup object.
Definition: animGroup.cxx:362
This is the root of an AnimChannel hierarchy.
Definition: animBundle.h:31
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
string get_name(TypedObject *object=(TypedObject *) NULL) const
Returns the name of the type.
Definition: typeHandle.I:132
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
Definition: animGroup.cxx:290
void sort_descendants()
Sorts the children nodes at each level of the hierarchy into alphabetical order.
Definition: animGroup.cxx:185
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
string get_string()
Extracts a variable-length string.
PN_uint16 get_uint16()
Extracts an unsigned 16-bit integer.
virtual void write(ostream &out, int indent_level) const
Writes a brief description of the group and all of its descendants.
Definition: animGroup.cxx:225
A base class for all things which can have a name.
Definition: namable.h:29
virtual void output(ostream &out) const
Writes a one-line description of the group.
Definition: animGroup.cxx:214
This is the base class for AnimChannel and AnimBundle.
Definition: animGroup.h:36
virtual TypeHandle get_value_type() const
Returns the TypeHandle associated with the ValueType we are concerned with.
Definition: animGroup.cxx:204
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
void add_uint16(PN_uint16 value)
Adds an unsigned 16-bit integer to the datagram.
Definition: datagram.I:181
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
AnimGroup * get_child_named(const string &name) const
Returns the first child found with the indicated name, or NULL if no such child exists.
Definition: animGroup.cxx:130
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
AnimGroup * get_child(int n) const
Returns the nth child of the group.
Definition: animGroup.cxx:115
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
Definition: bamWriter.cxx:279
void read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition: bamReader.cxx:652
static TypedWritable * make_AnimGroup(const FactoryParams &params)
Factory method to generate a AnimGroup object.
Definition: animGroup.cxx:346