00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "animChannelMatrixXfmTable.h"
00017 #include "animBundle.h"
00018 #include "config_chan.h"
00019
00020 #include "compose_matrix.h"
00021 #include "indent.h"
00022 #include "datagram.h"
00023 #include "datagramIterator.h"
00024 #include "bamReader.h"
00025 #include "bamWriter.h"
00026 #include "fftCompressor.h"
00027 #include "config_linmath.h"
00028
00029 TypeHandle AnimChannelMatrixXfmTable::_type_handle;
00030
00031
00032
00033
00034
00035
00036 AnimChannelMatrixXfmTable::
00037 AnimChannelMatrixXfmTable() {
00038 for (int i = 0; i < num_matrix_components; i++) {
00039 _tables[i] = CPTA_stdfloat(get_class_type());
00040 }
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 AnimChannelMatrixXfmTable::
00052 AnimChannelMatrixXfmTable(AnimGroup *parent, const AnimChannelMatrixXfmTable ©) :
00053 AnimChannelMatrix(parent, copy)
00054 {
00055 for (int i = 0; i < num_matrix_components; i++) {
00056 _tables[i] = copy._tables[i];
00057 }
00058 }
00059
00060
00061
00062
00063
00064
00065 AnimChannelMatrixXfmTable::
00066 AnimChannelMatrixXfmTable(AnimGroup *parent, const string &name)
00067 : AnimChannelMatrix(parent, name)
00068 {
00069 for (int i = 0; i < num_matrix_components; i++) {
00070 _tables[i] = CPTA_stdfloat(get_class_type());
00071 }
00072 }
00073
00074
00075
00076
00077
00078
00079 AnimChannelMatrixXfmTable::
00080 ~AnimChannelMatrixXfmTable() {
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 bool AnimChannelMatrixXfmTable::
00093 has_changed(int last_frame, double last_frac,
00094 int this_frame, double this_frac) {
00095 if (last_frame != this_frame) {
00096 for (int i = 0; i < num_matrix_components; i++) {
00097 if (_tables[i].size() > 1) {
00098 if (_tables[i][last_frame % _tables[i].size()] !=
00099 _tables[i][this_frame % _tables[i].size()]) {
00100 return true;
00101 }
00102 }
00103 }
00104 }
00105
00106 if (last_frac != this_frac) {
00107
00108
00109 for (int i = 0; i < num_matrix_components; i++) {
00110 if (_tables[i].size() > 1) {
00111 if (_tables[i][last_frame % _tables[i].size()] !=
00112 _tables[i][(this_frame + 1) % _tables[i].size()]) {
00113 return true;
00114 }
00115 }
00116 }
00117 }
00118
00119 return false;
00120 }
00121
00122
00123
00124
00125
00126
00127 void AnimChannelMatrixXfmTable::
00128 get_value(int frame, LMatrix4 &mat) {
00129 PN_stdfloat components[num_matrix_components];
00130
00131 for (int i = 0; i < num_matrix_components; i++) {
00132 if (_tables[i].empty()) {
00133 components[i] = get_default_value(i);
00134 } else {
00135 components[i] = _tables[i][frame % _tables[i].size()];
00136 }
00137 }
00138
00139 compose_matrix(mat, components);
00140 }
00141
00142
00143
00144
00145
00146
00147
00148 void AnimChannelMatrixXfmTable::
00149 get_value_no_scale_shear(int frame, LMatrix4 &mat) {
00150 PN_stdfloat components[num_matrix_components];
00151 components[0] = 1.0f;
00152 components[1] = 1.0f;
00153 components[2] = 1.0f;
00154 components[3] = 0.0f;
00155 components[4] = 0.0f;
00156 components[5] = 0.0f;
00157
00158 for (int i = 6; i < num_matrix_components; i++) {
00159 if (_tables[i].empty()) {
00160 components[i] = get_default_value(i);
00161 } else {
00162 components[i] = _tables[i][frame % _tables[i].size()];
00163 }
00164 }
00165
00166 compose_matrix(mat, components);
00167 }
00168
00169
00170
00171
00172
00173
00174 void AnimChannelMatrixXfmTable::
00175 get_scale(int frame, LVecBase3 &scale) {
00176 for (int i = 0; i < 3; i++) {
00177 if (_tables[i].empty()) {
00178 scale[i] = 1.0f;
00179 } else {
00180 scale[i] = _tables[i][frame % _tables[i].size()];
00181 }
00182 }
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192 void AnimChannelMatrixXfmTable::
00193 get_hpr(int frame, LVecBase3 &hpr) {
00194 for (int i = 0; i < 3; i++) {
00195 if (_tables[i + 6].empty()) {
00196 hpr[i] = 0.0f;
00197 } else {
00198 hpr[i] = _tables[i + 6][frame % _tables[i + 6].size()];
00199 }
00200 }
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210 void AnimChannelMatrixXfmTable::
00211 get_quat(int frame, LQuaternion &quat) {
00212 LVecBase3 hpr;
00213 for (int i = 0; i < 3; i++) {
00214 if (_tables[i + 6].empty()) {
00215 hpr[i] = 0.0f;
00216 } else {
00217 hpr[i] = _tables[i + 6][frame % _tables[i + 6].size()];
00218 }
00219 }
00220
00221 quat.set_hpr(hpr);
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231 void AnimChannelMatrixXfmTable::
00232 get_pos(int frame, LVecBase3 &pos) {
00233 for (int i = 0; i < 3; i++) {
00234 if (_tables[i + 9].empty()) {
00235 pos[i] = 0.0f;
00236 } else {
00237 pos[i] = _tables[i + 9][frame % _tables[i + 9].size()];
00238 }
00239 }
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249 void AnimChannelMatrixXfmTable::
00250 get_shear(int frame, LVecBase3 &shear) {
00251 for (int i = 0; i < 3; i++) {
00252 if (_tables[i + 3].empty()) {
00253 shear[i] = 0.0f;
00254 } else {
00255 shear[i] = _tables[i + 3][frame % _tables[i + 3].size()];
00256 }
00257 }
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 void AnimChannelMatrixXfmTable::
00270 set_table(char table_id, const CPTA_stdfloat &table) {
00271 int num_frames = _root->get_num_frames();
00272
00273 if (table.size() > 1 && (int)table.size() < num_frames) {
00274
00275
00276 nassertv(false);
00277 return;
00278 }
00279
00280 int i = get_table_index(table_id);
00281 if (i < 0) {
00282 return;
00283 }
00284
00285 _tables[i] = table;
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295 void AnimChannelMatrixXfmTable::
00296 clear_all_tables() {
00297 for (int i = 0; i < num_matrix_components; i++) {
00298 _tables[i] = CPTA_stdfloat(get_class_type());
00299 }
00300 }
00301
00302
00303
00304
00305
00306
00307
00308 void AnimChannelMatrixXfmTable::
00309 write(ostream &out, int indent_level) const {
00310 indent(out, indent_level)
00311 << get_type() << " " << get_name() << " ";
00312
00313
00314 bool found_any = false;
00315 for (int i = 0; i < num_matrix_components; i++) {
00316 if (!_tables[i].empty()) {
00317 out << get_table_id(i) << _tables[i].size();
00318 found_any = true;
00319 }
00320 }
00321
00322 if (!found_any) {
00323 out << "(no data)";
00324 }
00325
00326 if (!_children.empty()) {
00327 out << " {\n";
00328 write_descendants(out, indent_level + 2);
00329 indent(out, indent_level) << "}";
00330 }
00331
00332 out << "\n";
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 AnimGroup *AnimChannelMatrixXfmTable::
00344 make_copy(AnimGroup *parent) const {
00345 return new AnimChannelMatrixXfmTable(parent, *this);
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 int AnimChannelMatrixXfmTable::
00357 get_table_index(char table_id) {
00358 for (int i = 0; i < num_matrix_components; i++) {
00359 if (table_id == get_table_id(i)) {
00360 return i;
00361 }
00362 }
00363
00364 return -1;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373 void AnimChannelMatrixXfmTable::
00374 write_datagram(BamWriter *manager, Datagram &me) {
00375 AnimChannelMatrix::write_datagram(manager, me);
00376
00377 if (compress_channels && !FFTCompressor::is_compression_available()) {
00378 chan_cat.error()
00379 << "Compression is not available; writing uncompressed channels.\n";
00380 compress_channels = false;
00381 }
00382
00383 me.add_bool(compress_channels);
00384 me.add_bool(temp_hpr_fix);
00385
00386 if (!compress_channels) {
00387
00388 for (int i = 0; i < num_matrix_components; i++) {
00389 me.add_uint16(_tables[i].size());
00390 for(int j = 0; j < (int)_tables[i].size(); j++) {
00391 me.add_stdfloat(_tables[i][j]);
00392 }
00393 }
00394
00395 } else {
00396
00397 FFTCompressor compressor;
00398 compressor.set_quality(compress_chan_quality);
00399 compressor.set_use_error_threshold(true);
00400 compressor.write_header(me);
00401
00402
00403 int i;
00404 for (i = 0; i < 6; i++) {
00405 compressor.write_reals(me, _tables[i], _tables[i].size());
00406 }
00407
00408
00409
00410 pvector<LVecBase3> hprs;
00411 int hprs_length = max(max(_tables[6].size(), _tables[7].size()), _tables[8].size());
00412 hprs.reserve(hprs_length);
00413 for (i = 0; i < hprs_length; i++) {
00414 PN_stdfloat h = _tables[6].empty() ? 0.0f : _tables[6][i % _tables[6].size()];
00415 PN_stdfloat p = _tables[7].empty() ? 0.0f : _tables[7][i % _tables[7].size()];
00416 PN_stdfloat r = _tables[8].empty() ? 0.0f : _tables[8][i % _tables[8].size()];
00417 hprs.push_back(LVecBase3(h, p, r));
00418 }
00419 const LVecBase3 *hprs_array = NULL;
00420 if (hprs_length != 0) {
00421 hprs_array = &hprs[0];
00422 }
00423 compressor.write_hprs(me, hprs_array, hprs_length);
00424
00425
00426 for(i = 9; i < num_matrix_components; i++) {
00427 compressor.write_reals(me, _tables[i], _tables[i].size());
00428 }
00429 }
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 void AnimChannelMatrixXfmTable::
00441 fillin(DatagramIterator &scan, BamReader *manager) {
00442 AnimChannelMatrix::fillin(scan, manager);
00443
00444 bool wrote_compressed = scan.get_bool();
00445
00446 bool new_hpr = scan.get_bool();
00447
00448 if (!wrote_compressed) {
00449
00450
00451 for (int i = 0; i < num_matrix_components; i++) {
00452 int size = scan.get_uint16();
00453 PTA_stdfloat ind_table(get_class_type());
00454 for (int j = 0; j < size; j++) {
00455 ind_table.push_back(scan.get_stdfloat());
00456 }
00457 _tables[i] = ind_table;
00458 }
00459
00460 if ((!new_hpr && temp_hpr_fix) || (new_hpr && !temp_hpr_fix)) {
00461
00462 size_t num_hprs = max(max(_tables[6].size(), _tables[7].size()),
00463 _tables[8].size());
00464
00465 LVecBase3 default_hpr(0.0, 0.0, 0.0);
00466 if (!_tables[6].empty()) {
00467 default_hpr[0] = _tables[6][0];
00468 }
00469 if (!_tables[7].empty()) {
00470 default_hpr[1] = _tables[7][0];
00471 }
00472 if (!_tables[8].empty()) {
00473 default_hpr[2] = _tables[8][0];
00474 }
00475
00476 PTA_stdfloat h_table = PTA_stdfloat::empty_array(num_hprs, get_class_type());
00477 PTA_stdfloat p_table = PTA_stdfloat::empty_array(num_hprs, get_class_type());
00478 PTA_stdfloat r_table = PTA_stdfloat::empty_array(num_hprs, get_class_type());
00479
00480 for (size_t hi = 0; hi < num_hprs; hi++) {
00481 PN_stdfloat h = (hi < _tables[6].size() ? _tables[6][hi] : default_hpr[0]);
00482 PN_stdfloat p = (hi < _tables[7].size() ? _tables[7][hi] : default_hpr[1]);
00483 PN_stdfloat r = (hi < _tables[8].size() ? _tables[8][hi] : default_hpr[2]);
00484
00485 LVecBase3 hpr;
00486 if (temp_hpr_fix) {
00487 hpr = old_to_new_hpr(LVecBase3(h, p, r));
00488 } else {
00489 hpr = new_to_old_hpr(LVecBase3(h, p, r));
00490 }
00491 h_table[hi] = hpr[0];
00492 p_table[hi] = hpr[1];
00493 r_table[hi] = hpr[2];
00494 }
00495 _tables[6] = h_table;
00496 _tables[7] = p_table;
00497 _tables[8] = r_table;
00498 }
00499
00500 } else {
00501
00502 if (!read_compressed_channels) {
00503 chan_cat.info()
00504 << "Not reading compressed animation channels.\n";
00505 clear_all_tables();
00506 return;
00507 }
00508
00509 FFTCompressor compressor;
00510 compressor.read_header(scan, manager->get_file_minor_ver());
00511
00512 int i;
00513
00514 for (i = 0; i < 6; i++) {
00515 PTA_stdfloat ind_table = PTA_stdfloat::empty_array(0, get_class_type());
00516 compressor.read_reals(scan, ind_table.v());
00517 _tables[i] = ind_table;
00518 }
00519
00520
00521 pvector<LVecBase3> hprs;
00522 compressor.read_hprs(scan, hprs, new_hpr);
00523 PTA_stdfloat h_table = PTA_stdfloat::empty_array(hprs.size(), get_class_type());
00524 PTA_stdfloat p_table = PTA_stdfloat::empty_array(hprs.size(), get_class_type());
00525 PTA_stdfloat r_table = PTA_stdfloat::empty_array(hprs.size(), get_class_type());
00526
00527 for (i = 0; i < (int)hprs.size(); i++) {
00528 if (!new_hpr && temp_hpr_fix) {
00529
00530 LVecBase3 hpr = old_to_new_hpr(hprs[i]);
00531 h_table[i] = hpr[0];
00532 p_table[i] = hpr[1];
00533 r_table[i] = hpr[2];
00534
00535 } else if (new_hpr && !temp_hpr_fix) {
00536
00537 LVecBase3 hpr = new_to_old_hpr(hprs[i]);
00538 h_table[i] = hpr[0];
00539 p_table[i] = hpr[1];
00540 r_table[i] = hpr[2];
00541
00542 } else {
00543
00544 h_table[i] = hprs[i][0];
00545 p_table[i] = hprs[i][1];
00546 r_table[i] = hprs[i][2];
00547 }
00548 }
00549 _tables[6] = h_table;
00550 _tables[7] = p_table;
00551 _tables[8] = r_table;
00552
00553
00554 for (i = 9; i < num_matrix_components; i++) {
00555 PTA_stdfloat ind_table = PTA_stdfloat::empty_array(0, get_class_type());
00556 compressor.read_reals(scan, ind_table.v());
00557 _tables[i] = ind_table;
00558 }
00559 }
00560 }
00561
00562
00563
00564
00565
00566
00567
00568 TypedWritable *AnimChannelMatrixXfmTable::
00569 make_AnimChannelMatrixXfmTable(const FactoryParams ¶ms) {
00570 AnimChannelMatrixXfmTable *me = new AnimChannelMatrixXfmTable;
00571 DatagramIterator scan;
00572 BamReader *manager;
00573
00574 parse_params(params, scan, manager);
00575 me->fillin(scan, manager);
00576 return me;
00577 }
00578
00579
00580
00581
00582
00583
00584
00585 void AnimChannelMatrixXfmTable::
00586 register_with_read_factory() {
00587 BamReader::get_factory()->register_factory(get_class_type(), make_AnimChannelMatrixXfmTable);
00588 }
00589
00590