00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00028
00029
00030
00031 CharacterJoint::
00032 CharacterJoint() :
00033 _character(NULL)
00034 {
00035 }
00036
00037
00038
00039
00040
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
00050 }
00051
00052
00053
00054
00055
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
00067
00068 update_internals(root, parent, true, false, current_thread);
00069
00070
00071
00072 _initial_net_transform_inverse = invert(_net_transform);
00073 }
00074
00075
00076
00077
00078
00079
00080 CharacterJoint::
00081 ~CharacterJoint() {
00082 nassertv(_vertex_transforms.empty());
00083 nassertv(_character == (Character *)NULL);
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093 bool CharacterJoint::
00094 is_character_joint() const {
00095 return true;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104 PartGroup *CharacterJoint::
00105 make_copy() const {
00106 return new CharacterJoint(*this);
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
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
00132
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
00142
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
00163
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
00188
00189
00190
00191
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
00204
00205
00206
00207
00208
00209
00210
00211
00212
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
00226
00227
00228
00229
00230
00231
00232
00233
00234
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
00249
00250
00251
00252
00253
00254 bool CharacterJoint::
00255 has_net_transform(PandaNode *node) const {
00256 return (_net_transform_nodes.count(node) > 0);
00257 }
00258
00259
00260
00261
00262
00263
00264
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
00286
00287
00288
00289
00290
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
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
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
00336
00337
00338
00339
00340
00341
00342
00343
00344
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
00359
00360
00361
00362
00363
00364 bool CharacterJoint::
00365 has_local_transform(PandaNode *node) const {
00366 return (_local_transform_nodes.count(node) > 0);
00367 }
00368
00369
00370
00371
00372
00373
00374
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
00396
00397
00398
00399
00400
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
00419
00420
00421
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
00435
00436
00437
00438
00439
00440 void CharacterJoint::
00441 get_net_transform(LMatrix4 &transform) const {
00442 transform = _net_transform;
00443 }
00444
00445
00446
00447
00448
00449
00450 Character *CharacterJoint::
00451 get_character() const {
00452 return _character;
00453 }
00454
00455
00456
00457
00458
00459
00460 void CharacterJoint::
00461 set_character(Character *character) {
00462 if (character != _character) {
00463
00464 if (character != (Character *)NULL) {
00465
00466
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 {
00482
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
00514
00515
00516
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
00544
00545
00546
00547
00548
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
00574
00575
00576
00577
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
00605
00606
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
00621
00622
00623
00624 void CharacterJoint::
00625 register_with_read_factory() {
00626 BamReader::get_factory()->register_factory(get_class_type(), make_CharacterJoint);
00627 }
00628
00629