00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "animChannelMatrixXfmTable.h"
00021 #include "animBundle.h"
00022 #include "config_chan.h"
00023
00024 #include <compose_matrix.h>
00025 #include <indent.h>
00026 #include <datagram.h>
00027 #include <datagramIterator.h>
00028 #include <bamReader.h>
00029 #include <bamWriter.h>
00030 #include <fftCompressor.h>
00031
00032 TypeHandle AnimChannelMatrixXfmTable::_type_handle;
00033
00034 const char
00035 AnimChannelMatrixXfmTable::_table_ids[AnimChannelMatrixXfmTable::num_tables] =
00036 { 'i', 'j', 'k', 'h', 'p', 'r', 'x', 'y', 'z' };
00037
00038 const float
00039 AnimChannelMatrixXfmTable::_default_values[AnimChannelMatrixXfmTable::num_tables] =
00040 { 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
00041
00042
00043
00044
00045
00046
00047 AnimChannelMatrixXfmTable::
00048 AnimChannelMatrixXfmTable(AnimGroup *parent, const string &name)
00049 : AnimChannelMatrix(parent, name) {
00050 }
00051
00052
00053 AnimChannelMatrixXfmTable::
00054 AnimChannelMatrixXfmTable(void)
00055 {
00056 }
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 bool AnimChannelMatrixXfmTable::
00068 has_changed(int last_frame, int this_frame) {
00069 for (int i = 0; i < num_tables; i++) {
00070 if (_tables[i].size() > 1) {
00071 if (_tables[i][last_frame % _tables[i].size()] !=
00072 _tables[i][this_frame % _tables[i].size()]) {
00073 return true;
00074 }
00075 }
00076 }
00077
00078 return false;
00079 }
00080
00081
00082
00083
00084
00085
00086 void AnimChannelMatrixXfmTable::
00087 get_value(int frame, LMatrix4f &mat) {
00088 float components[num_tables];
00089
00090 for (int i = 0; i < num_tables; i++) {
00091 if (_tables[i].empty()) {
00092 components[i] = get_default_value(i);
00093 } else {
00094 components[i] = _tables[i][frame % _tables[i].size()];
00095 }
00096 }
00097
00098 compose_matrix(mat, components);
00099 }
00100
00101
00102
00103
00104
00105
00106
00107 void AnimChannelMatrixXfmTable::
00108 get_value_no_scale(int frame, LMatrix4f &mat) {
00109 float components[num_tables];
00110 components[0] = 1.0f;
00111 components[1] = 1.0f;
00112 components[2] = 1.0f;
00113
00114 for (int i = 3; i < num_tables; i++) {
00115 if (_tables[i].empty()) {
00116 components[i] = get_default_value(i);
00117 } else {
00118 components[i] = _tables[i][frame % _tables[i].size()];
00119 }
00120 }
00121
00122 compose_matrix(mat, components);
00123 }
00124
00125
00126
00127
00128
00129
00130 void AnimChannelMatrixXfmTable::
00131 get_scale(int frame, float scale[3]) {
00132 for (int i = 0; i < 3; i++) {
00133 if (_tables[i].empty()) {
00134 scale[i] = get_default_value(i);
00135 } else {
00136 scale[i] = _tables[i][frame % _tables[i].size()];
00137 }
00138 }
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148 void AnimChannelMatrixXfmTable::
00149 clear_all_tables() {
00150 for (int i = 0; i < num_tables; i++) {
00151 _tables[i] = NULL;
00152 }
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 void AnimChannelMatrixXfmTable::
00164 set_table(char table_id, const CPTA_float &table) {
00165 int num_frames = _root->get_num_frames();
00166
00167 if (table.size() > 1 && (int)table.size() < num_frames) {
00168
00169
00170 return;
00171 }
00172
00173 int i = get_table_index(table_id);
00174 if (i < 0) {
00175 return;
00176 }
00177
00178 _tables[i] = table;
00179 }
00180
00181
00182
00183
00184
00185
00186
00187 void AnimChannelMatrixXfmTable::
00188 write(ostream &out, int indent_level) const {
00189 indent(out, indent_level)
00190 << get_type() << " " << get_name() << " ";
00191
00192
00193 bool found_any = false;
00194 for (int i = 0; i < num_tables; i++) {
00195 if (!_tables[i].empty()) {
00196 out << get_table_id(i) << _tables[i].size();
00197 found_any = true;
00198 }
00199 }
00200
00201 if (!found_any) {
00202 out << "(no data)";
00203 }
00204
00205 if (!_children.empty()) {
00206 out << " {\n";
00207 write_descendants(out, indent_level + 2);
00208 indent(out, indent_level) << "}";
00209 }
00210
00211 out << "\n";
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 int AnimChannelMatrixXfmTable::
00223 get_table_index(char table_id) {
00224 for (int i = 0; i < num_tables; i++) {
00225 if (table_id == get_table_id(i)) {
00226 return i;
00227 }
00228 }
00229
00230 return -1;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 void AnimChannelMatrixXfmTable::
00240 write_datagram(BamWriter *manager, Datagram &me)
00241 {
00242 AnimChannelMatrix::write_datagram(manager, me);
00243
00244 if (compress_channels && !FFTCompressor::is_compression_available()) {
00245 chan_cat.error()
00246 << "Compression is not available; writing uncompressed channels.\n";
00247 compress_channels = false;
00248 }
00249
00250 me.add_bool(compress_channels);
00251 if (!compress_channels) {
00252
00253 for(int i = 0; i < num_tables; i++) {
00254 me.add_uint16(_tables[i].size());
00255 for(int j = 0; j < (int)_tables[i].size(); j++) {
00256 me.add_float32(_tables[i][j]);
00257 }
00258 }
00259
00260 } else {
00261
00262
00263 FFTCompressor compressor;
00264 compressor.set_quality(compress_chan_quality);
00265 compressor.write_header(me);
00266
00267
00268 int i;
00269 for(i = 0; i < 3; i++) {
00270 compressor.write_reals(me, _tables[i], _tables[i].size());
00271 }
00272
00273
00274
00275 vector_LVecBase3f hprs;
00276 int hprs_length =
00277 max(max(_tables[3].size(), _tables[4].size()), _tables[5].size());
00278 hprs.reserve(hprs_length);
00279 for (i = 0; i < hprs_length; i++) {
00280 float h = _tables[3].empty() ? 0.0f : _tables[3][i % _tables[3].size()];
00281 float p = _tables[4].empty() ? 0.0f : _tables[4][i % _tables[4].size()];
00282 float r = _tables[5].empty() ? 0.0f : _tables[5][i % _tables[5].size()];
00283 hprs.push_back(LVecBase3f(h, p, r));
00284 }
00285 compressor.write_hprs(me, &hprs[0], hprs_length);
00286
00287
00288 for(i = 6; i < 9; i++) {
00289 compressor.write_reals(me, _tables[i], _tables[i].size());
00290 }
00291 }
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 void AnimChannelMatrixXfmTable::
00303 fillin(DatagramIterator& scan, BamReader* manager)
00304 {
00305 AnimChannelMatrix::fillin(scan, manager);
00306
00307 bool wrote_compressed = scan.get_bool();
00308
00309 if (!wrote_compressed) {
00310
00311 for(int i = 0; i < num_tables; i++) {
00312 int size = scan.get_uint16();
00313 PTA_float ind_table;
00314 for(int j = 0; j < size; j++) {
00315 ind_table.push_back(scan.get_float32());
00316 }
00317 _tables[i] = ind_table;
00318 }
00319
00320 } else {
00321
00322 if (!read_compressed_channels) {
00323 chan_cat.info()
00324 << "Not reading compressed animation channels.\n";
00325 clear_all_tables();
00326 return;
00327 }
00328
00329 FFTCompressor compressor;
00330 compressor.read_header(scan);
00331
00332 int i;
00333
00334 for(i = 0; i < 3; i++) {
00335 PTA_float ind_table=PTA_float::empty_array(0);
00336 compressor.read_reals(scan, ind_table.v());
00337 _tables[i] = ind_table;
00338 }
00339
00340
00341 vector_LVecBase3f hprs;
00342 compressor.read_hprs(scan, hprs);
00343 PTA_float h_table=PTA_float::empty_array(hprs.size());
00344 PTA_float p_table=PTA_float::empty_array(hprs.size());
00345 PTA_float r_table=PTA_float::empty_array(hprs.size());
00346
00347 for (i = 0; i < (int)hprs.size(); i++) {
00348 h_table[i] = hprs[i][0];
00349 p_table[i] = hprs[i][1];
00350 r_table[i] = hprs[i][2];
00351 }
00352 _tables[3] = h_table;
00353 _tables[4] = p_table;
00354 _tables[5] = r_table;
00355
00356
00357 for (i = 6; i < 9; i++) {
00358 PTA_float ind_table=PTA_float::empty_array(0);
00359 compressor.read_reals(scan, ind_table.v());
00360 _tables[i] = ind_table;
00361 }
00362 }
00363 }
00364
00365
00366
00367
00368
00369
00370 TypedWritable* AnimChannelMatrixXfmTable::
00371 make_AnimChannelMatrixXfmTable(const FactoryParams ¶ms)
00372 {
00373 AnimChannelMatrixXfmTable *me = new AnimChannelMatrixXfmTable;
00374 DatagramIterator scan;
00375 BamReader *manager;
00376
00377 parse_params(params, scan, manager);
00378 me->fillin(scan, manager);
00379 return me;
00380 }
00381
00382
00383
00384
00385
00386
00387 void AnimChannelMatrixXfmTable::
00388 register_with_read_factory(void)
00389 {
00390 BamReader::get_factory()->register_factory(get_class_type(), make_AnimChannelMatrixXfmTable);
00391 }
00392
00393