Panda3D
xFileAnimationSet.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file xFileAnimationSet.cxx
10  * @author drose
11  * @date 2004-10-02
12  */
13 
14 #include "xFileAnimationSet.h"
15 #include "xFileToEggConverter.h"
16 #include "config_xfile.h"
17 #include "eggGroup.h"
18 #include "eggTable.h"
19 #include "eggData.h"
20 #include "eggXfmSAnim.h"
21 #include "dcast.h"
22 
23 /**
24  *
25  */
26 XFileAnimationSet::
27 XFileAnimationSet() {
28  _frame_rate = 0.0;
29 }
30 
31 /**
32  *
33  */
34 XFileAnimationSet::
35 ~XFileAnimationSet() {
36 }
37 
38 /**
39  * Sets up the hierarchy of EggTables corresponding to this AnimationSet.
40  */
43  // Egg animation tables start off with one Table entry, enclosing a Bundle
44  // entry.
45  EggTable *table = new EggTable(get_name());
46  converter->get_egg_data()->add_child(table);
47  EggTable *bundle = new EggTable(converter->_char_name);
48  table->add_child(bundle);
49  bundle->set_table_type(EggTable::TT_bundle);
50 
51  // Then the Bundle contains a "<skeleton>" entry, which begins the animation
52  // table hierarchy.
53  EggTable *skeleton = new EggTable("<skeleton>");
54  bundle->add_child(skeleton);
55 
56  // Fill in the rest of the hierarchy with empty tables.
57  mirror_table(converter, converter->get_dart_node(), skeleton);
58 
59  // Now populate those empty tables with the frame data.
60  JointData::const_iterator ji;
61  for (ji = _joint_data.begin(); ji != _joint_data.end(); ++ji) {
62  const std::string &joint_name = (*ji).first;
63  const FrameData &table = (*ji).second;
64 
65  EggXfmSAnim *anim_table = get_table(joint_name);
66  if (anim_table == nullptr) {
67  xfile_cat.warning()
68  << "Frame " << joint_name << ", named by animation data, not defined.\n";
69  } else {
70  // If we have animation data, apply it.
71  FrameEntries::const_iterator fi;
72  for (fi = table._entries.begin(); fi != table._entries.end(); ++fi) {
73  anim_table->add_data((*fi).get_mat(table._flags));
74  }
75  anim_table->optimize();
76  }
77  }
78 
79  // Put some data in the empty tables also.
80  Tables::iterator ti;
81  for (ti = _tables.begin(); ti != _tables.end(); ++ti) {
82  EggXfmSAnim *anim_table = (*ti).second._table;
83  EggGroup *joint = (*ti).second._joint;
84  if (anim_table->empty() && joint != nullptr) {
85  // If there's no animation data, assign the rest transform.
86  anim_table->add_data(joint->get_transform3d());
87  }
88  anim_table->optimize();
89  if (_frame_rate != 0.0) {
90  anim_table->set_fps(_frame_rate);
91  }
92  }
93 
94  return true;
95 }
96 
97 /**
98  * Returns the table associated with the indicated joint name.
99  */
101 get_table(const std::string &joint_name) const {
102  Tables::const_iterator ti;
103  ti = _tables.find(joint_name);
104  if (ti != _tables.end()) {
105  return (*ti).second._table;
106  }
107  return nullptr;
108 }
109 
110 /**
111  * Returns a reference to a new FrameData table corresponding to the indicated
112  * joint.
113  */
115 create_frame_data(const std::string &joint_name) {
116  return _joint_data[joint_name];
117 }
118 
119 /**
120  * Builds up a new set of EggTable nodes, as a mirror of the existing set of
121  * EggGroup (joint) nodes, and saves each new table in the _tables record.
122  */
123 void XFileAnimationSet::
124 mirror_table(XFileToEggConverter *converter,
125  EggGroup *model_node, EggTable *anim_node) {
126  EggGroupNode::iterator gi;
127  for (gi = model_node->begin(); gi != model_node->end(); ++gi) {
128  EggNode *child = (*gi);
129  if (child->is_of_type(EggGroup::get_class_type())) {
130  EggGroup *group = DCAST(EggGroup, child);
131  if (group->get_group_type() == EggGroup::GT_joint) {
132  // When we come to a <Joint>, create a new Table for it.
133  EggTable *new_table = new EggTable(group->get_name());
134  anim_node->add_child(new_table);
135  CoordinateSystem cs =
136  converter->get_egg_data()->get_coordinate_system();
137  EggXfmSAnim *xform = new EggXfmSAnim("xform", cs);
138  new_table->add_child(xform);
139  xform->set_fps(converter->_frame_rate);
140  TablePair &table_pair = _tables[group->get_name()];
141  table_pair._table = xform;
142  table_pair._joint = group;
143 
144  // Now recurse.
145  mirror_table(converter, group, new_table);
146 
147  } else {
148  // If we come to an ordinary <Group>, skip past it.
149  mirror_table(converter, group, anim_node);
150  }
151  }
152  }
153 }
get_coordinate_system
Returns the coordinate system in which the egg file is defined.
Definition: eggData.h:73
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Definition: eggGroup.h:34
A base class for things that may be directly added into the egg hierarchy.
Definition: eggNode.h:36
This corresponds to a.
Definition: eggTable.h:27
const LMatrix4d & get_transform3d() const
Returns the overall transform as a 4x4 matrix.
Definition: eggTransform.I:212
This corresponds to an <Xfm$Anim_S$> entry, which is a collection of up to nine <S$Anim> entries that...
Definition: eggXfmSAnim.h:28
void optimize()
Optimizes the table by collapsing redundant sub-tables.
Definition: eggXfmSAnim.cxx:63
bool add_data(const LMatrix4d &mat)
Adds a new matrix to the table, by adding a new row to each of the subtables.
EggData * get_egg_data()
Returns the EggData structure.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
bool create_hierarchy(XFileToEggConverter *converter)
Sets up the hierarchy of EggTables corresponding to this AnimationSet.
EggXfmSAnim * get_table(const std::string &joint_name) const
Returns the table associated with the indicated joint name.
FrameData & create_frame_data(const std::string &joint_name)
Returns a reference to a new FrameData table corresponding to the indicated joint.
EggGroup * get_dart_node() const
Returns the root of the joint hierarchy, if _make_char is true, or NULL otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.