Panda3D
|
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 ©) : 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 ¶ms) { 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