30 const string EggXfmSAnim::_standard_order = 
"srpht";
    42   if (convert_from.has_order()) {
    43     set_order(convert_from.get_order());
    45   if (convert_from.has_fps()) {
    46     set_fps(convert_from.
get_fps());
    49   const string &contents = convert_from.get_contents();
    50   for (
int col = 0; col < convert_from.
get_num_cols(); col++) {
    53     for (
int row = 0; row < convert_from.
get_num_rows(); row++) {
    64   iterator ci = begin();
    66     iterator ci_next = ci;
    69     if ((*ci)->is_of_type(EggSAnimData::get_class_type())) {
    78         if (sanim->
has_name() && strchr(
"ijk", sanim->get_name()[0]) != 
nullptr) {
    84         if (fabs(value - default_value) < egg_parameters->_table_threshold) {
   103     normalize_by_rebuilding();
   120     normalize_by_rebuilding();
   126     normalize_by_expanding();
   143 write(std::ostream &out, 
int indent_level)
 const {
   144   test_under_integrity();
   149     indent(out, indent_level + 2) << 
"<Scalar> fps { " << 
get_fps() << 
" }\n";
   153     indent(out, indent_level + 2)
   154       << 
"<Char*> order { " << get_order() << 
" }\n";
   162   memset(tables, 0, 
sizeof(
EggSAnimData *) * num_matrix_components);
   165   for (ci = begin(); ci != end(); ++ci) {
   167     if (child->
is_of_type(EggSAnimData::get_class_type())) {
   171       nassertv(sanim->get_name().length() == 1);
   172       char name = sanim->get_name()[0];
   173       char *p = (
char *)strchr(matrix_component_letters, name);
   174       nassertv(p != 
nullptr);
   176         int index = p - matrix_component_letters;
   177         nassertv(tables[index] == 
nullptr);
   178         tables[index] = sanim;
   182       child->write(out, indent_level + 2);
   187   for (
int i = 0; i < num_matrix_components; i++) {
   188     if (tables[i] != 
nullptr) {
   189       tables[i]->
write(out, indent_level + 2);
   193   indent(out, indent_level) << 
"}\n";
   204                    const LVecBase3d &scale,
   205                    const LVecBase3d &shear,
   206                    const LVecBase3d &hpr,
   207                    const LVecBase3d &trans,
   209                    CoordinateSystem cs) {
   211   mat = LMatrix4d::ident_mat();
   213   bool reverse_roll = 
false;
   215   if (order == 
"sphrt" && egg_support_old_anims) {
   222   string::const_iterator pi;
   223   for (pi = order.begin(); pi != order.end(); ++pi) {
   226       mat = mat * LMatrix4d::scale_shear_mat(scale, shear, cs);
   230       mat = mat * LMatrix4d::rotate_mat_normaxis(hpr[0], LVector3d::up(cs), cs);
   234       mat = mat * LMatrix4d::rotate_mat_normaxis(hpr[1], LVector3d::right(cs), cs);
   239         mat = mat * LMatrix4d::rotate_mat_normaxis(-hpr[2], LVector3d::forward(cs), cs);
   241         mat = mat * LMatrix4d::rotate_mat_normaxis(hpr[2], LVector3d::forward(cs), cs);
   246       mat = mat * LMatrix4d::translate_mat(trans);
   251         << 
"Invalid letter in order string: " << *pi << 
"\n";
   264   bool found_any = 
false;
   268   for (ci = begin(); ci != end(); ++ci) {
   269     if ((*ci)->is_of_type(EggSAnimData::get_class_type())) {
   294   LVector3d scale(1.0, 1.0, 1.0);
   295   LVector3d shear(0.0, 0.0, 0.0);
   296   LVector3d hpr(0.0, 0.0, 0.0);
   297   LVector3d translate(0.0, 0.0, 0.0);
   300   for (ci = begin(); ci != end(); ++ci) {
   301     if ((*ci)->is_of_type(EggSAnimData::get_class_type())) {
   318       nassertv(sanim->get_name().length() == 1);
   320       switch (sanim->get_name()[0]) {
   358         translate[0] = value;
   362         translate[1] = value;
   366         translate[2] = value;
   371         nassert_raise(
"invalid name in child table");
   395   double components[num_matrix_components];
   396   bool add_ok = decompose_matrix(mat, components, _coordsys);
   400   int table_length = -1;
   403   for (
int i = 0; i < num_matrix_components; i++) {
   404     string name(1, matrix_component_letters[i]);
   406     nassertr(child != 
nullptr &&
   407              child->
is_of_type(EggSAnimData::get_class_type()), 
false);
   412     if (table_length < 0) {
   413       table_length = sanim->get_num_rows();
   415       nassertr(sanim->get_num_rows() == table_length, 
false);
   418     sanim->set_value(row, components[i]);
   425   if (!new_mat.almost_equal(mat, 0.005)) {
   427       << 
"After set_row(" << row << 
", ...) to:\n";
   428     mat.write(egg_cat.warning(
false), 2);
   429     egg_cat.warning(
false)
   430       << 
"which produces components:\n";
   431     for (
int i = 0; i < num_matrix_components; i += 3) {
   432       egg_cat.warning(
false)
   434         << matrix_component_letters[i]
   435         << matrix_component_letters[i + 1]
   436         << matrix_component_letters[i + 2]
   438         << components[i] << 
" "   439         << components[i + 1] << 
" "   440         << components[i + 2] << 
"\n";
   442     egg_cat.warning(
false)
   443       << 
"new mat set was:\n";
   444     new_mat.write(egg_cat.warning(
false), 2);
   477   double components[num_matrix_components];
   478   bool add_ok = decompose_matrix(mat, components, _coordsys);
   482     for (
int i = 0; i < num_matrix_components; i++) {
   483       char name = matrix_component_letters[i];
   495   int table_length = -1;
   498   for (
int i = 0; i < num_matrix_components; i++) {
   499     string name(1, matrix_component_letters[i]);
   501     nassertr(child != 
nullptr &&
   502              child->
is_of_type(EggSAnimData::get_class_type()), 
false);
   507     if (table_length < 0) {
   508       table_length = sanim->get_num_rows();
   510       nassertr(sanim->get_num_rows() == table_length, 
false);
   513     sanim->add_data(components[i]);
   519   if (table_length >= 0) {
   524   if (!new_mat.almost_equal(mat, 0.005)) {
   526       << 
"After add_data():\n";
   527     mat.write(egg_cat.warning(
false), 2);
   528     egg_cat.warning(
false)
   529       << 
"which produces components:\n";
   530     for (
int i = 0; i < num_matrix_components; i += 3) {
   531       egg_cat.warning(
false)
   533         << matrix_component_letters[i]
   534         << matrix_component_letters[i + 1]
   535         << matrix_component_letters[i + 2]
   537         << components[i] << 
" "   538         << components[i + 1] << 
" "   539         << components[i + 2] << 
"\n";
   541     egg_cat.warning(
false)
   542       << 
"new mat set was:\n";
   543     new_mat.write(egg_cat.warning(
false), 2);
   559   if (child == 
nullptr) {
   565     DCAST_INTO_V(sanim, child);
   576   nassertv(component >= 0 && component < num_matrix_components);
   578   string name(1, matrix_component_letters[component]);
   588 r_transform(
const LMatrix4d &mat, 
const LMatrix4d &inv,
   589             CoordinateSystem to_cs) {
   592   LMatrix4d inv1 = inv;
   593   inv1.set_row(3, LVector3d(0.0, 0.0, 0.0));
   601   if (to_cs != CS_default) {
   607   for (
int r = 0; r < num_rows; r++) {
   609     bool result = 
add_data(inv1 * orig_mat * mat);
   627 r_mark_coordsys(CoordinateSystem cs) {
   638 normalize_by_rebuilding() {
   647   for (
int r = 0; r < num_rows; r++) {
   665 normalize_by_expanding() {
   670   int table_length = 1;
   671   string remaining_tables = matrix_component_letters;
   673   for (ci = begin(); ci != end(); ++ci) {
   674     if ((*ci)->is_of_type(EggSAnimData::get_class_type())) {
   677       nassertv(sanim->get_name().length() == 1);
   678       char name = sanim->get_name()[0];
   679       size_t p = remaining_tables.find(name);
   680       nassertv(p != string::npos);
   681       remaining_tables[p] = 
' ';
   685         if (table_length == 1) {
   694   if (num_tables < num_matrix_components) {
   696     for (
size_t p = 0; p < remaining_tables.length(); p++) {
   697       if (remaining_tables[p] != 
' ') {
   698         double default_value;
   699         switch (remaining_tables[p]) {
   710         string name(1, remaining_tables[p]);
   719   for (ci = begin(); ci != end(); ++ci) {
   720     if ((*ci)->is_of_type(EggSAnimData::get_class_type())) {
   724         for (
int i = 1; i < table_length; i++) {
 void optimize()
Optimizes the data by collapsing a long table of duplicate values into a single value.
static void compose_with_order(LMatrix4d &mat, const LVecBase3d &scale, const LVecBase3d &shear, const LVecBase3d &hpr, const LVecBase3d &trans, const std::string &order, CoordinateSystem cs)
Composes a matrix out of the nine individual components, respecting the order string.
int get_num_cols() const
Returns the number of columns in the table.
int get_num_rows() const
Returns the number of rows in the table.
void write_header(std::ostream &out, int indent_level, const char *egg_keyword) const
Writes the first line of the egg object, e.g.
bool add_data(const LMatrix4d &mat)
Adds a new matrix to the table, by adding a new row to each of the subtables.
void add_data(double value)
Adds a single element to the table.
virtual void write(std::ostream &out, int indent_level) const
Writes the data to the indicated output stream in Egg format.
A base class for nodes in the hierarchy that are not leaf nodes.
void normalize()
The inverse operation of optimize(), this ensures that all the sub-tables have the same length by dup...
Corresponding to an <S$Anim> entry, this stores a single column of numbers, for instance for a morph ...
CoordinateSystem get_coordinate_system() const
Returns the coordinate system this table believes it is defined within.
double get_value(int row) const
Returns the value at the indicated row.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void write(std::ostream &out, int indent_level) const
Writes the data to the indicated output stream in Egg format.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
double get_value(int row, int col) const
Returns the value at the indicated row.
This corresponds to an <Xfm$Anim_S$> entry, which is a collection of up to nine <S$Anim> entries that...
double get_fps() const
This is only valid if has_fps() returns true.
void steal_children(EggGroupNode &other)
Moves all the children from the other node to this one.
Corresponding to an <Xfm$Anim> entry, this stores a two-dimensional table with up to nine columns,...
void optimize_to_standard_order()
Optimizes the table by collapsing redundant sub-tables, and simultaneously ensures that the order str...
void optimize()
Optimizes the table by collapsing redundant sub-tables.
void get_value(int row, LMatrix4d &mat) const
Returns the value of the aggregate row of the table as a matrix.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
void add_component_data(const std::string &component_name, double value)
Adds a new row to the named component (one of matrix_component_letters) of the table.
int get_num_rows() const
Returns the effective number of rows in the table.
A base class for things that may be directly added into the egg hierarchy.
virtual bool is_anim_matrix() const
Returns true if this node represents a table of animation transformation data, false otherwise.
double get_fps() const
This is only valid if has_fps() returns true.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_num_rows() const
Returns the number of rows in the table.
bool set_value(int row, const LMatrix4d &mat)
Replaces the indicated row of the table with the given matrix.
bool has_name() const
Returns true if the Namable has a nonempty name set, false if the name is empty.
static const std::string & get_standard_order()
Returns the standard order of matrix component composition.
TypeHandle is the identifier used to differentiate C++ class types.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggNode * find_child(const std::string &name) const
Returns the child of this node whose name is the indicated string, or NULL if there is no child of th...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.