16 #include "animChannelMatrixXfmTable.h"
17 #include "animBundle.h"
18 #include "config_chan.h"
20 #include "compose_matrix.h"
23 #include "datagramIterator.h"
24 #include "bamReader.h"
25 #include "bamWriter.h"
26 #include "fftCompressor.h"
27 #include "config_linmath.h"
29 TypeHandle AnimChannelMatrixXfmTable::_type_handle;
36 AnimChannelMatrixXfmTable::
37 AnimChannelMatrixXfmTable() {
38 for (
int i = 0; i < num_matrix_components; i++) {
51 AnimChannelMatrixXfmTable::
55 for (
int i = 0; i < num_matrix_components; i++) {
56 _tables[i] = copy._tables[i];
65 AnimChannelMatrixXfmTable::
66 AnimChannelMatrixXfmTable(
AnimGroup *parent,
const string &name)
69 for (
int i = 0; i < num_matrix_components; i++) {
79 AnimChannelMatrixXfmTable::
80 ~AnimChannelMatrixXfmTable() {
94 int this_frame,
double this_frac) {
95 if (last_frame != this_frame) {
96 for (
int i = 0; i < num_matrix_components; i++) {
97 if (_tables[i].size() > 1) {
98 if (_tables[i][last_frame % _tables[i].size()] !=
99 _tables[i][this_frame % _tables[i].size()]) {
106 if (last_frac != this_frac) {
109 for (
int i = 0; i < num_matrix_components; i++) {
110 if (_tables[i].size() > 1) {
111 if (_tables[i][last_frame % _tables[i].size()] !=
112 _tables[i][(this_frame + 1) % _tables[i].size()]) {
129 PN_stdfloat components[num_matrix_components];
131 for (
int i = 0; i < num_matrix_components; i++) {
132 if (_tables[i].empty()) {
133 components[i] = get_default_value(i);
135 components[i] = _tables[i][frame % _tables[i].size()];
139 compose_matrix(mat, components);
150 PN_stdfloat components[num_matrix_components];
151 components[0] = 1.0f;
152 components[1] = 1.0f;
153 components[2] = 1.0f;
154 components[3] = 0.0f;
155 components[4] = 0.0f;
156 components[5] = 0.0f;
158 for (
int i = 6; i < num_matrix_components; i++) {
159 if (_tables[i].empty()) {
160 components[i] = get_default_value(i);
162 components[i] = _tables[i][frame % _tables[i].size()];
166 compose_matrix(mat, components);
176 for (
int i = 0; i < 3; i++) {
177 if (_tables[i].empty()) {
180 scale[i] = _tables[i][frame % _tables[i].size()];
194 for (
int i = 0; i < 3; i++) {
195 if (_tables[i + 6].empty()) {
198 hpr[i] = _tables[i + 6][frame % _tables[i + 6].size()];
213 for (
int i = 0; i < 3; i++) {
214 if (_tables[i + 6].empty()) {
217 hpr[i] = _tables[i + 6][frame % _tables[i + 6].size()];
233 for (
int i = 0; i < 3; i++) {
234 if (_tables[i + 9].empty()) {
237 pos[i] = _tables[i + 9][frame % _tables[i + 9].size()];
251 for (
int i = 0; i < 3; i++) {
252 if (_tables[i + 3].empty()) {
255 shear[i] = _tables[i + 3][frame % _tables[i + 3].size()];
271 int num_frames = _root->get_num_frames();
273 if (table.size() > 1 && (int)table.size() < num_frames) {
280 int i = get_table_index(table_id);
297 for (
int i = 0; i < num_matrix_components; i++) {
309 write(ostream &out,
int indent_level)
const {
310 indent(out, indent_level)
311 << get_type() <<
" " << get_name() <<
" ";
314 bool found_any =
false;
315 for (
int i = 0; i < num_matrix_components; i++) {
316 if (!_tables[i].empty()) {
317 out << get_table_id(i) << _tables[i].size();
326 if (!_children.empty()) {
328 write_descendants(out, indent_level + 2);
329 indent(out, indent_level) <<
"}";
356 int AnimChannelMatrixXfmTable::
357 get_table_index(
char table_id) {
358 for (
int i = 0; i < num_matrix_components; i++) {
359 if (table_id == get_table_id(i)) {
379 <<
"Compression is not available; writing uncompressed channels.\n";
380 compress_channels =
false;
386 if (!compress_channels) {
388 for (
int i = 0; i < num_matrix_components; i++) {
390 for(
int j = 0; j < (int)_tables[i].size(); j++) {
404 for (i = 0; i < 6; i++) {
405 compressor.
write_reals(me, _tables[i], _tables[i].size());
411 int hprs_length = max(max(_tables[6].size(), _tables[7].size()), _tables[8].size());
412 hprs.reserve(hprs_length);
413 for (i = 0; i < hprs_length; i++) {
414 PN_stdfloat h = _tables[6].empty() ? 0.0f : _tables[6][i % _tables[6].size()];
415 PN_stdfloat p = _tables[7].empty() ? 0.0f : _tables[7][i % _tables[7].size()];
416 PN_stdfloat r = _tables[8].empty() ? 0.0f : _tables[8][i % _tables[8].size()];
420 if (hprs_length != 0) {
421 hprs_array = &hprs[0];
423 compressor.
write_hprs(me, hprs_array, hprs_length);
426 for(i = 9; i < num_matrix_components; i++) {
427 compressor.
write_reals(me, _tables[i], _tables[i].size());
440 void AnimChannelMatrixXfmTable::
442 AnimChannelMatrix::fillin(scan, manager);
444 bool wrote_compressed = scan.
get_bool();
448 if (!wrote_compressed) {
451 for (
int i = 0; i < num_matrix_components; i++) {
453 PTA_stdfloat ind_table(get_class_type());
454 for (
int j = 0; j < size; j++) {
457 _tables[i] = ind_table;
460 if ((!new_hpr && temp_hpr_fix) || (new_hpr && !temp_hpr_fix)) {
462 size_t num_hprs = max(max(_tables[6].size(), _tables[7].size()),
466 if (!_tables[6].empty()) {
467 default_hpr[0] = _tables[6][0];
469 if (!_tables[7].empty()) {
470 default_hpr[1] = _tables[7][0];
472 if (!_tables[8].empty()) {
473 default_hpr[2] = _tables[8][0];
476 PTA_stdfloat h_table = PTA_stdfloat::empty_array(num_hprs, get_class_type());
477 PTA_stdfloat p_table = PTA_stdfloat::empty_array(num_hprs, get_class_type());
478 PTA_stdfloat r_table = PTA_stdfloat::empty_array(num_hprs, get_class_type());
480 for (
size_t hi = 0; hi < num_hprs; hi++) {
481 PN_stdfloat h = (hi < _tables[6].size() ? _tables[6][hi] : default_hpr[0]);
482 PN_stdfloat p = (hi < _tables[7].size() ? _tables[7][hi] : default_hpr[1]);
483 PN_stdfloat r = (hi < _tables[8].size() ? _tables[8][hi] : default_hpr[2]);
487 hpr = old_to_new_hpr(
LVecBase3(h, p, r));
489 hpr = new_to_old_hpr(
LVecBase3(h, p, r));
491 h_table[hi] = hpr[0];
492 p_table[hi] = hpr[1];
493 r_table[hi] = hpr[2];
495 _tables[6] = h_table;
496 _tables[7] = p_table;
497 _tables[8] = r_table;
502 if (!read_compressed_channels) {
504 <<
"Not reading compressed animation channels.\n";
514 for (i = 0; i < 6; i++) {
515 PTA_stdfloat ind_table = PTA_stdfloat::empty_array(0, get_class_type());
517 _tables[i] = ind_table;
522 compressor.
read_hprs(scan, hprs, new_hpr);
523 PTA_stdfloat h_table = PTA_stdfloat::empty_array(hprs.size(), get_class_type());
524 PTA_stdfloat p_table = PTA_stdfloat::empty_array(hprs.size(), get_class_type());
525 PTA_stdfloat r_table = PTA_stdfloat::empty_array(hprs.size(), get_class_type());
527 for (i = 0; i < (int)hprs.size(); i++) {
528 if (!new_hpr && temp_hpr_fix) {
535 }
else if (new_hpr && !temp_hpr_fix) {
544 h_table[i] = hprs[i][0];
545 p_table[i] = hprs[i][1];
546 r_table[i] = hprs[i][2];
549 _tables[6] = h_table;
550 _tables[7] = p_table;
551 _tables[8] = r_table;
554 for (i = 9; i < num_matrix_components; i++) {
555 PTA_stdfloat ind_table = PTA_stdfloat::empty_array(0, get_class_type());
557 _tables[i] = ind_table;
574 parse_params(params, scan, manager);
575 me->fillin(scan, manager);
virtual void get_hpr(int frame, LVecBase3 &hpr)
Returns the h, p, and r components associated with the current frame.
This is the base class for all three-component vectors and points.
bool read_reals(DatagramIterator &di, vector_stdfloat &array)
Reads an array of floating-point numbers.
bool read_hprs(DatagramIterator &di, pvector< LVecBase3 > &array, bool new_hpr)
Reads an array of HPR angles.
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
void set_quality(int quality)
Sets the quality factor for the compression.
bool get_bool()
Extracts a boolean value.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
virtual void get_shear(int frame, LVecBase3 &shear)
Returns the a, b, and c shear components associated with the current frame.
bool read_header(DatagramIterator &di, int bam_minor_version)
Reads the compression header that was written previously.
virtual void get_pos(int frame, LVecBase3 &pos)
Returns the x, y, and z translation components associated with the current frame. ...
Base class for objects that can be written to and read from Bam files.
virtual void get_scale(int frame, LVecBase3 &scale)
Gets the scale value at the indicated frame.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
This class manages a lossy compression and decompression of a stream of floating-point numbers to a d...
PN_uint16 get_uint16()
Extracts an unsigned 16-bit integer.
void clear_all_tables()
Removes all the tables from the channel, and resets it to its initial state.
virtual void write(ostream &out, int indent_level) const
Writes a brief description of the table and all of its descendants.
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
This is our own Panda specialization on the default STL vector.
void add_bool(bool value)
Adds a boolean value to the datagram.
This is the base class for AnimChannel and AnimBundle.
This is a 4-by-4 transform matrix.
static TypedWritable * make_AnimChannelMatrixXfmTable(const FactoryParams ¶ms)
Factory method to generate an AnimChannelMatrixXfmTable object.
void write_header(Datagram &datagram)
Writes the compression parameters to the indicated datagram.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
void set_table(char table_id, const CPTA_stdfloat &table)
Assigns the indicated table.
void set_hpr(const LVecBase3f &hpr, CoordinateSystem cs=CS_default)
Sets the quaternion as the unit quaternion that is equivalent to these Euler angles.
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
void add_uint16(PN_uint16 value)
Adds an unsigned 16-bit integer to the datagram.
virtual void get_value(int frame, LMatrix4 &mat)
Gets the value of the channel at the indicated frame.
void write_reals(Datagram &datagram, const PN_stdfloat *array, int length)
Writes an array of floating-point numbers to the indicated datagram.
static void register_with_read_factory()
Factory method to generate an AnimChannelMatrixXfmTable object.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
This is the base quaternion class.
void write_hprs(Datagram &datagram, const LVecBase3 *array, int length)
Writes an array of HPR angles to the indicated datagram.
An animation channel that issues a matrix each frame, read from a table such as might have been read ...
virtual void get_quat(int frame, LQuaternion &quat)
Returns the rotation component associated with the current frame, expressed as a quaternion.
A class to retrieve the individual data elements previously stored in a Datagram. ...
void set_use_error_threshold(bool use_error_threshold)
Enables or disables the use of the error threshold measurement to put a cap on the amount of damage d...
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
TypeHandle is the identifier used to differentiate C++ class types.
virtual bool has_changed(int last_frame, double last_frac, int this_frame, double this_frac)
Returns true if the value has changed since the last call to has_changed().
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
static bool is_compression_available()
Returns true if the FFTW library is compiled in, so that this class is actually capable of doing usef...
Similar to PointerToArray, except that its contents may not be modified.
virtual void get_value_no_scale_shear(int frame, LMatrix4 &value)
Gets the value of the channel at the indicated frame, without any scale or shear information.