Panda3D
characterJoint.cxx
1 // Filename: characterJoint.cxx
2 // Created by: drose (23Feb99)
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 #include "characterJoint.h"
16 #include "config_char.h"
17 #include "jointVertexTransform.h"
18 #include "characterJointEffect.h"
19 #include "datagram.h"
20 #include "datagramIterator.h"
21 #include "bamReader.h"
22 #include "bamWriter.h"
23 
24 TypeHandle CharacterJoint::_type_handle;
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: CharacterJoint::Default Constructor
28 // Access: Protected
29 // Description: For internal use only.
30 ////////////////////////////////////////////////////////////////////
31 CharacterJoint::
32 CharacterJoint() :
33  _character(NULL)
34 {
35 }
36 
37 ////////////////////////////////////////////////////////////////////
38 // Function: CharacterJoint::Copy Constructor
39 // Access: Protected
40 // Description:
41 ////////////////////////////////////////////////////////////////////
42 CharacterJoint::
43 CharacterJoint(const CharacterJoint &copy) :
44  MovingPartMatrix(copy),
45  _character(NULL),
46  _net_transform(copy._net_transform),
47  _initial_net_transform_inverse(copy._initial_net_transform_inverse)
48 {
49  // We don't copy the sets of transform nodes.
50 }
51 
52 ////////////////////////////////////////////////////////////////////
53 // Function: CharacterJoint::Constructor
54 // Access: Public
55 // Description:
56 ////////////////////////////////////////////////////////////////////
57 CharacterJoint::
58 CharacterJoint(Character *character,
59  PartBundle *root, PartGroup *parent, const string &name,
60  const LMatrix4 &default_value) :
61  MovingPartMatrix(parent, name, default_value),
62  _character(character)
63 {
64  Thread *current_thread = Thread::get_current_thread();
65 
66  // Now that we've constructed and we're in the tree, let's call
67  // update_internals() to get our _net_transform set properly.
68  update_internals(root, parent, true, false, current_thread);
69 
70  // And then compute its inverse. This is needed for
71  // ComputedVertices, during animation.
72  _initial_net_transform_inverse = invert(_net_transform);
73 }
74 
75 ////////////////////////////////////////////////////////////////////
76 // Function: CharacterJoint::Destructor
77 // Access: Public, Virtual
78 // Description:
79 ////////////////////////////////////////////////////////////////////
80 CharacterJoint::
81 ~CharacterJoint() {
82  nassertv(_vertex_transforms.empty());
83  nassertv(_character == (Character *)NULL);
84 }
85 
86 ////////////////////////////////////////////////////////////////////
87 // Function: CharacterJoint::is_character_joint
88 // Access: Public, Virtual
89 // Description: Returns true if this part is a CharacterJoint, false
90 // otherwise. This is a tiny optimization over
91 // is_of_type(CharacterType::get_class_type()).
92 ////////////////////////////////////////////////////////////////////
95  return true;
96 }
97 
98 ////////////////////////////////////////////////////////////////////
99 // Function: CharacterJoint::make_copy
100 // Access: Public, Virtual
101 // Description: Allocates and returns a new copy of the node.
102 // Children are not copied, but see copy_subgraph().
103 ////////////////////////////////////////////////////////////////////
105 make_copy() const {
106  return new CharacterJoint(*this);
107 }
108 
109 ////////////////////////////////////////////////////////////////////
110 // Function: CharacterJoint::update_internals
111 // Access: Public, Virtual
112 // Description: This is called by do_update() whenever the part or
113 // some ancestor has changed values. It is a hook for
114 // derived classes to update whatever cache they may
115 // have that depends on these.
116 //
117 // The return value is true if the part has changed as a
118 // result of the update, or false otherwise.
119 //
120 // In the case of a CharacterJoint, of course, it means
121 // to recompute the joint angles and associated
122 // transforms for this particular joint.
123 ////////////////////////////////////////////////////////////////////
124 bool CharacterJoint::
125 update_internals(PartBundle *root, PartGroup *parent, bool self_changed,
126  bool parent_changed, Thread *current_thread) {
127  nassertr(parent != (PartGroup *)NULL, false);
128 
129  bool net_changed = false;
130  if (parent->is_character_joint()) {
131  // The joint is not a toplevel joint; its parent therefore affects
132  // its net transform.
133  if (parent_changed || self_changed) {
134  CharacterJoint *parent_joint = DCAST(CharacterJoint, parent);
135 
136  _net_transform = _value * parent_joint->_net_transform;
137  net_changed = true;
138  }
139 
140  } else {
141  // The joint is a toplevel joint, so therefore it gets its root
142  // transform from the bundle.
143  if (self_changed) {
144  _net_transform = _value * root->get_root_xform();
145  net_changed = true;
146  }
147  }
148 
149  if (net_changed) {
150  if (!_net_transform_nodes.empty()) {
151  CPT(TransformState) t = TransformState::make_mat(_net_transform);
152 
153  NodeList::iterator ai;
154  for (ai = _net_transform_nodes.begin();
155  ai != _net_transform_nodes.end();
156  ++ai) {
157  PandaNode *node = *ai;
158  node->set_transform(t, current_thread);
159  }
160  }
161 
162  // Also tell our related JointVertexTransforms that they now need
163  // to recompute themselves.
164  VertexTransforms::iterator vti;
165  for (vti = _vertex_transforms.begin(); vti != _vertex_transforms.end(); ++vti) {
166  (*vti)->_matrix_stale = true;
167  (*vti)->mark_modified(current_thread);
168  }
169  }
170 
171  if (self_changed && !_local_transform_nodes.empty()) {
172  CPT(TransformState) t = TransformState::make_mat(_value);
173 
174  NodeList::iterator ai;
175  for (ai = _local_transform_nodes.begin();
176  ai != _local_transform_nodes.end();
177  ++ai) {
178  PandaNode *node = *ai;
179  node->set_transform(t, current_thread);
180  }
181  }
182 
183  return self_changed || net_changed;
184 }
185 
186 ////////////////////////////////////////////////////////////////////
187 // Function: CharacterJoint::do_xform
188 // Access: Public, Virtual
189 // Description: Called by PartBundle::xform(), this indicates the
190 // indicated transform is being applied to the root
191 // joint.
192 ////////////////////////////////////////////////////////////////////
193 void CharacterJoint::
194 do_xform(const LMatrix4 &mat, const LMatrix4 &inv_mat) {
195  _initial_net_transform_inverse = inv_mat * _initial_net_transform_inverse;
196 
197  MovingPartMatrix::do_xform(mat, inv_mat);
198 }
199 
200 
201 
202 ////////////////////////////////////////////////////////////////////
203 // Function: CharacterJoint::add_net_transform
204 // Access: Published
205 // Description: Adds the indicated node to the list of nodes that will
206 // be updated each frame with the joint's net transform
207 // from the root. Returns true if the node is
208 // successfully added, false if it had already been
209 // added.
210 //
211 // A CharacterJointEffect for this joint's Character
212 // will automatically be added to the specified node.
213 ////////////////////////////////////////////////////////////////////
214 bool CharacterJoint::
216  if (_character != (Character *)NULL) {
217  node->set_effect(CharacterJointEffect::make(_character));
218  }
219  CPT(TransformState) t = TransformState::make_mat(_net_transform);
221  return _net_transform_nodes.insert(node).second;
222 }
223 
224 ////////////////////////////////////////////////////////////////////
225 // Function: CharacterJoint::remove_net_transform
226 // Access: Published
227 // Description: Removes the indicated node from the list of nodes that
228 // will be updated each frame with the joint's net
229 // transform from the root. Returns true if the node is
230 // successfully removed, false if it was not on the
231 // list.
232 //
233 // If the node has a CharacterJointEffect that matches
234 // this joint's Character, it will be cleared.
235 ////////////////////////////////////////////////////////////////////
236 bool CharacterJoint::
238  CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
239  if (effect != (RenderEffect *)NULL &&
240  DCAST(CharacterJointEffect, effect)->get_character() == _character) {
241  node->clear_effect(CharacterJointEffect::get_class_type());
242  }
243 
244  return (_net_transform_nodes.erase(node) > 0);
245 }
246 
247 ////////////////////////////////////////////////////////////////////
248 // Function: CharacterJoint::has_net_transform
249 // Access: Published
250 // Description: Returns true if the node is on the list of nodes that
251 // will be updated each frame with the joint's net
252 // transform from the root, false otherwise.
253 ////////////////////////////////////////////////////////////////////
254 bool CharacterJoint::
256  return (_net_transform_nodes.count(node) > 0);
257 }
258 
259 ////////////////////////////////////////////////////////////////////
260 // Function: CharacterJoint::clear_net_transforms
261 // Access: Published
262 // Description: Removes all nodes from the list of nodes that will be
263 // updated each frame with the joint's net transform
264 // from the root.
265 ////////////////////////////////////////////////////////////////////
266 void CharacterJoint::
268  NodeList::iterator ai;
269  for (ai = _net_transform_nodes.begin();
270  ai != _net_transform_nodes.end();
271  ++ai) {
272  PandaNode *node = *ai;
273 
274  CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
275  if (effect != (RenderEffect *)NULL &&
276  DCAST(CharacterJointEffect, effect)->get_character() == _character) {
277  node->clear_effect(CharacterJointEffect::get_class_type());
278  }
279  }
280 
281  _net_transform_nodes.clear();
282 }
283 
284 ////////////////////////////////////////////////////////////////////
285 // Function: CharacterJoint::get_net_transforms
286 // Access: Published
287 // Description: Returns a list of the net transforms set for this
288 // node. Note that this returns a list of NodePaths,
289 // even though the net transforms are actually a list of
290 // PandaNodes.
291 ////////////////////////////////////////////////////////////////////
294  NodePathCollection npc;
295 
296  NodeList::iterator ai;
297  for (ai = _net_transform_nodes.begin();
298  ai != _net_transform_nodes.end();
299  ++ai) {
300  PandaNode *node = *ai;
301  npc.add_path(NodePath::any_path(node));
302  }
303 
304  return npc;
305 }
306 
307 ////////////////////////////////////////////////////////////////////
308 // Function: CharacterJoint::add_local_transform
309 // Access: Published
310 // Description: Adds the indicated node to the list of nodes that will
311 // be updated each frame with the joint's local
312 // transform from its parent. Returns true if the node
313 // is successfully added, false if it had already been
314 // added.
315 //
316 // The Character pointer should be the Character object
317 // that owns this joint; this will be used to create a
318 // CharacterJointEffect for this node. If it is NULL,
319 // no such effect will be created.
320 //
321 // A CharacterJointEffect for this joint's Character
322 // will automatically be added to the specified node.
323 ////////////////////////////////////////////////////////////////////
324 bool CharacterJoint::
326  if (_character != (Character *)NULL) {
327  node->set_effect(CharacterJointEffect::make(_character));
328  }
329  CPT(TransformState) t = TransformState::make_mat(_value);
331  return _local_transform_nodes.insert(node).second;
332 }
333 
334 ////////////////////////////////////////////////////////////////////
335 // Function: CharacterJoint::remove_local_transform
336 // Access: Published
337 // Description: Removes the indicated node from the list of nodes that
338 // will be updated each frame with the joint's local
339 // transform from its parent. Returns true if the node
340 // is successfully removed, false if it was not on the
341 // list.
342 //
343 // If the node has a CharacterJointEffect that matches
344 // this joint's Character, it will be cleared.
345 ////////////////////////////////////////////////////////////////////
346 bool CharacterJoint::
348  CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
349  if (effect != (RenderEffect *)NULL &&
350  DCAST(CharacterJointEffect, effect)->get_character() == _character) {
351  node->clear_effect(CharacterJointEffect::get_class_type());
352  }
353 
354  return (_local_transform_nodes.erase(node) > 0);
355 }
356 
357 ////////////////////////////////////////////////////////////////////
358 // Function: CharacterJoint::has_local_transform
359 // Access: Published
360 // Description: Returns true if the node is on the list of nodes that
361 // will be updated each frame with the joint's local
362 // transform from its parent, false otherwise.
363 ////////////////////////////////////////////////////////////////////
364 bool CharacterJoint::
366  return (_local_transform_nodes.count(node) > 0);
367 }
368 
369 ////////////////////////////////////////////////////////////////////
370 // Function: CharacterJoint::clear_local_transforms
371 // Access: Published
372 // Description: Removes all nodes from the list of nodes that will be
373 // updated each frame with the joint's local transform
374 // from its parent.
375 ////////////////////////////////////////////////////////////////////
376 void CharacterJoint::
378  NodeList::iterator ai;
379  for (ai = _local_transform_nodes.begin();
380  ai != _local_transform_nodes.end();
381  ++ai) {
382  PandaNode *node = *ai;
383 
384  CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
385  if (effect != (RenderEffect *)NULL &&
386  DCAST(CharacterJointEffect, effect)->get_character() == _character) {
387  node->clear_effect(CharacterJointEffect::get_class_type());
388  }
389  }
390 
391  _local_transform_nodes.clear();
392 }
393 
394 ////////////////////////////////////////////////////////////////////
395 // Function: CharacterJoint::get_local_transforms
396 // Access: Published
397 // Description: Returns a list of the local transforms set for this
398 // node. Note that this returns a list of NodePaths,
399 // even though the local transforms are actually a list of
400 // PandaNodes.
401 ////////////////////////////////////////////////////////////////////
404  NodePathCollection npc;
405 
406  NodeList::iterator ai;
407  for (ai = _local_transform_nodes.begin();
408  ai != _local_transform_nodes.end();
409  ++ai) {
410  PandaNode *node = *ai;
411  npc.add_path(NodePath::any_path(node));
412  }
413 
414  return npc;
415 }
416 
417 ////////////////////////////////////////////////////////////////////
418 // Function: CharacterJoint::get_transform
419 // Access: Published
420 // Description: Copies the joint's current transform into the
421 // indicated matrix.
422 ////////////////////////////////////////////////////////////////////
423 void CharacterJoint::
424 get_transform(LMatrix4 &transform) const {
425  transform = _value;
426 }
427 
428 CPT(TransformState) CharacterJoint::
429 get_transform_state() const {
430  return TransformState::make_mat( _value );
431 }
432 
433 ////////////////////////////////////////////////////////////////////
434 // Function: CharacterJoint::get_net_transform
435 // Access: Published
436 // Description: Copies the joint's current net transform (composed
437 // from the root of the character joint hierarchy) into
438 // the indicated matrix.
439 ////////////////////////////////////////////////////////////////////
440 void CharacterJoint::
441 get_net_transform(LMatrix4 &transform) const {
442  transform = _net_transform;
443 }
444 
445 ////////////////////////////////////////////////////////////////////
446 // Function: CharacterJoint::get_character
447 // Access: Published
448 // Description: Returns the Character that owns this joint.
449 ////////////////////////////////////////////////////////////////////
450 Character *CharacterJoint::
451 get_character() const {
452  return _character;
453 }
454 
455 ////////////////////////////////////////////////////////////////////
456 // Function: CharacterJoint::set_character
457 // Access: Private
458 // Description: Changes the Character that owns this joint.
459 ////////////////////////////////////////////////////////////////////
460 void CharacterJoint::
461 set_character(Character *character) {
462  if (character != _character) {
463 
464  if (character != (Character *)NULL) {
465  // Change or set a _character pointer on each joint's exposed
466  // node.
467  NodeList::iterator ai;
468  for (ai = _net_transform_nodes.begin();
469  ai != _net_transform_nodes.end();
470  ++ai) {
471  PandaNode *node = *ai;
472  node->set_effect(CharacterJointEffect::make(character));
473  }
474  for (ai = _local_transform_nodes.begin();
475  ai != _local_transform_nodes.end();
476  ++ai) {
477  PandaNode *node = *ai;
478  node->set_effect(CharacterJointEffect::make(character));
479  }
480 
481  } else { // (character == (Character *)NULL)
482  // Clear the _character pointer on each joint's exposed node.
483  NodeList::iterator ai;
484  for (ai = _net_transform_nodes.begin();
485  ai != _net_transform_nodes.end();
486  ++ai) {
487  PandaNode *node = *ai;
488 
489  CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
490  if (effect != (RenderEffect *)NULL &&
491  DCAST(CharacterJointEffect, effect)->get_character() == _character) {
492  node->clear_effect(CharacterJointEffect::get_class_type());
493  }
494  }
495  for (ai = _local_transform_nodes.begin();
496  ai != _local_transform_nodes.end();
497  ++ai) {
498  PandaNode *node = *ai;
499 
500  CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
501  if (effect != (RenderEffect *)NULL &&
502  DCAST(CharacterJointEffect, effect)->get_character() == _character) {
503  node->clear_effect(CharacterJointEffect::get_class_type());
504  }
505  }
506  }
507  }
508 
509  _character = character;
510 }
511 
512 ////////////////////////////////////////////////////////////////////
513 // Function: CharacterJoint::write_datagram
514 // Access: Public
515 // Description: Function to write the important information in
516 // the particular object to a Datagram
517 ////////////////////////////////////////////////////////////////////
518 void CharacterJoint::
520  NodeList::iterator ni;
522 
523  manager->write_pointer(me, _character);
524 
525  me.add_uint16(_net_transform_nodes.size());
526  for (ni = _net_transform_nodes.begin();
527  ni != _net_transform_nodes.end();
528  ni++) {
529  manager->write_pointer(me, (*ni));
530  }
531 
532  me.add_uint16(_local_transform_nodes.size());
533  for (ni = _local_transform_nodes.begin();
534  ni != _local_transform_nodes.end();
535  ni++) {
536  manager->write_pointer(me, (*ni));
537  }
538 
539  _initial_net_transform_inverse.write_datagram(me);
540 }
541 
542 ////////////////////////////////////////////////////////////////////
543 // Function: CharacterJoint::fillin
544 // Access: Protected
545 // Description: Function that reads out of the datagram (or asks
546 // manager to read) all of the data that is needed to
547 // re-create this object and stores it in the appropiate
548 // place
549 ////////////////////////////////////////////////////////////////////
550 void CharacterJoint::
551 fillin(DatagramIterator &scan, BamReader *manager) {
552  int i;
553  MovingPartMatrix::fillin(scan, manager);
554 
555  if (manager->get_file_minor_ver() >= 4) {
556  manager->read_pointer(scan);
557  }
558 
559  _num_net_nodes = scan.get_uint16();
560  for(i = 0; i < _num_net_nodes; i++) {
561  manager->read_pointer(scan);
562  }
563 
564  _num_local_nodes = scan.get_uint16();
565  for(i = 0; i < _num_local_nodes; i++) {
566  manager->read_pointer(scan);
567  }
568 
569  _initial_net_transform_inverse.read_datagram(scan);
570 }
571 
572 ////////////////////////////////////////////////////////////////////
573 // Function: CharacterJoint::complete_pointers
574 // Access: Public
575 // Description: Takes in a vector of pointers to TypedWritable
576 // objects that correspond to all the requests for
577 // pointers that this object made to BamReader.
578 ////////////////////////////////////////////////////////////////////
581  int pi = MovingPartMatrix::complete_pointers(p_list, manager);
582 
583  if (manager->get_file_minor_ver() >= 4) {
584  _character = DCAST(Character, p_list[pi++]);
585  } else {
586  _character = NULL;
587  }
588 
589  int i;
590  for (i = 0; i < _num_net_nodes; i++) {
591  PandaNode *node = DCAST(PandaNode, p_list[pi++]);
592  _net_transform_nodes.insert(node);
593  }
594 
595  for (i = 0; i < _num_local_nodes; i++) {
596  PandaNode *node = DCAST(PandaNode, p_list[pi++]);
597  _local_transform_nodes.insert(node);
598  }
599 
600  return pi;
601 }
602 
603 ////////////////////////////////////////////////////////////////////
604 // Function: CharacterJoint::make_CharacterJoint
605 // Access: Protected
606 // Description: Factory method to generate a CharacterJoint object
607 ////////////////////////////////////////////////////////////////////
610  CharacterJoint *me = new CharacterJoint;
611  DatagramIterator scan;
612  BamReader *manager;
613 
614  parse_params(params, scan, manager);
615  me->fillin(scan, manager);
616  return me;
617 }
618 
619 ////////////////////////////////////////////////////////////////////
620 // Function: CharacterJoint::register_with_factory
621 // Access: Public, Static
622 // Description: Factory method to generate a CharacterJoint object
623 ////////////////////////////////////////////////////////////////////
624 void CharacterJoint::
627 }
628 
629 
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
void add_path(const NodePath &node_path)
Adds a new NodePath to the collection.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
An animated character, with skeleton-morph animation and either soft-skinned or hard-skinned vertices...
Definition: character.h:41
size_type_0 size() const
Returns the number of elements in the ordered vector.
void clear()
Removes all elements from the ordered vector.
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
bool has_net_transform(PandaNode *node) const
Returns true if the node is on the list of nodes that will be updated each frame with the joint&#39;s net...
This effect will be added automatically to a node by CharacterJoint::add_net_transform() and Characte...
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
bool add_net_transform(PandaNode *node)
Adds the indicated node to the list of nodes that will be updated each frame with the joint&#39;s net tra...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
This is the base class for a number of special render effects that may be set on scene graph nodes to...
Definition: renderEffect.h:56
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
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:555
bool empty() const
Returns true if the ordered vector is empty, false otherwise.
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
Definition: movingPart.I:119
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
Definition: bamReader.I:105
PN_uint16 get_uint16()
Extracts an unsigned 16-bit integer.
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
Definition: thread.I:145
void clear_local_transforms()
Removes all nodes from the list of nodes that will be updated each frame with the joint&#39;s local trans...
static TypedWritable * make_CharacterJoint(const FactoryParams &params)
Factory method to generate a CharacterJoint object.
static NodePath any_path(PandaNode *node, Thread *current_thread=Thread::get_current_thread())
Returns a new NodePath that represents any arbitrary path from the root to the indicated node...
Definition: nodePath.I:77
bool add_local_transform(PandaNode *node)
Adds the indicated node to the list of nodes that will be updated each frame with the joint&#39;s local t...
static void register_with_read_factory()
Factory method to generate a CharacterJoint object.
bool has_local_transform(PandaNode *node) const
Returns true if the node is on the list of nodes that will be updated each frame with the joint&#39;s loc...
void write_datagram(Datagram &destination) const
Writes the matrix to the Datagram using add_stdfloat().
Definition: lmatrix.cxx:1148
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
virtual bool is_character_joint() const
Returns true if this part is a CharacterJoint, false otherwise.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
void set_effect(const RenderEffect *effect)
Adds the indicated render effect to the scene graph on this node.
Definition: pandaNode.cxx:1174
void read_datagram(DatagramIterator &source)
Reads the matrix from the Datagram using get_stdfloat().
Definition: lmatrix.cxx:1162
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...
virtual bool is_character_joint() const
Returns true if this part is a CharacterJoint, false otherwise.
Definition: partGroup.cxx:65
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
This is a particular kind of MovingPart that accepts a matrix each frame.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
A thread; that is, a lightweight process.
Definition: thread.h:51
This is the root of a MovingPart hierarchy.
Definition: partBundle.h:49
size_type_0 count(const key_type_0 &key) const
Returns the number of elements that sort equivalent to the key that are in the vector.
This represents one joint of the character&#39;s animation, containing an animating transform matrix...
bool remove_net_transform(PandaNode *node)
Removes the indicated node from the list of nodes that will be updated each frame with the joint&#39;s ne...
void clear_net_transforms()
Removes all nodes from the list of nodes that will be updated each frame with the joint&#39;s net transfo...
bool remove_local_transform(PandaNode *node)
Removes the indicated node from the list of nodes that will be updated each frame with the joint&#39;s lo...
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin()...
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...
A class to retrieve the individual data elements previously stored in a Datagram. ...
NodePathCollection get_local_transforms()
Returns a list of the local transforms set for this node.
void clear_effect(TypeHandle type)
Removes the render effect of the given type from this node.
Definition: pandaNode.cxx:1194
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
NodePathCollection get_net_transforms()
Returns a list of the net transforms set for this node.
const LMatrix4 & get_transform() const
Returns the transform matrix of the joint.
virtual PartGroup * make_copy() const
Allocates and returns a new copy of the node.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
const LMatrix4 & get_root_xform() const
Returns the transform matrix which is implicitly applied at the root of the animated hierarchy...
Definition: partBundle.I:186
void set_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Sets the transform that will be applied to this node and below.
Definition: pandaNode.cxx:1267
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:658
virtual bool update_internals(PartBundle *root, PartGroup *parent, bool self_changed, bool parent_changed, Thread *current_thread)
This is called by do_update() whenever the part or some ancestor has changed values.
This is a set of zero or more NodePaths.
This is the base class for PartRoot and MovingPart.
Definition: partGroup.h:45