*** empty log message ***

This commit is contained in:
David Rose 2001-02-27 20:07:01 +00:00
parent 7378d9ffe5
commit 8f338d05a8
6 changed files with 205 additions and 2 deletions

View File

@ -79,7 +79,7 @@ bind_anims(const PartNodes &parts, const AnimNodes &anims,
PT(AnimControl) control =
part->bind_anim(anim, hierarchy_match_flags);
if (control != (AnimControl *)NULL) {
controls.store_anim(control, (*ani)->get_name());
controls.store_anim(control, anim->get_name());
}
if (chan_cat.is_info()) {

View File

@ -62,3 +62,16 @@ get_value(int row) const {
}
////////////////////////////////////////////////////////////////////
// Function: EggSAnimData::set_value
// Access: Public
// Description: Changes the value at the indicated row. Row must be
// in the range 0 <= row < get_num_rows().
////////////////////////////////////////////////////////////////////
INLINE void EggSAnimData::
set_value(int row, double value) {
nassertv(row >= 0 && row < get_num_rows());
_data[row] = value;
}

View File

@ -24,6 +24,7 @@ public:
INLINE int get_num_rows() const;
INLINE double get_value(int row) const;
INLINE void set_value(int row, double value);
void optimize();

View File

@ -145,3 +145,14 @@ INLINE CoordinateSystem EggXfmSAnim::
get_coordinate_system() const {
return _coordsys;
}
////////////////////////////////////////////////////////////////////
// Function: EggXfmSAnim::clear_data
// Access: Public
// Description: Removes all data from the table. It does this by
// removing all of its children.
////////////////////////////////////////////////////////////////////
INLINE void EggXfmSAnim::
clear_data() {
EggGroupNode::clear();
}

View File

@ -86,6 +86,85 @@ optimize() {
}
}
////////////////////////////////////////////////////////////////////
// Function: EggXfmSAnim::normalize
// Access: Public
// Description: The inverse operation of optimize(), this ensures
// that all the sub-tables have the same length by
// duplicating rows as necessary. This is needed before
// doing operations like add_data() or set_value() on an
// existing table.
////////////////////////////////////////////////////////////////////
void EggXfmSAnim::
normalize() {
iterator ci;
// First, determine which tables we already have, and how long they
// are.
int num_tables = 0;
int table_length = 1;
string remaining_tables = "ijkhprxyz";
for (ci = begin(); ci != end(); ++ci) {
if ((*ci)->is_of_type(EggSAnimData::get_class_type())) {
EggSAnimData *sanim = DCAST(EggSAnimData, *ci);
nassertv(sanim->get_name().length() == 1);
char name = sanim->get_name()[0];
size_t p = remaining_tables.find(name);
nassertv(p != string::npos);
remaining_tables[p] = ' ';
num_tables++;
if (sanim->get_num_rows() > 1) {
if (table_length == 1) {
table_length = sanim->get_num_rows();
} else {
nassertv(sanim->get_num_rows() == table_length);
}
}
}
}
if (num_tables < 9) {
// Create new, default, children for each table we lack.
for (size_t p = 0; p < remaining_tables.length(); p++) {
if (remaining_tables[p] != ' ') {
double default_value;
switch (remaining_tables[p]) {
case 'i':
case 'j':
case 'k':
default_value = 1.0;
break;
default:
default_value = 0.0;
}
string name(1, remaining_tables[p]);
EggSAnimData *sanim = new EggSAnimData(name);
add_child(sanim);
sanim->add_data(default_value);
}
}
}
// Now expand any one-row tables as needed.
for (ci = begin(); ci != end(); ++ci) {
if ((*ci)->is_of_type(EggSAnimData::get_class_type())) {
EggSAnimData *sanim = DCAST(EggSAnimData, *ci);
if (sanim->get_num_rows() == 1) {
double value = sanim->get_value(0);
for (int i = 1; i < table_length; i++) {
sanim->add_data(value);
}
}
nassertv(sanim->get_num_rows() == table_length);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: EggXfmSAnim::write
// Access: Public, Virtual
@ -230,7 +309,101 @@ get_value(int row, LMatrix4d &mat) const {
// So now we've got the nine components; build a matrix.
compose_matrix(mat, scale, hpr, translate, _coordsys);
}
////////////////////////////////////////////////////////////////////
// Function: EggXfmSAnim::set_value
// Access: Public
// Description: Replaces the indicated row of the table with the
// given matrix.
//
// This function can only be called if all the
// constraints of add_data(), below, are met. Call
// normalize() first if you are not sure.
//
// The return value is true if the matrix can be
// decomposed and stored as scale, rotate, and
// translate, or false otherwise.
////////////////////////////////////////////////////////////////////
bool EggXfmSAnim::
set_value(int row, const LMatrix4d &mat) {
LVector3d scale, hpr, translate;
bool result = decompose_matrix(mat, scale, hpr, translate, _coordsys);
if (!result) {
return false;
}
// Sanity check our sub-tables.
#ifndef NDEBUG
int table_length = -1;
int num_tables = 0;
#endif
const_iterator ci;
for (ci = begin(); ci != end(); ++ci) {
if ((*ci)->is_of_type(EggSAnimData::get_class_type())) {
EggSAnimData *sanim = DCAST(EggSAnimData, *ci);
#ifndef NDEBUG
num_tables++;
// Each table must have the same length.
if (table_length < 0) {
table_length = sanim->get_num_rows();
} else {
nassertr(sanim->get_num_rows() == table_length, false);
}
#endif
// Each child SAnimData table should have a one-letter name.
nassertr(sanim->get_name().length() == 1, false);
switch (sanim->get_name()[0]) {
case 'i':
sanim->set_value(row, scale[0]);
break;
case 'j':
sanim->set_value(row, scale[1]);
break;
case 'k':
sanim->set_value(row, scale[2]);
break;
case 'h':
sanim->set_value(row, hpr[0]);
break;
case 'p':
sanim->set_value(row, hpr[1]);
break;
case 'r':
sanim->set_value(row, hpr[2]);
break;
case 'x':
sanim->set_value(row, translate[0]);
break;
case 'y':
sanim->set_value(row, translate[1]);
break;
case 'z':
sanim->set_value(row, translate[2]);
break;
default:
// One of the child tables had an invalid name.
nassertr(false, false);
}
}
}
nassertr(num_tables == 9, false);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: EggXfmSAnim::add_data
@ -251,7 +424,8 @@ get_value(int row, LMatrix4d &mat) const {
// EggXfmSAnim object and start adding matrices to the
// end; you must clear out the original data first. (As
// a special exception, if no tables exist, they will be
// created.)
// created.) The method normalize() will do this for
// you on an existing EggXfmSAnim.
//
// This function may fail silently if the matrix cannot
// be decomposed into scale, rotate, and translate. In

View File

@ -43,9 +43,13 @@ public:
INLINE CoordinateSystem get_coordinate_system() const;
void optimize();
void normalize();
int get_num_rows() const;
void get_value(int row, LMatrix4d &mat) const;
bool set_value(int row, const LMatrix4d &mat);
INLINE void clear_data();
bool add_data(const LMatrix4d &mat);
virtual void write(ostream &out, int indent_level) const;