00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "transformState.h"
00020 #include "compose_matrix.h"
00021 #include "bamReader.h"
00022 #include "bamWriter.h"
00023 #include "datagramIterator.h"
00024 #include "indent.h"
00025 #include "compareTo.h"
00026
00027 TransformState::States *TransformState::_states = NULL;
00028 CPT(TransformState) TransformState::_identity_state;
00029 TypeHandle TransformState::_type_handle;
00030 TypeHandle EventStoreTransform::_type_handle;
00031
00032
00033
00034
00035
00036
00037
00038
00039 TransformState::
00040 TransformState() {
00041 if (_states == (States *)NULL) {
00042
00043
00044
00045
00046
00047 _states = new States;
00048 }
00049 _saved_entry = _states->end();
00050 _self_compose = (TransformState *)NULL;
00051 _flags = F_is_identity | F_singular_known;
00052 _inv_mat = (LMatrix4f *)NULL;
00053 }
00054
00055
00056
00057
00058
00059
00060 TransformState::
00061 TransformState(const TransformState &) {
00062 nassertv(false);
00063 }
00064
00065
00066
00067
00068
00069
00070 void TransformState::
00071 operator = (const TransformState &) {
00072 nassertv(false);
00073 }
00074
00075
00076
00077
00078
00079
00080
00081 TransformState::
00082 ~TransformState() {
00083
00084 nassertv(!is_destructing());
00085 set_destructing();
00086
00087
00088 if (_inv_mat != (LMatrix4f *)NULL) {
00089 delete _inv_mat;
00090 }
00091
00092
00093 if (_saved_entry != _states->end()) {
00094 nassertv(_states->find(this) == _saved_entry);
00095 _states->erase(_saved_entry);
00096 _saved_entry = _states->end();
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 while (!_composition_cache.empty()) {
00121 CompositionCache::iterator ci = _composition_cache.begin();
00122
00123
00124
00125
00126
00127
00128
00129
00130 TransformState *other = (TransformState *)(*ci).first;
00131
00132
00133
00134 nassertv(other != this);
00135
00136
00137
00138
00139 Composition comp = (*ci).second;
00140
00141
00142
00143
00144
00145 _composition_cache.erase(ci);
00146
00147 CompositionCache::iterator oci = other->_composition_cache.find(this);
00148
00149
00150
00151
00152 if (oci != other->_composition_cache.end()) {
00153
00154 Composition ocomp = (*oci).second;
00155
00156
00157
00158
00159 other->_composition_cache.erase(oci);
00160 }
00161
00162
00163
00164
00165
00166 }
00167
00168
00169 while (!_invert_composition_cache.empty()) {
00170 CompositionCache::iterator ci = _invert_composition_cache.begin();
00171 TransformState *other = (TransformState *)(*ci).first;
00172 nassertv(other != this);
00173 Composition comp = (*ci).second;
00174 _invert_composition_cache.erase(ci);
00175 CompositionCache::iterator oci =
00176 other->_invert_composition_cache.find(this);
00177 if (oci != other->_invert_composition_cache.end()) {
00178 Composition ocomp = (*oci).second;
00179 other->_invert_composition_cache.erase(oci);
00180 }
00181 }
00182
00183
00184
00185
00186 if (_self_compose != (TransformState *)NULL && _self_compose != this) {
00187 unref_delete((TransformState *)_self_compose);
00188 }
00189
00190
00191
00192 nassertv(get_ref_count() == 0);
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 bool TransformState::
00208 operator < (const TransformState &other) const {
00209 static const int significant_flags =
00210 (F_is_invalid | F_is_identity | F_components_given | F_hpr_given);
00211
00212 int flags = (_flags & significant_flags);
00213 int other_flags = (other._flags & significant_flags);
00214 if (flags != other_flags) {
00215 return flags < other_flags;
00216 }
00217
00218 if ((_flags & (F_is_invalid | F_is_identity)) != 0) {
00219
00220
00221 return 0;
00222 }
00223
00224 if ((_flags & (F_components_given | F_hpr_given | F_quat_given)) ==
00225 (F_components_given | F_hpr_given | F_quat_given)) {
00226
00227
00228 int c = _pos.compare_to(other._pos);
00229 if (c != 0) {
00230 return c < 0;
00231 }
00232
00233 if ((_flags & F_hpr_given) != 0) {
00234 c = _hpr.compare_to(other._hpr);
00235 if (c != 0) {
00236 return c < 0;
00237 }
00238 } else if ((_flags & F_quat_given) != 0) {
00239 c = _quat.compare_to(other._quat);
00240 if (c != 0) {
00241 return c < 0;
00242 }
00243 }
00244
00245 c = _scale.compare_to(other._scale);
00246 return c < 0;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 return (this < &other);
00263 }
00264
00265
00266
00267
00268
00269
00270 CPT(TransformState) TransformState::
00271 make_identity() {
00272
00273
00274 if (_identity_state == (TransformState *)NULL) {
00275 TransformState *state = new TransformState;
00276 _identity_state = return_new(state);
00277 }
00278
00279 return _identity_state;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288 CPT(TransformState) TransformState::
00289 make_invalid() {
00290 TransformState *state = new TransformState;
00291 state->_flags = F_is_invalid | F_singular_known | F_is_singular | F_components_known | F_mat_known;
00292 return return_new(state);
00293 }
00294
00295
00296
00297
00298
00299
00300
00301 CPT(TransformState) TransformState::
00302 make_pos_hpr_scale(const LVecBase3f &pos, const LVecBase3f &hpr,
00303 const LVecBase3f &scale) {
00304
00305 if (pos == LVecBase3f(0.0f, 0.0f, 0.0f) &&
00306 hpr == LVecBase3f(0.0f, 0.0f, 0.0f) &&
00307 scale == LVecBase3f(1.0f, 1.0f, 1.0f)) {
00308 return make_identity();
00309 }
00310
00311 TransformState *state = new TransformState;
00312 state->_pos = pos;
00313 state->_hpr = hpr;
00314 state->_scale = scale;
00315 state->_flags = F_components_given | F_hpr_given | F_components_known | F_hpr_known | F_has_components;
00316 state->check_uniform_scale();
00317 return return_new(state);
00318 }
00319
00320
00321
00322
00323
00324
00325
00326 CPT(TransformState) TransformState::
00327 make_pos_quat_scale(const LVecBase3f &pos, const LQuaternionf &quat,
00328 const LVecBase3f &scale) {
00329
00330 if (pos == LVecBase3f(0.0f, 0.0f, 0.0f) &&
00331 quat == LQuaternionf::ident_quat() &&
00332 scale == LVecBase3f(1.0f, 1.0f, 1.0f)) {
00333 return make_identity();
00334 }
00335
00336 TransformState *state = new TransformState;
00337 state->_pos = pos;
00338 state->_quat = quat;
00339 state->_scale = scale;
00340 state->_flags = F_components_given | F_quat_given | F_components_known | F_quat_known | F_has_components;
00341 state->check_uniform_scale();
00342 return return_new(state);
00343 }
00344
00345
00346
00347
00348
00349
00350
00351 CPT(TransformState) TransformState::
00352 make_mat(const LMatrix4f &mat) {
00353
00354 if (mat == LMatrix4f::ident_mat()) {
00355 return make_identity();
00356 }
00357
00358 TransformState *state = new TransformState;
00359 state->_mat = mat;
00360 state->_flags = F_mat_known;
00361 return return_new(state);
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371 CPT(TransformState) TransformState::
00372 set_pos(const LVecBase3f &pos) const {
00373 nassertr(!is_invalid(), this);
00374 if (is_identity() || components_given()) {
00375
00376
00377 if (quat_given()) {
00378 return make_pos_quat_scale(pos, get_quat(), get_scale());
00379 } else {
00380 return make_pos_hpr_scale(pos, get_hpr(), get_scale());
00381 }
00382
00383 } else {
00384
00385 LMatrix4f mat = get_mat();
00386 mat.set_row(3, pos);
00387 return make_mat(mat);
00388 }
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398 CPT(TransformState) TransformState::
00399 set_hpr(const LVecBase3f &hpr) const {
00400 nassertr(!is_invalid(), this);
00401
00402 return make_pos_hpr_scale(get_pos(), hpr, get_scale());
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412 CPT(TransformState) TransformState::
00413 set_quat(const LQuaternionf &quat) const {
00414 nassertr(!is_invalid(), this);
00415
00416 return make_pos_quat_scale(get_pos(), quat, get_scale());
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426 CPT(TransformState) TransformState::
00427 set_scale(const LVecBase3f &scale) const {
00428 nassertr(!is_invalid(), this);
00429
00430 if (quat_given()) {
00431 return make_pos_quat_scale(get_pos(), get_quat(), scale);
00432 } else {
00433 return make_pos_hpr_scale(get_pos(), get_hpr(), scale);
00434 }
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 CPT(TransformState) TransformState::
00451 compose(const TransformState *other) const {
00452
00453
00454
00455
00456
00457 if (is_identity()) {
00458 return other;
00459 }
00460 if (other->is_identity()) {
00461 return this;
00462 }
00463
00464
00465 if (is_invalid()) {
00466 return this;
00467 }
00468 if (other->is_invalid()) {
00469 return other;
00470 }
00471
00472 if (other == this) {
00473
00474
00475 if (_self_compose != (TransformState *)NULL) {
00476 return _self_compose;
00477 }
00478 CPT(TransformState) result = do_compose(this);
00479 ((TransformState *)this)->_self_compose = result;
00480
00481 if (result != (const TransformState *)this) {
00482
00483
00484
00485 _self_compose->ref();
00486
00487
00488
00489
00490 }
00491 return _self_compose;
00492 }
00493
00494
00495 CompositionCache::const_iterator ci = _composition_cache.find(other);
00496 if (ci != _composition_cache.end()) {
00497 const Composition &comp = (*ci).second;
00498 if (comp._result == (const TransformState *)NULL) {
00499
00500
00501
00502 ((Composition &)comp)._result = do_compose(other);
00503 }
00504
00505 return comp._result;
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515 CPT(TransformState) result = do_compose(other);
00516
00517 ((TransformState *)other)->_composition_cache[this]._result = NULL;
00518 ((TransformState *)this)->_composition_cache[other]._result = result;
00519
00520 return result;
00521 }
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 CPT(TransformState) TransformState::
00535 invert_compose(const TransformState *other) const {
00536
00537
00538
00539
00540
00541 if (is_identity()) {
00542 return other;
00543 }
00544
00545
00546
00547
00548 if (is_invalid()) {
00549 return this;
00550 }
00551 if (other->is_invalid()) {
00552 return other;
00553 }
00554
00555 if (other == this) {
00556
00557 return make_identity();
00558 }
00559
00560
00561 CompositionCache::const_iterator ci = _invert_composition_cache.find(other);
00562 if (ci != _invert_composition_cache.end()) {
00563 const Composition &comp = (*ci).second;
00564 if (comp._result == (const TransformState *)NULL) {
00565
00566
00567
00568 ((Composition &)comp)._result = do_invert_compose(other);
00569 }
00570
00571 return comp._result;
00572 }
00573
00574
00575
00576
00577
00578
00579
00580
00581 CPT(TransformState) result = do_invert_compose(other);
00582
00583 ((TransformState *)other)->_invert_composition_cache[this]._result = NULL;
00584 ((TransformState *)this)->_invert_composition_cache[other]._result = result;
00585
00586 return result;
00587 }
00588
00589
00590
00591
00592
00593
00594 void TransformState::
00595 output(ostream &out) const {
00596 out << "T:";
00597 if (is_invalid()) {
00598 out << "(invalid)";
00599
00600 } else if (is_identity()) {
00601 out << "(identity)";
00602
00603 } else if (has_components()) {
00604 bool output_hpr = !get_hpr().almost_equal(LVecBase3f(0.0f, 0.0f, 0.0f));
00605
00606 if (!components_given()) {
00607
00608
00609
00610 out << "m";
00611
00612 } else if (output_hpr && quat_given()) {
00613
00614
00615
00616
00617 out << "q";
00618 }
00619
00620 char lead = '(';
00621 if (!get_pos().almost_equal(LVecBase3f(0.0f, 0.0f, 0.0f))) {
00622 out << lead << "pos " << get_pos();
00623 lead = ' ';
00624 }
00625 if (output_hpr) {
00626 out << lead << "hpr " << get_hpr();
00627 lead = ' ';
00628 }
00629 if (!get_scale().almost_equal(LVecBase3f(1.0f, 1.0f, 1.0f))) {
00630 if (has_uniform_scale()) {
00631 out << lead << "scale " << get_uniform_scale();
00632 lead = ' ';
00633 } else {
00634 out << lead << "scale " << get_scale();
00635 lead = ' ';
00636 }
00637 }
00638 if (lead == '(') {
00639 out << "(almost identity)";
00640 } else {
00641 out << ")";
00642 }
00643
00644 } else {
00645 out << get_mat();
00646 }
00647 }
00648
00649
00650
00651
00652
00653
00654
00655 void TransformState::
00656 write(ostream &out, int indent_level) const {
00657 indent(out, indent_level) << *this << "\n";
00658 }
00659
00660
00661
00662
00663
00664
00665
00666
00667 int TransformState::
00668 get_num_states() {
00669 if (_states == (States *)NULL) {
00670 return 0;
00671 }
00672 return _states->size();
00673 }
00674
00675
00676
00677
00678
00679
00680
00681
00682 int TransformState::
00683 get_num_unused_states() {
00684 if (_states == (States *)NULL) {
00685 return 0;
00686 }
00687
00688 int num_unused = 0;
00689
00690
00691
00692 typedef pmap<const TransformState *, int> StateCount;
00693 StateCount state_count;
00694
00695 States::iterator si;
00696 for (si = _states->begin(); si != _states->end(); ++si) {
00697 const TransformState *state = (*si);
00698
00699 CompositionCache::const_iterator ci;
00700 for (ci = state->_composition_cache.begin();
00701 ci != state->_composition_cache.end();
00702 ++ci) {
00703 const TransformState *result = (*ci).second._result;
00704 if (result != (const TransformState *)NULL) {
00705
00706
00707 pair<StateCount::iterator, bool> ir =
00708 state_count.insert(StateCount::value_type(result, 1));
00709 if (!ir.second) {
00710
00711
00712 (*(ir.first)).second++;
00713 }
00714 }
00715 }
00716 for (ci = state->_invert_composition_cache.begin();
00717 ci != state->_invert_composition_cache.end();
00718 ++ci) {
00719 const TransformState *result = (*ci).second._result;
00720 if (result != (const TransformState *)NULL) {
00721 pair<StateCount::iterator, bool> ir =
00722 state_count.insert(StateCount::value_type(result, 1));
00723 if (!ir.second) {
00724 (*(ir.first)).second++;
00725 }
00726 }
00727 }
00728
00729
00730
00731 if (state->_self_compose != (const TransformState *)NULL &&
00732 state->_self_compose != state) {
00733 const TransformState *result = state->_self_compose;
00734 if (result != (const TransformState *)NULL) {
00735 pair<StateCount::iterator, bool> ir =
00736 state_count.insert(StateCount::value_type(result, 1));
00737 if (!ir.second) {
00738 (*(ir.first)).second++;
00739 }
00740 }
00741 }
00742
00743 }
00744
00745
00746
00747
00748 StateCount::iterator sci;
00749 for (sci = state_count.begin(); sci != state_count.end(); ++sci) {
00750 const TransformState *state = (*sci).first;
00751 int count = (*sci).second;
00752 nassertr(count <= state->get_ref_count(), num_unused);
00753 if (count == state->get_ref_count()) {
00754 num_unused++;
00755 }
00756 }
00757
00758 return num_unused;
00759 }
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786 int TransformState::
00787 clear_cache() {
00788 if (_states == (States *)NULL) {
00789 return 0;
00790 }
00791
00792 int orig_size = _states->size();
00793
00794
00795
00796
00797
00798 {
00799 typedef pvector< CPT(TransformState) > TempStates;
00800 TempStates temp_states;
00801 temp_states.reserve(orig_size);
00802
00803 copy(_states->begin(), _states->end(),
00804 back_inserter(temp_states));
00805
00806
00807
00808
00809 TempStates::iterator ti;
00810 for (ti = temp_states.begin(); ti != temp_states.end(); ++ti) {
00811 TransformState *state = (TransformState *)(*ti).p();
00812 state->_composition_cache.clear();
00813 state->_invert_composition_cache.clear();
00814 if (state->_self_compose != (TransformState *)NULL &&
00815 state->_self_compose != state) {
00816 unref_delete((TransformState *)state->_self_compose);
00817 state->_self_compose = (TransformState *)NULL;
00818 }
00819 }
00820
00821
00822
00823
00824 }
00825
00826 int new_size = _states->size();
00827 return orig_size - new_size;
00828 }
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842 CPT(TransformState) TransformState::
00843 return_new(TransformState *state) {
00844 nassertr(state != (TransformState *)NULL, state);
00845
00846
00847
00848 nassertr(state->_saved_entry == _states->end(), state);
00849
00850
00851
00852 CPT(TransformState) pt_state = state;
00853
00854 pair<States::iterator, bool> result = _states->insert(state);
00855 if (result.second) {
00856
00857
00858 state->_saved_entry = result.first;
00859 return pt_state;
00860 }
00861
00862
00863
00864 return *(result.first);
00865 }
00866
00867
00868
00869
00870
00871
00872
00873
00874 CPT(TransformState) TransformState::
00875 do_compose(const TransformState *other) const {
00876 nassertr((_flags & F_is_invalid) == 0, this);
00877 nassertr((other->_flags & F_is_invalid) == 0, other);
00878
00879 if (compose_componentwise &&
00880 has_uniform_scale() &&
00881 ((components_given() && other->has_components()) ||
00882 (other->components_given() && has_components()))) {
00883
00884
00885
00886
00887 LVecBase3f pos = get_pos();
00888 LQuaternionf quat = get_quat();
00889 float scale = get_uniform_scale();
00890
00891 pos += quat.xform(other->get_pos()) * scale;
00892 quat = other->get_quat() * quat;
00893 quat.normalize();
00894 LVecBase3f new_scale = other->get_scale() * scale;
00895
00896 CPT(TransformState) result =
00897 make_pos_quat_scale(pos, quat, new_scale);
00898
00899 #ifndef NDEBUG
00900 if (paranoid_compose) {
00901
00902 LMatrix4f new_mat = other->get_mat() * get_mat();
00903 if (!new_mat.almost_equal(result->get_mat(), 0.05)) {
00904 CPT(TransformState) correct = make_mat(new_mat);
00905 pgraph_cat.warning()
00906 << "Componentwise composition of " << *this << " and " << *other
00907 << " produced:\n"
00908 << *result << "\n instead of:\n" << *correct << "\n";
00909 result = correct;
00910 }
00911 }
00912 #endif // NDEBUG
00913
00914 return result;
00915 }
00916
00917
00918 LMatrix4f new_mat = other->get_mat() * get_mat();
00919 return make_mat(new_mat);
00920 }
00921
00922
00923
00924
00925
00926
00927 CPT(TransformState) TransformState::
00928 do_invert_compose(const TransformState *other) const {
00929 nassertr((_flags & F_is_invalid) == 0, this);
00930 nassertr((other->_flags & F_is_invalid) == 0, other);
00931
00932 if (compose_componentwise &&
00933 has_uniform_scale() &&
00934 ((components_given() && other->has_components()) ||
00935 (other->components_given() && has_components()))) {
00936
00937
00938
00939
00940 LVecBase3f pos = get_pos();
00941 LQuaternionf quat = get_quat();
00942 float scale = get_uniform_scale();
00943
00944
00945 if (scale == 0.0f) {
00946 ((TransformState *)this)->_flags |= F_is_singular | F_singular_known;
00947 return make_invalid();
00948 }
00949 scale = 1.0f / scale;
00950 quat.invert_in_place();
00951 pos = quat.xform(-pos) * scale;
00952 LVecBase3f new_scale(scale, scale, scale);
00953
00954
00955 if (!other->is_identity()) {
00956 pos += quat.xform(other->get_pos()) * scale;
00957 quat = other->get_quat() * quat;
00958 quat.normalize();
00959 new_scale = other->get_scale() * scale;
00960 }
00961
00962 CPT(TransformState) result =
00963 make_pos_quat_scale(pos, quat, new_scale);
00964
00965 #ifndef NDEBUG
00966 if (paranoid_compose) {
00967
00968 if (is_singular()) {
00969 pgraph_cat.warning()
00970 << "Unexpected singular matrix found for " << *this << "\n";
00971 } else {
00972 nassertr(_inv_mat != (LMatrix4f *)NULL, make_invalid());
00973 LMatrix4f new_mat = other->get_mat() * (*_inv_mat);
00974 if (!new_mat.almost_equal(result->get_mat(), 0.05)) {
00975 CPT(TransformState) correct = make_mat(new_mat);
00976 pgraph_cat.warning()
00977 << "Componentwise invert-composition of " << *this << " and " << *other
00978 << " produced:\n"
00979 << *result << "\n instead of:\n" << *correct << "\n";
00980 result = correct;
00981 }
00982 }
00983 }
00984 #endif // NDEBUG
00985
00986 return result;
00987 }
00988
00989 if (is_singular()) {
00990 return make_invalid();
00991 }
00992
00993
00994
00995 nassertr(_inv_mat != (LMatrix4f *)NULL, make_invalid());
00996
00997 if (other->is_identity()) {
00998 return make_mat(*_inv_mat);
00999 } else {
01000 return make_mat(other->get_mat() * (*_inv_mat));
01001 }
01002 }
01003
01004
01005
01006
01007
01008
01009
01010 void TransformState::
01011 calc_singular() {
01012 nassertv((_flags & F_is_invalid) == 0);
01013
01014
01015
01016
01017
01018
01019
01020 nassertv(_inv_mat == (LMatrix4f *)NULL);
01021 _inv_mat = new LMatrix4f;
01022 bool inverted = _inv_mat->invert_from(get_mat());
01023
01024 if (!inverted) {
01025 _flags |= F_is_singular;
01026 delete _inv_mat;
01027 _inv_mat = (LMatrix4f *)NULL;
01028 }
01029 _flags |= F_singular_known;
01030 }
01031
01032
01033
01034
01035
01036
01037 void TransformState::
01038 calc_components() {
01039 nassertv((_flags & F_is_invalid) == 0);
01040 if ((_flags & F_is_identity) != 0) {
01041 _scale.set(1.0f, 1.0f, 1.0f);
01042 _hpr.set(0.0f, 0.0f, 0.0f);
01043 _quat = LQuaternionf::ident_quat();
01044 _pos.set(0.0f, 0.0f, 0.0f);
01045 _flags |= F_has_components | F_components_known | F_hpr_known | F_quat_known | F_uniform_scale;
01046
01047 } else {
01048
01049
01050 nassertv((_flags & F_mat_known) != 0);
01051
01052 const LMatrix4f &mat = get_mat();
01053 bool possible = decompose_matrix(mat, _scale, _hpr, _pos);
01054 if (!possible) {
01055
01056
01057
01058 _flags |= F_components_known | F_hpr_known;
01059
01060 } else {
01061
01062 _flags |= F_has_components | F_components_known | F_hpr_known;
01063 check_uniform_scale();
01064 }
01065
01066
01067 mat.get_row3(_pos, 3);
01068 }
01069 }
01070
01071
01072
01073
01074
01075
01076
01077 void TransformState::
01078 calc_hpr() {
01079 nassertv((_flags & F_is_invalid) == 0);
01080 check_components();
01081 if ((_flags & F_hpr_known) == 0) {
01082
01083
01084 nassertv((_flags & F_quat_known) != 0);
01085 _hpr = _quat.get_hpr();
01086 _flags |= F_hpr_known;
01087 }
01088 }
01089
01090
01091
01092
01093
01094
01095 void TransformState::
01096 calc_quat() {
01097 nassertv((_flags & F_is_invalid) == 0);
01098 check_components();
01099 if ((_flags & F_quat_known) == 0) {
01100
01101
01102 nassertv((_flags & F_hpr_known) != 0);
01103 _quat.set_hpr(_hpr);
01104 _flags |= F_quat_known;
01105 }
01106 }
01107
01108
01109
01110
01111
01112
01113 void TransformState::
01114 calc_mat() {
01115 nassertv((_flags & F_is_invalid) == 0);
01116 if ((_flags & F_is_identity) != 0) {
01117 _mat = LMatrix4f::ident_mat();
01118
01119 } else {
01120
01121
01122 nassertv((_flags & F_components_known) != 0);
01123 compose_matrix(_mat, _scale, get_hpr(), _pos);
01124 }
01125 _flags |= F_mat_known;
01126 }
01127
01128
01129
01130
01131
01132
01133
01134 void TransformState::
01135 register_with_read_factory() {
01136 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
01137 }
01138
01139
01140
01141
01142
01143
01144
01145 void TransformState::
01146 write_datagram(BamWriter *manager, Datagram &dg) {
01147 TypedWritable::write_datagram(manager, dg);
01148
01149 if ((_flags & F_is_identity) != 0) {
01150
01151 int flags = F_is_identity | F_singular_known;
01152 dg.add_uint16(flags);
01153
01154 } else if ((_flags & F_is_invalid) != 0) {
01155
01156 int flags = F_is_invalid | F_singular_known | F_is_singular | F_components_known | F_mat_known;
01157 dg.add_uint16(flags);
01158
01159 } else if ((_flags & F_components_given) != 0) {
01160
01161 int flags = F_components_given | F_components_known | F_has_components;
01162 if ((_flags & F_quat_given) != 0) {
01163 flags |= (F_quat_given | F_quat_known);
01164 } else if ((_flags & F_hpr_given) != 0) {
01165 flags |= (F_hpr_given | F_hpr_known);
01166 }
01167
01168 dg.add_uint16(flags);
01169
01170 _pos.write_datagram(dg);
01171 if ((_flags & F_quat_given) != 0) {
01172 _quat.write_datagram(dg);
01173 } else {
01174 get_hpr().write_datagram(dg);
01175 }
01176 _scale.write_datagram(dg);
01177
01178 } else {
01179
01180 nassertv((_flags & F_mat_known) != 0);
01181 int flags = F_mat_known;
01182 dg.add_uint16(flags);
01183 _mat.write_datagram(dg);
01184 }
01185 }
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198 TypedWritable *TransformState::
01199 change_this(TypedWritable *old_ptr, BamReader *manager) {
01200
01201 TransformState *state = DCAST(TransformState, old_ptr);
01202 CPT(TransformState) pointer = return_new(state);
01203
01204
01205
01206
01207
01208
01209 if (pointer == state) {
01210 pointer->ref();
01211 manager->register_finalize(state);
01212 }
01213
01214
01215
01216 return (TransformState *)pointer.p();
01217 }
01218
01219
01220
01221
01222
01223
01224
01225
01226 void TransformState::
01227 finalize() {
01228
01229 unref();
01230
01231
01232
01233
01234
01235
01236 nassertv(get_ref_count() != 0);
01237 }
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247 TypedWritable *TransformState::
01248 make_from_bam(const FactoryParams ¶ms) {
01249 TransformState *state = new TransformState;
01250 DatagramIterator scan;
01251 BamReader *manager;
01252
01253 parse_params(params, scan, manager);
01254 state->fillin(scan, manager);
01255 manager->register_change_this(change_this, state);
01256
01257 return state;
01258 }
01259
01260
01261
01262
01263
01264
01265
01266
01267 void TransformState::
01268 fillin(DatagramIterator &scan, BamReader *manager) {
01269 TypedWritable::fillin(scan, manager);
01270
01271 _flags = scan.get_uint16();
01272
01273 if ((_flags & F_components_given) != 0) {
01274
01275 _pos.read_datagram(scan);
01276 if ((_flags & F_quat_given) != 0) {
01277 _quat.read_datagram(scan);
01278 } else {
01279 _hpr.read_datagram(scan);
01280
01281
01282 _flags |= (F_hpr_given | F_hpr_known);
01283 }
01284 _scale.read_datagram(scan);
01285 check_uniform_scale();
01286 }
01287
01288 if ((_flags & F_mat_known) != 0) {
01289
01290 _mat.read_datagram(scan);
01291
01292 if (bams_componentwise) {
01293
01294 if (has_components()) {
01295 _flags |= F_components_given | F_hpr_given;
01296 }
01297 }
01298 }
01299 }
01300
01301
01302
01303
01304
01305
01306 void EventStoreTransform::
01307 output(ostream &out) const {
01308 out << *_value;
01309 }