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