Panda3D

characterJoint.cxx

00001 // Filename: characterJoint.cxx
00002 // Created by:  drose (23Feb99)
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 #include "characterJoint.h"
00016 #include "config_char.h"
00017 #include "jointVertexTransform.h"
00018 #include "characterJointEffect.h"
00019 #include "datagram.h"
00020 #include "datagramIterator.h"
00021 #include "bamReader.h"
00022 #include "bamWriter.h"
00023 
00024 TypeHandle CharacterJoint::_type_handle;
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: CharacterJoint::Default Constructor
00028 //       Access: Protected
00029 //  Description: For internal use only.
00030 ////////////////////////////////////////////////////////////////////
00031 CharacterJoint::
00032 CharacterJoint() :
00033   _character(NULL)
00034 {
00035 }
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //     Function: CharacterJoint::Copy Constructor
00039 //       Access: Protected
00040 //  Description:
00041 ////////////////////////////////////////////////////////////////////
00042 CharacterJoint::
00043 CharacterJoint(const CharacterJoint &copy) :
00044   MovingPartMatrix(copy),
00045   _character(NULL),
00046   _net_transform(copy._net_transform),
00047   _initial_net_transform_inverse(copy._initial_net_transform_inverse)
00048 {
00049   // We don't copy the sets of transform nodes.
00050 }
00051 
00052 ////////////////////////////////////////////////////////////////////
00053 //     Function: CharacterJoint::Constructor
00054 //       Access: Public
00055 //  Description:
00056 ////////////////////////////////////////////////////////////////////
00057 CharacterJoint::
00058 CharacterJoint(Character *character,
00059                PartBundle *root, PartGroup *parent, const string &name,
00060                const LMatrix4 &default_value) :
00061   MovingPartMatrix(parent, name, default_value),
00062   _character(character)
00063 {
00064   Thread *current_thread = Thread::get_current_thread();
00065 
00066   // Now that we've constructed and we're in the tree, let's call
00067   // update_internals() to get our _net_transform set properly.
00068   update_internals(root, parent, true, false, current_thread);
00069 
00070   // And then compute its inverse.  This is needed for
00071   // ComputedVertices, during animation.
00072   _initial_net_transform_inverse = invert(_net_transform);
00073 }
00074 
00075 ////////////////////////////////////////////////////////////////////
00076 //     Function: CharacterJoint::Destructor
00077 //       Access: Public, Virtual
00078 //  Description:
00079 ////////////////////////////////////////////////////////////////////
00080 CharacterJoint::
00081 ~CharacterJoint() {
00082   nassertv(_vertex_transforms.empty());
00083   nassertv(_character == (Character *)NULL);
00084 }
00085 
00086 ////////////////////////////////////////////////////////////////////
00087 //     Function: CharacterJoint::is_character_joint
00088 //       Access: Public, Virtual
00089 //  Description: Returns true if this part is a CharacterJoint, false
00090 //               otherwise.  This is a tiny optimization over
00091 //               is_of_type(CharacterType::get_class_type()).
00092 ////////////////////////////////////////////////////////////////////
00093 bool CharacterJoint::
00094 is_character_joint() const {
00095   return true;
00096 }
00097 
00098 ////////////////////////////////////////////////////////////////////
00099 //     Function: CharacterJoint::make_copy
00100 //       Access: Public, Virtual
00101 //  Description: Allocates and returns a new copy of the node.
00102 //               Children are not copied, but see copy_subgraph().
00103 ////////////////////////////////////////////////////////////////////
00104 PartGroup *CharacterJoint::
00105 make_copy() const {
00106   return new CharacterJoint(*this);
00107 }
00108 
00109 ////////////////////////////////////////////////////////////////////
00110 //     Function: CharacterJoint::update_internals
00111 //       Access: Public, Virtual
00112 //  Description: This is called by do_update() whenever the part or
00113 //               some ancestor has changed values.  It is a hook for
00114 //               derived classes to update whatever cache they may
00115 //               have that depends on these.
00116 //
00117 //               The return value is true if the part has changed as a
00118 //               result of the update, or false otherwise.
00119 //
00120 //               In the case of a CharacterJoint, of course, it means
00121 //               to recompute the joint angles and associated
00122 //               transforms for this particular joint.
00123 ////////////////////////////////////////////////////////////////////
00124 bool CharacterJoint::
00125 update_internals(PartBundle *root, PartGroup *parent, bool self_changed, 
00126                  bool parent_changed, Thread *current_thread) {
00127   nassertr(parent != (PartGroup *)NULL, false);
00128 
00129   bool net_changed = false;
00130   if (parent->is_character_joint()) {
00131     // The joint is not a toplevel joint; its parent therefore affects
00132     // its net transform.
00133     if (parent_changed || self_changed) {
00134       CharacterJoint *parent_joint = DCAST(CharacterJoint, parent);
00135       
00136       _net_transform = _value * parent_joint->_net_transform;
00137       net_changed = true;
00138     }
00139 
00140   } else {
00141     // The joint is a toplevel joint, so therefore it gets its root
00142     // transform from the bundle.
00143     if (self_changed) {
00144       _net_transform = _value * root->get_root_xform();
00145       net_changed = true;
00146     }
00147   }
00148 
00149   if (net_changed) {
00150     if (!_net_transform_nodes.empty()) {
00151       CPT(TransformState) t = TransformState::make_mat(_net_transform);
00152       
00153       NodeList::iterator ai;
00154       for (ai = _net_transform_nodes.begin();
00155            ai != _net_transform_nodes.end();
00156            ++ai) {
00157         PandaNode *node = *ai;
00158         node->set_transform(t, current_thread);
00159       }
00160     }
00161 
00162     // Also tell our related JointVertexTransforms that they now need
00163     // to recompute themselves.
00164     VertexTransforms::iterator vti;
00165     for (vti = _vertex_transforms.begin(); vti != _vertex_transforms.end(); ++vti) {
00166       (*vti)->_matrix_stale = true;
00167       (*vti)->mark_modified(current_thread);
00168     }
00169   }
00170 
00171   if (self_changed && !_local_transform_nodes.empty()) {
00172     CPT(TransformState) t = TransformState::make_mat(_value);
00173 
00174     NodeList::iterator ai;
00175     for (ai = _local_transform_nodes.begin();
00176          ai != _local_transform_nodes.end();
00177          ++ai) {
00178       PandaNode *node = *ai;
00179       node->set_transform(t, current_thread);
00180     }
00181   }
00182 
00183   return self_changed || net_changed;
00184 }
00185 
00186 ////////////////////////////////////////////////////////////////////
00187 //     Function: CharacterJoint::do_xform
00188 //       Access: Public, Virtual
00189 //  Description: Called by PartBundle::xform(), this indicates the
00190 //               indicated transform is being applied to the root
00191 //               joint.
00192 ////////////////////////////////////////////////////////////////////
00193 void CharacterJoint::
00194 do_xform(const LMatrix4 &mat, const LMatrix4 &inv_mat) {
00195   _initial_net_transform_inverse = inv_mat * _initial_net_transform_inverse;
00196 
00197   MovingPartMatrix::do_xform(mat, inv_mat);
00198 }
00199 
00200 
00201 
00202 ////////////////////////////////////////////////////////////////////
00203 //     Function: CharacterJoint::add_net_transform
00204 //       Access: Published
00205 //  Description: Adds the indicated node to the list of nodes that will
00206 //               be updated each frame with the joint's net transform
00207 //               from the root.  Returns true if the node is
00208 //               successfully added, false if it had already been
00209 //               added.
00210 //
00211 //               A CharacterJointEffect for this joint's Character
00212 //               will automatically be added to the specified node.
00213 ////////////////////////////////////////////////////////////////////
00214 bool CharacterJoint::
00215 add_net_transform(PandaNode *node) {
00216   if (_character != (Character *)NULL) {
00217     node->set_effect(CharacterJointEffect::make(_character));
00218   }
00219   CPT(TransformState) t = TransformState::make_mat(_net_transform);
00220   node->set_transform(t, Thread::get_current_thread());
00221   return _net_transform_nodes.insert(node).second;
00222 }
00223 
00224 ////////////////////////////////////////////////////////////////////
00225 //     Function: CharacterJoint::remove_net_transform
00226 //       Access: Published
00227 //  Description: Removes the indicated node from the list of nodes that
00228 //               will be updated each frame with the joint's net
00229 //               transform from the root.  Returns true if the node is
00230 //               successfully removed, false if it was not on the
00231 //               list.
00232 //
00233 //               If the node has a CharacterJointEffect that matches
00234 //               this joint's Character, it will be cleared.
00235 ////////////////////////////////////////////////////////////////////
00236 bool CharacterJoint::
00237 remove_net_transform(PandaNode *node) {
00238   CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
00239   if (effect != (RenderEffect *)NULL &&
00240       DCAST(CharacterJointEffect, effect)->get_character() == _character) {
00241     node->clear_effect(CharacterJointEffect::get_class_type());
00242   }
00243 
00244   return (_net_transform_nodes.erase(node) > 0);
00245 }
00246 
00247 ////////////////////////////////////////////////////////////////////
00248 //     Function: CharacterJoint::has_net_transform
00249 //       Access: Published
00250 //  Description: Returns true if the node is on the list of nodes that
00251 //               will be updated each frame with the joint's net
00252 //               transform from the root, false otherwise.
00253 ////////////////////////////////////////////////////////////////////
00254 bool CharacterJoint::
00255 has_net_transform(PandaNode *node) const {
00256   return (_net_transform_nodes.count(node) > 0);
00257 }
00258 
00259 ////////////////////////////////////////////////////////////////////
00260 //     Function: CharacterJoint::clear_net_transforms
00261 //       Access: Published
00262 //  Description: Removes all nodes from the list of nodes that will be
00263 //               updated each frame with the joint's net transform
00264 //               from the root.
00265 ////////////////////////////////////////////////////////////////////
00266 void CharacterJoint::
00267 clear_net_transforms() {
00268   NodeList::iterator ai;
00269   for (ai = _net_transform_nodes.begin();
00270        ai != _net_transform_nodes.end();
00271        ++ai) {
00272     PandaNode *node = *ai;
00273 
00274     CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
00275     if (effect != (RenderEffect *)NULL &&
00276         DCAST(CharacterJointEffect, effect)->get_character() == _character) {
00277       node->clear_effect(CharacterJointEffect::get_class_type());
00278     }
00279   }
00280 
00281   _net_transform_nodes.clear();
00282 }
00283 
00284 ////////////////////////////////////////////////////////////////////
00285 //     Function: CharacterJoint::get_net_transforms
00286 //       Access: Published
00287 //  Description: Returns a list of the net transforms set for this
00288 //               node.  Note that this returns a list of NodePaths,
00289 //               even though the net transforms are actually a list of
00290 //               PandaNodes.
00291 ////////////////////////////////////////////////////////////////////
00292 NodePathCollection CharacterJoint::
00293 get_net_transforms() {
00294   NodePathCollection npc;
00295 
00296   NodeList::iterator ai;
00297   for (ai = _net_transform_nodes.begin();
00298        ai != _net_transform_nodes.end();
00299        ++ai) {
00300     PandaNode *node = *ai;
00301     npc.add_path(NodePath::any_path(node));
00302   }
00303 
00304   return npc;
00305 }
00306 
00307 ////////////////////////////////////////////////////////////////////
00308 //     Function: CharacterJoint::add_local_transform
00309 //       Access: Published
00310 //  Description: Adds the indicated node to the list of nodes that will
00311 //               be updated each frame with the joint's local
00312 //               transform from its parent.  Returns true if the node
00313 //               is successfully added, false if it had already been
00314 //               added.
00315 //
00316 //               The Character pointer should be the Character object
00317 //               that owns this joint; this will be used to create a
00318 //               CharacterJointEffect for this node.  If it is NULL,
00319 //               no such effect will be created.
00320 //
00321 //               A CharacterJointEffect for this joint's Character
00322 //               will automatically be added to the specified node.
00323 ////////////////////////////////////////////////////////////////////
00324 bool CharacterJoint::
00325 add_local_transform(PandaNode *node) {
00326   if (_character != (Character *)NULL) {
00327     node->set_effect(CharacterJointEffect::make(_character));
00328   }
00329   CPT(TransformState) t = TransformState::make_mat(_value);
00330   node->set_transform(t, Thread::get_current_thread());
00331   return _local_transform_nodes.insert(node).second;
00332 }
00333 
00334 ////////////////////////////////////////////////////////////////////
00335 //     Function: CharacterJoint::remove_local_transform
00336 //       Access: Published
00337 //  Description: Removes the indicated node from the list of nodes that
00338 //               will be updated each frame with the joint's local
00339 //               transform from its parent.  Returns true if the node
00340 //               is successfully removed, false if it was not on the
00341 //               list.
00342 //
00343 //               If the node has a CharacterJointEffect that matches
00344 //               this joint's Character, it will be cleared.
00345 ////////////////////////////////////////////////////////////////////
00346 bool CharacterJoint::
00347 remove_local_transform(PandaNode *node) {
00348   CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
00349   if (effect != (RenderEffect *)NULL &&
00350       DCAST(CharacterJointEffect, effect)->get_character() == _character) {
00351     node->clear_effect(CharacterJointEffect::get_class_type());
00352   }
00353 
00354   return (_local_transform_nodes.erase(node) > 0);
00355 }
00356 
00357 ////////////////////////////////////////////////////////////////////
00358 //     Function: CharacterJoint::has_local_transform
00359 //       Access: Published
00360 //  Description: Returns true if the node is on the list of nodes that
00361 //               will be updated each frame with the joint's local
00362 //               transform from its parent, false otherwise.
00363 ////////////////////////////////////////////////////////////////////
00364 bool CharacterJoint::
00365 has_local_transform(PandaNode *node) const {
00366   return (_local_transform_nodes.count(node) > 0);
00367 }
00368 
00369 ////////////////////////////////////////////////////////////////////
00370 //     Function: CharacterJoint::clear_local_transforms
00371 //       Access: Published
00372 //  Description: Removes all nodes from the list of nodes that will be
00373 //               updated each frame with the joint's local transform
00374 //               from its parent.
00375 ////////////////////////////////////////////////////////////////////
00376 void CharacterJoint::
00377 clear_local_transforms() {
00378   NodeList::iterator ai;
00379   for (ai = _local_transform_nodes.begin();
00380        ai != _local_transform_nodes.end();
00381        ++ai) {
00382     PandaNode *node = *ai;
00383 
00384     CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
00385     if (effect != (RenderEffect *)NULL &&
00386         DCAST(CharacterJointEffect, effect)->get_character() == _character) {
00387       node->clear_effect(CharacterJointEffect::get_class_type());
00388     }
00389   }
00390 
00391   _local_transform_nodes.clear();
00392 }
00393 
00394 ////////////////////////////////////////////////////////////////////
00395 //     Function: CharacterJoint::get_local_transforms
00396 //       Access: Published
00397 //  Description: Returns a list of the local transforms set for this
00398 //               node.  Note that this returns a list of NodePaths,
00399 //               even though the local transforms are actually a list of
00400 //               PandaNodes.
00401 ////////////////////////////////////////////////////////////////////
00402 NodePathCollection CharacterJoint::
00403 get_local_transforms() {
00404   NodePathCollection npc;
00405 
00406   NodeList::iterator ai;
00407   for (ai = _local_transform_nodes.begin();
00408        ai != _local_transform_nodes.end();
00409        ++ai) {
00410     PandaNode *node = *ai;
00411     npc.add_path(NodePath::any_path(node));
00412   }
00413 
00414   return npc;
00415 }
00416 
00417 ////////////////////////////////////////////////////////////////////
00418 //     Function: CharacterJoint::get_transform
00419 //       Access: Published
00420 //  Description: Copies the joint's current transform into the
00421 //               indicated matrix.
00422 ////////////////////////////////////////////////////////////////////
00423 void CharacterJoint::
00424 get_transform(LMatrix4 &transform) const {
00425   transform = _value;
00426 }
00427 
00428 CPT(TransformState) CharacterJoint::
00429 get_transform_state() const {
00430     return TransformState::make_mat( _value );
00431 }
00432 
00433 ////////////////////////////////////////////////////////////////////
00434 //     Function: CharacterJoint::get_net_transform
00435 //       Access: Published
00436 //  Description: Copies the joint's current net transform (composed
00437 //               from the root of the character joint hierarchy) into
00438 //               the indicated matrix.
00439 ////////////////////////////////////////////////////////////////////
00440 void CharacterJoint::
00441 get_net_transform(LMatrix4 &transform) const {
00442   transform = _net_transform;
00443 }
00444 
00445 ////////////////////////////////////////////////////////////////////
00446 //     Function: CharacterJoint::get_character
00447 //       Access: Published
00448 //  Description: Returns the Character that owns this joint.
00449 ////////////////////////////////////////////////////////////////////
00450 Character *CharacterJoint::
00451 get_character() const {
00452   return _character;
00453 }
00454 
00455 ////////////////////////////////////////////////////////////////////
00456 //     Function: CharacterJoint::set_character
00457 //       Access: Private
00458 //  Description: Changes the Character that owns this joint.
00459 ////////////////////////////////////////////////////////////////////
00460 void CharacterJoint::
00461 set_character(Character *character) {
00462   if (character != _character) {
00463 
00464     if (character != (Character *)NULL) {
00465       // Change or set a _character pointer on each joint's exposed
00466       // node.
00467       NodeList::iterator ai;
00468       for (ai = _net_transform_nodes.begin();
00469            ai != _net_transform_nodes.end();
00470            ++ai) {
00471         PandaNode *node = *ai;
00472         node->set_effect(CharacterJointEffect::make(character));
00473       }
00474       for (ai = _local_transform_nodes.begin();
00475            ai != _local_transform_nodes.end();
00476            ++ai) {
00477         PandaNode *node = *ai;
00478         node->set_effect(CharacterJointEffect::make(character));
00479       }
00480 
00481     } else {  // (character == (Character *)NULL)
00482       // Clear the _character pointer on each joint's exposed node.
00483       NodeList::iterator ai;
00484       for (ai = _net_transform_nodes.begin();
00485            ai != _net_transform_nodes.end();
00486            ++ai) {
00487         PandaNode *node = *ai;
00488         
00489         CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
00490         if (effect != (RenderEffect *)NULL &&
00491             DCAST(CharacterJointEffect, effect)->get_character() == _character) {
00492           node->clear_effect(CharacterJointEffect::get_class_type());
00493         }
00494       }
00495       for (ai = _local_transform_nodes.begin();
00496            ai != _local_transform_nodes.end();
00497            ++ai) {
00498         PandaNode *node = *ai;
00499         
00500         CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
00501         if (effect != (RenderEffect *)NULL &&
00502             DCAST(CharacterJointEffect, effect)->get_character() == _character) {
00503           node->clear_effect(CharacterJointEffect::get_class_type());
00504         }
00505       }
00506     }
00507   }
00508     
00509   _character = character;
00510 }
00511 
00512 ////////////////////////////////////////////////////////////////////
00513 //     Function: CharacterJoint::write_datagram
00514 //       Access: Public
00515 //  Description: Function to write the important information in
00516 //               the particular object to a Datagram
00517 ////////////////////////////////////////////////////////////////////
00518 void CharacterJoint::
00519 write_datagram(BamWriter *manager, Datagram &me) {
00520   NodeList::iterator ni;
00521   MovingPartMatrix::write_datagram(manager, me);
00522 
00523   manager->write_pointer(me, _character);
00524 
00525   me.add_uint16(_net_transform_nodes.size());
00526   for (ni = _net_transform_nodes.begin(); 
00527        ni != _net_transform_nodes.end(); 
00528        ni++) {
00529     manager->write_pointer(me, (*ni));
00530   }
00531 
00532   me.add_uint16(_local_transform_nodes.size());
00533   for (ni = _local_transform_nodes.begin(); 
00534        ni != _local_transform_nodes.end(); 
00535        ni++) {
00536     manager->write_pointer(me, (*ni));
00537   }
00538 
00539   _initial_net_transform_inverse.write_datagram(me);
00540 }
00541 
00542 ////////////////////////////////////////////////////////////////////
00543 //     Function: CharacterJoint::fillin
00544 //       Access: Protected
00545 //  Description: Function that reads out of the datagram (or asks
00546 //               manager to read) all of the data that is needed to
00547 //               re-create this object and stores it in the appropiate
00548 //               place
00549 ////////////////////////////////////////////////////////////////////
00550 void CharacterJoint::
00551 fillin(DatagramIterator &scan, BamReader *manager) {
00552   int i;
00553   MovingPartMatrix::fillin(scan, manager);
00554 
00555   if (manager->get_file_minor_ver() >= 4) {
00556     manager->read_pointer(scan);
00557   }
00558 
00559   _num_net_nodes = scan.get_uint16();
00560   for(i = 0; i < _num_net_nodes; i++) {
00561     manager->read_pointer(scan);
00562   }
00563   
00564   _num_local_nodes = scan.get_uint16();
00565   for(i = 0; i < _num_local_nodes; i++) {
00566     manager->read_pointer(scan);
00567   }
00568 
00569   _initial_net_transform_inverse.read_datagram(scan);
00570 }
00571 
00572 ////////////////////////////////////////////////////////////////////
00573 //     Function: CharacterJoint::complete_pointers
00574 //       Access: Public
00575 //  Description: Takes in a vector of pointers to TypedWritable
00576 //               objects that correspond to all the requests for
00577 //               pointers that this object made to BamReader.
00578 ////////////////////////////////////////////////////////////////////
00579 int CharacterJoint::
00580 complete_pointers(TypedWritable **p_list, BamReader* manager) {
00581   int pi = MovingPartMatrix::complete_pointers(p_list, manager);
00582 
00583   if (manager->get_file_minor_ver() >= 4) {
00584     _character = DCAST(Character, p_list[pi++]);
00585   } else {
00586     _character = NULL;
00587   }
00588 
00589   int i;
00590   for (i = 0; i < _num_net_nodes; i++) {
00591     PandaNode *node = DCAST(PandaNode, p_list[pi++]);
00592     _net_transform_nodes.insert(node);
00593   }
00594 
00595   for (i = 0; i < _num_local_nodes; i++) {
00596     PandaNode *node = DCAST(PandaNode, p_list[pi++]);
00597     _local_transform_nodes.insert(node);
00598   }
00599 
00600   return pi;
00601 }
00602 
00603 ////////////////////////////////////////////////////////////////////
00604 //     Function: CharacterJoint::make_CharacterJoint
00605 //       Access: Protected
00606 //  Description: Factory method to generate a CharacterJoint object
00607 ////////////////////////////////////////////////////////////////////
00608 TypedWritable* CharacterJoint::
00609 make_CharacterJoint(const FactoryParams &params) {
00610   CharacterJoint *me = new CharacterJoint;
00611   DatagramIterator scan;
00612   BamReader *manager;
00613 
00614   parse_params(params, scan, manager);
00615   me->fillin(scan, manager);
00616   return me;
00617 }
00618 
00619 ////////////////////////////////////////////////////////////////////
00620 //     Function: CharacterJoint::register_with_factory
00621 //       Access: Public, Static
00622 //  Description: Factory method to generate a CharacterJoint object
00623 ////////////////////////////////////////////////////////////////////
00624 void CharacterJoint::
00625 register_with_read_factory() {
00626   BamReader::get_factory()->register_factory(get_class_type(), make_CharacterJoint);
00627 }
00628 
00629 
 All Classes Functions Variables Enumerations