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