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 LMatrix4f &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 LMatrix4f &mat, const LMatrix4f &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(LMatrix4f &transform) const {
00425   transform = _value;
00426 }
00427 
00428 ////////////////////////////////////////////////////////////////////
00429 //     Function: CharacterJoint::get_net_transform
00430 //       Access: Published
00431 //  Description: Copies the joint's current net transform (composed
00432 //               from the root of the character joint hierarchy) into
00433 //               the indicated matrix.
00434 ////////////////////////////////////////////////////////////////////
00435 void CharacterJoint::
00436 get_net_transform(LMatrix4f &transform) const {
00437   transform = _net_transform;
00438 }
00439 
00440 ////////////////////////////////////////////////////////////////////
00441 //     Function: CharacterJoint::get_character
00442 //       Access: Published
00443 //  Description: Returns the Character that owns this joint.
00444 ////////////////////////////////////////////////////////////////////
00445 Character *CharacterJoint::
00446 get_character() const {
00447   return _character;
00448 }
00449 
00450 ////////////////////////////////////////////////////////////////////
00451 //     Function: CharacterJoint::set_character
00452 //       Access: Private
00453 //  Description: Changes the Character that owns this joint.
00454 ////////////////////////////////////////////////////////////////////
00455 void CharacterJoint::
00456 set_character(Character *character) {
00457   if (character != _character) {
00458 
00459     if (character != (Character *)NULL) {
00460       // Change or set a _character pointer on each joint's exposed
00461       // node.
00462       NodeList::iterator ai;
00463       for (ai = _net_transform_nodes.begin();
00464            ai != _net_transform_nodes.end();
00465            ++ai) {
00466         PandaNode *node = *ai;
00467         node->set_effect(CharacterJointEffect::make(character));
00468       }
00469       for (ai = _local_transform_nodes.begin();
00470            ai != _local_transform_nodes.end();
00471            ++ai) {
00472         PandaNode *node = *ai;
00473         node->set_effect(CharacterJointEffect::make(character));
00474       }
00475 
00476     } else {  // (character == (Character *)NULL)
00477       // Clear the _character pointer on each joint's exposed node.
00478       NodeList::iterator ai;
00479       for (ai = _net_transform_nodes.begin();
00480            ai != _net_transform_nodes.end();
00481            ++ai) {
00482         PandaNode *node = *ai;
00483         
00484         CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
00485         if (effect != (RenderEffect *)NULL &&
00486             DCAST(CharacterJointEffect, effect)->get_character() == _character) {
00487           node->clear_effect(CharacterJointEffect::get_class_type());
00488         }
00489       }
00490       for (ai = _local_transform_nodes.begin();
00491            ai != _local_transform_nodes.end();
00492            ++ai) {
00493         PandaNode *node = *ai;
00494         
00495         CPT(RenderEffect) effect = node->get_effect(CharacterJointEffect::get_class_type());
00496         if (effect != (RenderEffect *)NULL &&
00497             DCAST(CharacterJointEffect, effect)->get_character() == _character) {
00498           node->clear_effect(CharacterJointEffect::get_class_type());
00499         }
00500       }
00501     }
00502   }
00503     
00504   _character = character;
00505 }
00506 
00507 ////////////////////////////////////////////////////////////////////
00508 //     Function: CharacterJoint::write_datagram
00509 //       Access: Public
00510 //  Description: Function to write the important information in
00511 //               the particular object to a Datagram
00512 ////////////////////////////////////////////////////////////////////
00513 void CharacterJoint::
00514 write_datagram(BamWriter *manager, Datagram &me) {
00515   NodeList::iterator ni;
00516   MovingPartMatrix::write_datagram(manager, me);
00517 
00518   manager->write_pointer(me, _character);
00519 
00520   me.add_uint16(_net_transform_nodes.size());
00521   for (ni = _net_transform_nodes.begin(); 
00522        ni != _net_transform_nodes.end(); 
00523        ni++) {
00524     manager->write_pointer(me, (*ni));
00525   }
00526 
00527   me.add_uint16(_local_transform_nodes.size());
00528   for (ni = _local_transform_nodes.begin(); 
00529        ni != _local_transform_nodes.end(); 
00530        ni++) {
00531     manager->write_pointer(me, (*ni));
00532   }
00533 
00534   _initial_net_transform_inverse.write_datagram(me);
00535 }
00536 
00537 ////////////////////////////////////////////////////////////////////
00538 //     Function: CharacterJoint::fillin
00539 //       Access: Protected
00540 //  Description: Function that reads out of the datagram (or asks
00541 //               manager to read) all of the data that is needed to
00542 //               re-create this object and stores it in the appropiate
00543 //               place
00544 ////////////////////////////////////////////////////////////////////
00545 void CharacterJoint::
00546 fillin(DatagramIterator &scan, BamReader *manager) {
00547   int i;
00548   MovingPartMatrix::fillin(scan, manager);
00549 
00550   if (manager->get_file_minor_ver() >= 4) {
00551     manager->read_pointer(scan);
00552   }
00553 
00554   _num_net_nodes = scan.get_uint16();
00555   for(i = 0; i < _num_net_nodes; i++) {
00556     manager->read_pointer(scan);
00557   }
00558   
00559   _num_local_nodes = scan.get_uint16();
00560   for(i = 0; i < _num_local_nodes; i++) {
00561     manager->read_pointer(scan);
00562   }
00563 
00564   _initial_net_transform_inverse.read_datagram(scan);
00565 }
00566 
00567 ////////////////////////////////////////////////////////////////////
00568 //     Function: CharacterJoint::complete_pointers
00569 //       Access: Public
00570 //  Description: Takes in a vector of pointers to TypedWritable
00571 //               objects that correspond to all the requests for
00572 //               pointers that this object made to BamReader.
00573 ////////////////////////////////////////////////////////////////////
00574 int CharacterJoint::
00575 complete_pointers(TypedWritable **p_list, BamReader* manager) {
00576   int pi = MovingPartMatrix::complete_pointers(p_list, manager);
00577 
00578   if (manager->get_file_minor_ver() >= 4) {
00579     _character = DCAST(Character, p_list[pi++]);
00580   } else {
00581     _character = NULL;
00582   }
00583 
00584   int i;
00585   for (i = 0; i < _num_net_nodes; i++) {
00586     PandaNode *node = DCAST(PandaNode, p_list[pi++]);
00587     _net_transform_nodes.insert(node);
00588   }
00589 
00590   for (i = 0; i < _num_local_nodes; i++) {
00591     PandaNode *node = DCAST(PandaNode, p_list[pi++]);
00592     _local_transform_nodes.insert(node);
00593   }
00594 
00595   return pi;
00596 }
00597 
00598 ////////////////////////////////////////////////////////////////////
00599 //     Function: CharacterJoint::make_CharacterJoint
00600 //       Access: Protected
00601 //  Description: Factory method to generate a CharacterJoint object
00602 ////////////////////////////////////////////////////////////////////
00603 TypedWritable* CharacterJoint::
00604 make_CharacterJoint(const FactoryParams &params) {
00605   CharacterJoint *me = new CharacterJoint;
00606   DatagramIterator scan;
00607   BamReader *manager;
00608 
00609   parse_params(params, scan, manager);
00610   me->fillin(scan, manager);
00611   return me;
00612 }
00613 
00614 ////////////////////////////////////////////////////////////////////
00615 //     Function: CharacterJoint::register_with_factory
00616 //       Access: Public, Static
00617 //  Description: Factory method to generate a CharacterJoint object
00618 ////////////////////////////////////////////////////////////////////
00619 void CharacterJoint::
00620 register_with_read_factory() {
00621   BamReader::get_factory()->register_factory(get_class_type(), make_CharacterJoint);
00622 }
00623 
00624 
 All Classes Functions Variables Enumerations