Panda3D

partGroup.cxx
Go to the documentation of this file.
1 /**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file partGroup.cxx
10 * @author drose
11 * @date 1999-02-22
12 */
13
14 #include "partGroup.h"
15 #include "animGroup.h"
16 #include "config_chan.h"
17 #include "partSubset.h"
18
19 #include "indent.h"
20 #include "datagram.h"
21 #include "datagramIterator.h"
22 #include "bamReader.h"
23 #include "bamWriter.h"
24 #include "transformState.h"
25
26 #include <algorithm>
27
28 using std::ostream;
29
30 TypeHandle PartGroup::_type_handle;
31
32 /**
33 * Creates the PartGroup, and adds it to the indicated parent. The only way
34 * to delete it subsequently is to delete the entire hierarchy.
35 */
36 PartGroup::
37 PartGroup(PartGroup *parent, const std::string &name) :
38 Namable(name),
39 _children(get_class_type())
40 {
41 nassertv(parent != nullptr);
42
43 parent->_children.push_back(this);
44 }
45
46 /**
47 *
48 */
49 PartGroup::
50 ~PartGroup() {
51 }
52
53 /**
54 * Returns true if this part is a CharacterJoint, false otherwise. This is a
55 * tiny optimization over is_of_type(CharacterType::get_class_type()).
56 */
57 bool PartGroup::
58 is_character_joint() const {
59 return false;
60 }
61
62 /**
63 * Allocates and returns a new copy of the node. Children are not copied, but
64 * see copy_subgraph().
65 */
66 PartGroup *PartGroup::
67 make_copy() const {
68 return new PartGroup(*this);
69 }
70
71 /**
72 * Allocates and returns a new copy of this node and of all of its children.
73 */
74 PartGroup *PartGroup::
75 copy_subgraph() const {
76 PartGroup *root = make_copy();
77
78 if (root->get_type() != get_type()) {
79 chan_cat.warning()
80 << "Don't know how to copy " << get_type() << "\n";
81 }
82
83 Children::const_iterator ci;
84 for (ci = _children.begin(); ci != _children.end(); ++ci) {
85 PartGroup *child = (*ci)->copy_subgraph();
86 root->_children.push_back(child);
87 }
88
89 return root;
90 }
91
92
93 /**
94 * Returns the number of child nodes of the group.
95 */
96 int PartGroup::
97 get_num_children() const {
98 return _children.size();
99 }
100
101
102 /**
103 * Returns the nth child of the group.
104 */
105 PartGroup *PartGroup::
106 get_child(int n) const {
107 nassertr(n >= 0 && n < (int)_children.size(), nullptr);
108 return _children[n];
109 }
110
111 /**
112 * Returns the first child found with the indicated name, or NULL if no such
113 * child exists. This method searches only the children of this particular
114 * PartGroup; it does not recursively search the entire graph. See also
115 * find_child().
116 */
117 PartGroup *PartGroup::
118 get_child_named(const std::string &name) const {
119 Children::const_iterator ci;
120 for (ci = _children.begin(); ci != _children.end(); ++ci) {
121 PartGroup *child = (*ci);
122 if (child->get_name() == name) {
123 return child;
124 }
125 }
126
127 return nullptr;
128 }
129
130 /**
131 * Returns the first descendant found with the indicated name, or NULL if no
132 * such descendant exists. This method searches the entire graph beginning at
133 * this PartGroup; see also get_child_named().
134 */
135 PartGroup *PartGroup::
136 find_child(const std::string &name) const {
137 Children::const_iterator ci;
138 for (ci = _children.begin(); ci != _children.end(); ++ci) {
139 PartGroup *child = (*ci);
140 if (child->get_name() == name) {
141 return child;
142 }
143 PartGroup *result = child->find_child(name);
144 if (result != nullptr) {
145 return result;
146 }
147 }
148
149 return nullptr;
150 }
151
152 // An STL object to sort a list of children into alphabetical order.
153 class PartGroupAlphabeticalOrder {
154 public:
155 bool operator()(const PT(PartGroup) &a, const PT(PartGroup) &b) const {
156 return a->get_name() < b->get_name();
157 }
158 };
159
160 /**
161 * Sorts the children nodes at each level of the hierarchy into alphabetical
162 * order. This should be done after creating the hierarchy, to guarantee that
163 * the correct names will match up together when the AnimBundle is later bound
164 * to a PlayerRoot.
165 */
166 void PartGroup::
167 sort_descendants() {
168 std::stable_sort(_children.begin(), _children.end(), PartGroupAlphabeticalOrder());
169
170 Children::iterator ci;
171 for (ci = _children.begin(); ci != _children.end(); ++ci) {
172 (*ci)->sort_descendants();
173 }
174 }
175
176 /**
177 * Freezes this particular joint so that it will always hold the specified
178 * transform. Returns true if this is a joint that can be so frozen, false
179 * otherwise.
180 *
181 * This is normally only called internally by PartBundle::freeze_joint(), but
182 * you may also call it directly.
183 */
184 bool PartGroup::
185 apply_freeze(const TransformState *transform) {
186 return apply_freeze_matrix(transform->get_pos(), transform->get_hpr(), transform->get_scale()) || apply_freeze_scalar(transform->get_pos()[0]);
187 }
188
189 /**
190 * Freezes this particular joint so that it will always hold the specified
191 * transform. Returns true if this is a joint that can be so frozen, false
192 * otherwise.
193 *
194 * This is normally only called internally by PartBundle::freeze_joint(), but
195 * you may also call it directly.
196 */
197 bool PartGroup::
198 apply_freeze_matrix(const LVecBase3 &pos, const LVecBase3 &hpr, const LVecBase3 &scale) {
199 return false;
200 }
201
202 /**
203 * Freezes this particular joint so that it will always hold the specified
204 * transform. Returns true if this is a joint that can be so frozen, false
205 * otherwise.
206 *
207 * This is normally only called internally by PartBundle::freeze_joint(), but
208 * you may also call it directly.
209 */
210 bool PartGroup::
211 apply_freeze_scalar(PN_stdfloat value) {
212 return false;
213 }
214
215
216 /**
217 * Specifies a node to influence this particular joint so that it will always
218 * hold the node's transform. Returns true if this is a joint that can be so
219 * controlled, false otherwise.
220 *
221 * This is normally only called internally by PartBundle::control_joint(), but
222 * you may also call it directly.
223 */
224 bool PartGroup::
225 apply_control(PandaNode *node) {
226 return false;
227 }
228
229 /**
230 * Undoes the effect of a previous call to apply_freeze() or apply_control().
231 * Returns true if the joint was modified, false otherwise.
232 *
233 * This is normally only called internally by PartBundle::release_joint(), but
234 * you may also call it directly.
235 */
236 bool PartGroup::
237 clear_forced_channel() {
238 return false;
239 }
240
241 /**
242 * Returns the AnimChannelBase that has been forced to this joint by a
243 * previous call to apply_freeze() or apply_control(), or NULL if no such
244 * channel has been applied.
245 */
246 AnimChannelBase *PartGroup::
247 get_forced_channel() const {
248 return nullptr;
249 }
250
251
252 /**
253 * Writes a brief description of the group and all of its descendants.
254 */
255 void PartGroup::
256 write(ostream &out, int indent_level) const {
257 indent(out, indent_level)
258 << get_type() << " " << get_name() << " {\n";
259 write_descendants(out, indent_level + 2);
260 indent(out, indent_level) << "}\n";
261 }
262
263 /**
264 * Writes a brief description of the group, showing its current value, and
265 * that of all of its descendants.
266 */
267 void PartGroup::
268 write_with_value(ostream &out, int indent_level) const {
269 indent(out, indent_level)
270 << get_type() << " " << get_name() << " {\n";
271 write_descendants_with_value(out, indent_level + 2);
272 indent(out, indent_level) << "}\n";
273 }
274
275 /**
276 * Returns the TypeHandle associated with the ValueType we are concerned with.
277 * This is provided to allow a bit of run-time checking that joints and
278 * channels are matching properly in type.
279 */
280 TypeHandle PartGroup::
281 get_value_type() const {
282 return TypeHandle::none();
283 }
284
285 /**
286 * Walks the part hierarchy in tandem with the indicated anim hierarchy, and
287 * returns true if the hierarchies match, false otherwise.
288 *
289 * If hierarchy_match_flags is 0, only an exact match is accepted; otherwise,
290 * it may contain a union of PartGroup::HierarchyMatchFlags values indicating
291 * conditions that will be tolerated (but warnings will still be issued).
292 */
293 bool PartGroup::
294 check_hierarchy(const AnimGroup *anim, const PartGroup *,
295 int hierarchy_match_flags) const {
296 Thread::consider_yield();
297 if (anim->get_value_type() != get_value_type()) {
298 if (chan_cat.is_error()) {
299 chan_cat.error()
300 << "Part " << get_name() << " expects type " << get_value_type()
301 << " while matching anim node has type " << anim->get_value_type()
302 << ".\n";
303 }
304 return false;
305 }
306
307 if (chan_cat.is_info()) {
308 // If we're issuing error messages, check ahead of time if the set of
309 // children agrees. If it does not, we'll write a one-line warning, and
310 // then list the set of children that differ.
311
312 bool match = true;
313 if (anim->get_num_children() != get_num_children()) {
314 // If the only difference is "morph", ignore it. We treat "morph" as a
315 // special case, because it's common for the model and animation files
316 // to differ meaninglessly here. Any differences here remain
317 // unreported.
318 if (anim->get_num_children() == get_num_children() + 1 &&
319 anim->get_child_named("morph") != nullptr &&
320 get_child_named("morph") == nullptr) {
321 // Anim has "morph" and model does not, but there are no other
322 // differences.
323
324 } else if (get_num_children() == anim->get_num_children() + 1 &&
325 get_child_named("morph") != nullptr &&
326 anim->get_child_named("morph") == nullptr) {
327 // Model has "morph" and anim does not, but there are no other
328 // differences.
329
330 } else {
331 chan_cat.info()
332 << "Part " << get_name() << " has " << get_num_children()
333 << " children, while matching anim node has "
334 << anim->get_num_children() << ":\n";
335 match = false;
336 }
337
338 } else {
339 for (int i = 0; match && i < get_num_children(); i++) {
340 PartGroup *pc = get_child(i);
341 AnimGroup *ac = anim->get_child(i);
342
343 match = (pc->get_name() == ac->get_name());
344 }
345 if (!match) {
346 chan_cat.info()
347 << "Part " << get_name() << " has a different set of children "
348 << " than matching anim node:\n";
349 }
350 }
351 if (!match) {
352 int i = 0, j = 0;
353 while (i < get_num_children() &&
354 j < anim->get_num_children()) {
355 PartGroup *pc = get_child(i);
356 AnimGroup *ac = anim->get_child(j);
357
358 if (pc->get_name() < ac->get_name()) {
359 chan_cat.info()
360 << " part has " << pc->get_name()
361 << ", not in anim.\n";
362 i++;
363 } else if (ac->get_name() < pc->get_name()) {
364 chan_cat.info()
365 << " anim has " << ac->get_name()
366 << ", not in part.\n";
367 j++;
368 } else {
369 // chan_cat.info() << " part and anim both have " << ac->get_name()
370 // << "\n";
371 i++;
372 j++;
373 }
374 }
375
376 while (i < get_num_children()) {
377 PartGroup *pc = get_child(i);
378 chan_cat.info()
379 << " part has " << pc->get_name()
380 << ", not in anim.\n";
381 i++;
382 }
383
384 while (j < anim->get_num_children()) {
385 AnimGroup *ac = anim->get_child(j);
386 chan_cat.info()
387 << " anim has " << ac->get_name()
388 << ", not in part.\n";
389 j++;
390 }
391 }
392 }
393
394 // Now walk the list of children and check the matching sub-hierarchies
395 // only.
396
397 int i = 0, j = 0;
398 while (i < get_num_children() &&
399 j < anim->get_num_children()) {
400 PartGroup *pc = get_child(i);
401 AnimGroup *ac = anim->get_child(j);
402
403 if (pc->get_name() < ac->get_name()) {
404 if (pc->get_name() == "morph") {
405 // Model has "morph", not in anim. Ignore.
406 } else {
407 if ((hierarchy_match_flags & HMF_ok_part_extra) == 0) {
408 return false;
409 }
410 }
411 i++;
412 } else if (ac->get_name() < pc->get_name()) {
413 if (ac->get_name() == "morph") {
414 // Anim has "morph", not in model. Ignore.
415 } else {
416 if ((hierarchy_match_flags & HMF_ok_anim_extra) == 0) {
417 return false;
418 }
419 }
420 j++;
421 } else {
422 if (!pc->check_hierarchy(ac, this, hierarchy_match_flags)) {
423 return false;
424 }
425 i++;
426 j++;
427 }
428 }
429
430 while (i < get_num_children()) {
431 // There's at least one extra part.
432 PartGroup *pc = get_child(i);
433
434 if (pc->get_name() == "morph") {
435 // Model has "morph", not in anim. Ignore.
436 } else {
437 if ((hierarchy_match_flags & HMF_ok_part_extra) == 0) {
438 return false;
439 }
440 }
441 i++;
442 }
443
444 while (j < anim->get_num_children()) {
445 // There's at least one extra anim channel.
446 AnimGroup *ac = anim->get_child(j);
447
448 if (ac->get_name() == "morph") {
449 // Anim has "morph", not in model. Ignore.
450 } else {
451 if ((hierarchy_match_flags & HMF_ok_anim_extra) == 0) {
452 return false;
453 }
454 }
455 j++;
456 }
457
458 return true;
459 }
460
461
462 /**
463 * Recursively update this particular part and all of its descendents for the
464 * current frame. This is not really public and is not intended to be called
465 * directly; it is called from the top of the tree by PartBundle::update().
466 *
467 * The return value is true if any part has changed, false otherwise.
468 */
469 bool PartGroup::
470 do_update(PartBundle *root, const CycleData *root_cdata, PartGroup *,
471 bool parent_changed, bool anim_changed, Thread *current_thread) {
472 bool any_changed = false;
473
474 Children::iterator ci;
475 for (ci = _children.begin(); ci != _children.end(); ++ci) {
476 if ((*ci)->do_update(root, root_cdata, this, parent_changed,
477 anim_changed, current_thread)) {
478 any_changed = true;
479 }
480 }
481
482 return any_changed;
483 }
484
485 /**
486 * Called by PartBundle::xform(), this indicates the indicated transform is
487 * being applied to the root joint.
488 */
489 void PartGroup::
490 do_xform(const LMatrix4 &mat, const LMatrix4 &inv_mat) {
491 Children::const_iterator ci;
492
493 for (ci = _children.begin(); ci != _children.end(); ++ci) {
494 (*ci)->do_xform(mat, inv_mat);
495 }
496 }
497
498 /**
499 * Should be called whenever the ChannelBlend values have changed, this
500 * recursively updates the _effective_channel member in each part.
501 */
502 void PartGroup::
503 determine_effective_channels(const CycleData *root_cdata) {
504 Children::iterator ci;
505 for (ci = _children.begin(); ci != _children.end(); ++ci) {
506 (*ci)->determine_effective_channels(root_cdata);
507 }
508 }
509
510
511 /**
512 * Writes a brief description of all of the group's descendants.
513 */
514 void PartGroup::
515 write_descendants(ostream &out, int indent_level) const {
516 Children::const_iterator ci;
517
518 for (ci = _children.begin(); ci != _children.end(); ++ci) {
519 (*ci)->write(out, indent_level);
520 }
521 }
522
523 /**
524 * Writes a brief description of all of the group's descendants and their
525 * values.
526 */
527 void PartGroup::
528 write_descendants_with_value(ostream &out, int indent_level) const {
529 Children::const_iterator ci;
530
531 for (ci = _children.begin(); ci != _children.end(); ++ci) {
532 (*ci)->write_with_value(out, indent_level);
533 }
534 }
535
536 /**
537 * Walks the part hierarchy, looking for a suitable channel index number to
538 * use. Available index numbers are the elements of the holes set, as well as
539 * next to infinity.
540 */
541 void PartGroup::
542 pick_channel_index(plist<int> &holes, int &next) const {
543 Children::const_iterator ci;
544 for (ci = _children.begin(); ci != _children.end(); ++ci) {
545 (*ci)->pick_channel_index(holes, next);
546 }
547 }
548
549
550 /**
551 * Binds the indicated anim hierarchy to the part hierarchy, at the given
552 * channel index number.
553 */
554 void PartGroup::
555 bind_hierarchy(AnimGroup *anim, int channel_index, int &joint_index,
556 bool is_included, BitArray &bound_joints,
557 const PartSubset &subset) {
558 Thread::consider_yield();
559 if (subset.matches_include(get_name())) {
560 is_included = true;
561 } else if (subset.matches_exclude(get_name())) {
562 is_included = false;
563 }
564
565 int i = 0, j = 0;
566 int part_num_children = get_num_children();
567 int anim_num_children = (anim == nullptr) ? 0 : anim->get_num_children();
568
569 while (i < part_num_children && j < anim_num_children) {
570 PartGroup *pc = get_child(i);
571 AnimGroup *ac = anim->get_child(j);
572
573 if (pc->get_name() < ac->get_name()) {
574 // Here's a part, not in the anim. Bind it to the special NULL anim.
575 pc->bind_hierarchy(nullptr, channel_index, joint_index, is_included,
576 bound_joints, subset);
577 i++;
578
579 } else if (ac->get_name() < pc->get_name()) {
580 // Here's an anim, not in the part. Ignore it.
581 j++;
582
583 } else {
584 // Here's a matched part and anim pair.
585 pc->bind_hierarchy(ac, channel_index, joint_index, is_included,
586 bound_joints, subset);
587 i++;
588 j++;
589 }
590 }
591
592 // Now pick up any more parts, not in the anim.
593 while (i < part_num_children) {
594 PartGroup *pc = get_child(i);
595 pc->bind_hierarchy(nullptr, channel_index, joint_index, is_included,
596 bound_joints, subset);
597 i++;
598 }
599 }
600
601 /**
602 * Similar to bind_hierarchy, but does not actually perform any binding. All
603 * it does is compute the BitArray bount_joints according to the specified
604 * subset. This is useful in preparation for asynchronous binding--in this
605 * case, we may need to know bound_joints immediately, without having to wait
606 * for the animation itself to load and bind.
607 */
608 void PartGroup::
609 find_bound_joints(int &joint_index, bool is_included, BitArray &bound_joints,
610 const PartSubset &subset) {
611 if (subset.matches_include(get_name())) {
612 is_included = true;
613 } else if (subset.matches_exclude(get_name())) {
614 is_included = false;
615 }
616
617 int part_num_children = get_num_children();
618 for (int i = 0; i < part_num_children; ++i) {
619 PartGroup *pc = get_child(i);
620 pc->find_bound_joints(joint_index, is_included, bound_joints, subset);
621 }
622 }
623
624 /**
625 * Function to write the important information in the particular object to a
626 * Datagram
627 */
628 void PartGroup::
629 write_datagram(BamWriter *manager, Datagram &me) {
630 me.add_string(get_name());
631 me.add_uint16(_children.size());
632 for (size_t i = 0; i < _children.size(); i++) {
633 manager->write_pointer(me, _children[i]);
634 }
635 }
636
637 /**
638 * Function that reads out of the datagram (or asks manager to read) all of
639 * the data that is needed to re-create this object and stores it in the
640 * appropiate place
641 */
642 void PartGroup::
643 fillin(DatagramIterator &scan, BamReader *manager) {
644 set_name(scan.get_string());
645
646 if (manager->get_file_minor_ver() == 11) {
647 // Skip over the old freeze-joint information, no longer stored here
648 scan.get_bool();
649 LMatrix4 mat;
650 mat.read_datagram(scan);
651 }
652
653 int num_children = scan.get_uint16();
654 _children.reserve(num_children);
655 for (int i = 0; i < num_children; i++) {
656 manager->read_pointer(scan);
657 _children.push_back(nullptr);
658 }
659 }
660
661 /**
662 * Takes in a vector of pointers to TypedWritable objects that correspond to
663 * all the requests for pointers that this object made to BamReader.
664 */
665 int PartGroup::
666 complete_pointers(TypedWritable **p_list, BamReader *manager) {
667 int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager);
668
669 Children::iterator ci;
670 for (ci = _children.begin(); ci != _children.end(); ++ci) {
671 (*ci) = DCAST(PartGroup, p_list[pi++]);
672 }
673
674 return pi;
675 }
676
677 /**
678 * Factory method to generate a PartGroup object
679 */
680 TypedWritable* PartGroup::
681 make_PartGroup(const FactoryParams &params) {
682 PartGroup *me = new PartGroup;
683 DatagramIterator scan;
684 BamReader *manager;
685
686 parse_params(params, scan, manager);
687 me->fillin(scan, manager);
688 return me;
689 }
690
691 /**
692 * Factory method to generate a PartGroup object
693 */
694 void PartGroup::
695 register_with_read_factory() {
696 BamReader::get_factory()->register_factory(get_class_type(), make_PartGroup);
697 }
animGroup.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bamReader.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
parse_params
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition: bamReader.I:275
bamWriter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
AnimChannelBase
Parent class for all animation channels.
Definition: animChannelBase.h:30
AnimGroup
This is the base class for AnimChannel and AnimBundle.
Definition: animGroup.h:33
AnimGroup::get_child
get_child
Returns the nth child of the group.
Definition: animGroup.h:45
AnimGroup::get_child_named
AnimGroup * get_child_named(const std::string &name) const
Returns the first child found with the indicated name, or NULL if no such child exists.
Definition: animGroup.cxx:111
AnimGroup::get_num_children
get_num_children
Returns the number of child nodes of the group.
Definition: animGroup.h:45
AnimGroup::get_value_type
virtual TypeHandle get_value_type() const
Returns the TypeHandle associated with the ValueType we are concerned with.
Definition: animGroup.cxx:176
BamReader
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
BamReader::read_pointer
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition: bamReader.cxx:610
BamReader::get_file_minor_ver
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
Definition: bamReader.I:83
BamReader::get_factory
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
BamWriter
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
BamWriter::write_pointer
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
Definition: bamWriter.cxx:317
BitArray
A dynamic array with an unlimited number of bits.
Definition: bitArray.h:40
CycleData
A single page of data maintained by a PipelineCycler.
Definition: cycleData.h:50
DatagramIterator
A class to retrieve the individual data elements previously stored in a Datagram.
Definition: datagramIterator.h:27
DatagramIterator::get_uint16
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
Definition: datagramIterator.I:145
DatagramIterator::get_bool
bool get_bool()
Extracts a boolean value.
Definition: datagramIterator.I:48
DatagramIterator::get_string
std::string get_string()
Extracts a variable-length string.
Definition: datagramIterator.cxx:26
Datagram
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
Datagram::add_uint16
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
Definition: datagram.I:85
Datagram::add_string
void add_string(const std::string &str)
Adds a variable-length string to the datagram.
Definition: datagram.I:219
FactoryParams
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
Factory::register_factory
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:73
Namable
A base class for all things which can have a name.
Definition: namable.h:26
PandaNode
A basic node of the scene graph or data graph.
Definition: pandaNode.h:65
PartBundle
This is the root of a MovingPart hierarchy.
Definition: partBundle.h:46
PartGroup
This is the base class for PartRoot and MovingPart.
Definition: partGroup.h:43
PartGroup::get_num_children
get_num_children
Returns the number of child nodes of the group.
Definition: partGroup.h:72
PartGroup::sort_descendants
void sort_descendants()
Sorts the children nodes at each level of the hierarchy into alphabetical order.
Definition: partGroup.cxx:167
PartGroup::get_child_named
PartGroup * get_child_named(const std::string &name) const
Returns the first child found with the indicated name, or NULL if no such child exists.
Definition: partGroup.cxx:118
PartGroup::copy_subgraph
PartGroup * copy_subgraph() const
Allocates and returns a new copy of this node and of all of its children.
Definition: partGroup.cxx:75
PartGroup::write
virtual void write(std::ostream &out, int indent_level) const
Writes a brief description of the group and all of its descendants.
Definition: partGroup.cxx:256
PartGroup::make_copy
virtual PartGroup * make_copy() const
Allocates and returns a new copy of the node.
Definition: partGroup.cxx:67
PartGroup::find_child
PartGroup * find_child(const std::string &name) const
Returns the first descendant found with the indicated name, or NULL if no such descendant exists.
Definition: partGroup.cxx:136
PartGroup::apply_freeze_scalar
virtual bool apply_freeze_scalar(PN_stdfloat value)
Freezes this particular joint so that it will always hold the specified transform.
Definition: partGroup.cxx:211
PartGroup::apply_freeze
bool apply_freeze(const TransformState *transform)
Freezes this particular joint so that it will always hold the specified transform.
Definition: partGroup.cxx:185
PartGroup::write_datagram
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
Definition: partGroup.cxx:629
PartGroup::apply_control
virtual bool apply_control(PandaNode *node)
Specifies a node to influence this particular joint so that it will always hold the node's transform.
Definition: partGroup.cxx:225
PartGroup::clear_forced_channel
virtual bool clear_forced_channel()
Undoes the effect of a previous call to apply_freeze() or apply_control().
Definition: partGroup.cxx:237
PartGroup::get_child
get_child
Returns the nth child of the group.
Definition: partGroup.h:72
PartGroup::register_with_read_factory
static void register_with_read_factory()
Factory method to generate a PartGroup object.
Definition: partGroup.cxx:695
PartGroup::check_hierarchy
bool check_hierarchy(const AnimGroup *anim, const PartGroup *parent, int hierarchy_match_flags=0) const
Walks the part hierarchy in tandem with the indicated anim hierarchy, and returns true if the hierarc...
Definition: partGroup.cxx:294
PartGroup::make_PartGroup
static TypedWritable * make_PartGroup(const FactoryParams &params)
Factory method to generate a PartGroup object.
Definition: partGroup.cxx:681
PartGroup::get_forced_channel
virtual AnimChannelBase * get_forced_channel() const
Returns the AnimChannelBase that has been forced to this joint by a previous call to apply_freeze() o...
Definition: partGroup.cxx:247
PartGroup::is_character_joint
virtual bool is_character_joint() const
Returns true if this part is a CharacterJoint, false otherwise.
Definition: partGroup.cxx:58
PartGroup::write_with_value
virtual void write_with_value(std::ostream &out, int indent_level) const
Writes a brief description of the group, showing its current value, and that of all of its descendant...
Definition: partGroup.cxx:268
PartGroup::determine_effective_channels
virtual void determine_effective_channels(const CycleData *root_cdata)
Should be called whenever the ChannelBlend values have changed, this recursively updates the _effecti...
Definition: partGroup.cxx:503
PartGroup::do_xform
virtual void do_xform(const LMatrix4 &mat, const LMatrix4 &inv_mat)
Called by PartBundle::xform(), this indicates the indicated transform is being applied to the root jo...
Definition: partGroup.cxx:490
PartGroup::get_value_type
virtual TypeHandle get_value_type() const
Returns the TypeHandle associated with the ValueType we are concerned with.
Definition: partGroup.cxx:281
PartGroup::apply_freeze_matrix
virtual bool apply_freeze_matrix(const LVecBase3 &pos, const LVecBase3 &hpr, const LVecBase3 &scale)
Freezes this particular joint so that it will always hold the specified transform.
Definition: partGroup.cxx:198
PartGroup::do_update
virtual bool do_update(PartBundle *root, const CycleData *root_cdata, PartGroup *parent, bool parent_changed, bool anim_changed, Thread *current_thread)
Recursively update this particular part and all of its descendents for the current frame.
Definition: partGroup.cxx:470
PartGroup::complete_pointers
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Takes in a vector of pointers to TypedWritable objects that correspond to all the requests for pointe...
Definition: partGroup.cxx:666
PartSubset
This class is used to define a subset of part names to apply to the PartBundle::bind_anim() operation...
Definition: partSubset.h:25
PartSubset::matches_exclude
bool matches_exclude(const std::string &joint_name) const
Returns true if the indicated name matches a name on the exclude list, false otherwise.
Definition: partSubset.cxx:140
PartSubset::matches_include
bool matches_include(const std::string &joint_name) const
Returns true if the indicated name matches a name on the include list, false otherwise.
Definition: partSubset.cxx:123
Thread
A thread; that is, a lightweight process.
Definition: thread.h:46
Thread::consider_yield
static void consider_yield()
Possibly suspends the current thread for the rest of the current epoch, if it has run for enough this...
Definition: thread.I:212
TransformState
Indicates a coordinate-system transform on vertices.
Definition: transformState.h:54
TransformState::get_scale
get_scale
Returns the scale component of the transform.
Definition: transformState.h:154
TransformState::get_hpr
get_hpr
Returns the rotation component of the transform as a trio of Euler angles.
Definition: transformState.h:151
TransformState::get_pos
get_pos
Returns the pos component of the transform.
Definition: transformState.h:150
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
TypedWritable
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
TypedWritable::complete_pointers
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
Definition: typedWritable.cxx:81
plist< int >
config_chan.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
datagramIterator.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
datagram.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
indent
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
indent.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
partGroup.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
partSubset.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
transformState.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.