Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/chan/animChannelMatrixXfmTable.cxx

Go to the documentation of this file.
00001 // Filename: animChannelMatrixXfmTable.cxx
00002 // Created by:  drose (20Feb99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
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 //     Function: AnimChannelMatrixXfmTable::Constructor
00044 //       Access: Public
00045 //  Description:
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 //     Function: AnimChannelMatrixXfmTable::has_changed
00061 //       Access: Public, Virtual
00062 //  Description: Returns true if the value has changed since the last
00063 //               call to has_changed().  last_frame is the frame
00064 //               number of the last call; this_frame is the current
00065 //               frame number.
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 //     Function: AnimChannelMatrixXfmTable::get_value
00083 //       Access: Public, Virtual
00084 //  Description: Gets the value of the channel at the indicated frame.
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 //     Function: AnimChannelMatrixXfmTable::get_value_no_scale
00103 //       Access: Public, Virtual
00104 //  Description: Gets the value of the channel at the indicated frame,
00105 //               without any scale information.
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 //     Function: AnimChannelMatrixXfmTable::get_scale
00127 //       Access: Public, Virtual
00128 //  Description: Gets the scale value at the indicated frame.
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 //     Function: AnimChannelMatrixXfmTable::clear_all_tables
00144 //       Access: Public
00145 //  Description: Removes all the tables from the channel, and resets
00146 //               it to its initial state.
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 //     Function: AnimChannelMatrixXfmTable::set_table
00157 //       Access: Public
00158 //  Description: Assigns the indicated table.  table_id is one of 'i',
00159 //               'j', 'k', for scale, 'h', 'p', 'r', for rotation, and
00160 //               'x', 'y', 'z', for translation.  The new table must
00161 //               have either zero, one, or get_num_frames() frames.
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     // The new table has an invalid number of frames--it doesn't match
00169     // the bundle's requirement.
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 //     Function: AnimChannelMatrixXfmTable::write
00183 //       Access: Public, Virtual
00184 //  Description: Writes a brief description of the table and all of
00185 //               its descendants.
00186 ////////////////////////////////////////////////////////////////////
00187 void AnimChannelMatrixXfmTable::
00188 write(ostream &out, int indent_level) const {
00189   indent(out, indent_level)
00190     << get_type() << " " << get_name() << " ";
00191 
00192   // Write a list of all the sub-tables that have data.
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 //     Function: AnimChannelMatrixXfmTable::get_table_index
00217 //       Access: Protected, Static
00218 //  Description: Returns the table index number, a value between 0 and
00219 //               num_tables, that corresponds to the indicate table
00220 //               id.  Returns -1 if the table id is invalid.
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 //     Function: AnimChannelMatrixXfmTable::write_datagram
00235 //       Access: Public
00236 //  Description: Function to write the important information in
00237 //               the particular object to a Datagram
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     // Write out everything uncompressed, as a stream of floats.
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     // Write out everything using lossy compression.
00262 
00263     FFTCompressor compressor;
00264     compressor.set_quality(compress_chan_quality);
00265     compressor.write_header(me);
00266 
00267     // First, write out the scales.
00268     int i;
00269     for(i = 0; i < 3; i++) {
00270       compressor.write_reals(me, _tables[i], _tables[i].size());
00271     }
00272 
00273     // Now, write out the joint angles.  For these we need to build up
00274     // a HPR array.
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     // And now the translations.
00288     for(i = 6; i < 9; i++) {
00289       compressor.write_reals(me, _tables[i], _tables[i].size());
00290     }
00291   }
00292 }
00293 
00294 ////////////////////////////////////////////////////////////////////
00295 //     Function: AnimChannelMatrixXfmTable::fillin
00296 //       Access: Protected
00297 //  Description: Function that reads out of the datagram (or asks
00298 //               manager to read) all of the data that is needed to
00299 //               re-create this object and stores it in the appropiate
00300 //               place
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     // Regular floats.
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     // Compressed channels.
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     // First, read in the scales.
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     // Read in the HPR array and store it back in the joint angles.
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     // Now read in the translations.
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 //     Function: AnimChannelMatrixXfmTable::make_AnimChannelMatrixXfmTable
00367 //       Access: Protected
00368 //  Description: Factory method to generate a AnimChannelMatrixXfmTable object
00369 ////////////////////////////////////////////////////////////////////
00370 TypedWritable* AnimChannelMatrixXfmTable::
00371 make_AnimChannelMatrixXfmTable(const FactoryParams &params)
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 //     Function: AnimChannelMatrixXfmTable::register_with_factory
00384 //       Access: Public, Static
00385 //  Description: Factory method to generate a AnimChannelMatrixXfmTable object
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 

Generated on Fri May 2 00:34:59 2003 for Panda by doxygen1.3