panda3d/pandatool/src/xfileegg/xFileAnimationSet.cxx

171 lines
6.1 KiB
C++

// Filename: xFileAnimationSet.cxx
// Created by: drose (02Oct04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "xFileAnimationSet.h"
#include "xFileToEggConverter.h"
#include "config_xfile.h"
#include "eggGroup.h"
#include "eggTable.h"
#include "eggData.h"
#include "eggXfmSAnim.h"
#include "dcast.h"
////////////////////////////////////////////////////////////////////
// Function: XFileAnimationSet::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
XFileAnimationSet::
XFileAnimationSet() {
}
////////////////////////////////////////////////////////////////////
// Function: XFileAnimationSet::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
XFileAnimationSet::
~XFileAnimationSet() {
}
////////////////////////////////////////////////////////////////////
// Function: XFileAnimationSet::create_hierarchy
// Access: Public
// Description: Sets up the hierarchy of EggTables corresponding to
// this AnimationSet.
////////////////////////////////////////////////////////////////////
bool XFileAnimationSet::
create_hierarchy(XFileToEggConverter *converter) {
// Egg animation tables start off with one Table entry, enclosing a
// Bundle entry.
EggTable *table = new EggTable(get_name());
converter->get_egg_data()->add_child(table);
EggTable *bundle = new EggTable(converter->_char_name);
table->add_child(bundle);
bundle->set_table_type(EggTable::TT_bundle);
// Then the Bundle contains a "<skeleton>" entry, which begins the
// animation table hierarchy.
EggTable *skeleton = new EggTable("<skeleton>");
bundle->add_child(skeleton);
// Fill in the rest of the hierarchy with empty tables.
mirror_table(converter, converter->get_dart_node(), skeleton);
// Now populate those empty tables with the frame data.
JointData::const_iterator ji;
for (ji = _joint_data.begin(); ji != _joint_data.end(); ++ji) {
const string &joint_name = (*ji).first;
const FrameData &table = (*ji).second;
EggXfmSAnim *anim_table = get_table(joint_name);
if (anim_table == (EggXfmSAnim *)NULL) {
xfile_cat.warning()
<< "Frame " << joint_name << ", named by animation data, not defined.\n";
} else {
// If we have animation data, apply it.
FrameEntries::const_iterator fi;
for (fi = table._entries.begin(); fi != table._entries.end(); ++fi) {
anim_table->add_data((*fi).get_mat(table._flags));
}
anim_table->optimize();
}
}
// Put some data in the empty tables also.
Tables::iterator ti;
for (ti = _tables.begin(); ti != _tables.end(); ++ti) {
EggXfmSAnim *anim_table = (*ti).second._table;
EggGroup *joint = (*ti).second._joint;
if (anim_table->empty() && joint != (EggGroup *)NULL) {
// If there's no animation data, assign the rest transform.
anim_table->add_data(joint->get_transform3d());
}
anim_table->optimize();
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: XFileAnimationSet::get_table
// Access: Public
// Description: Returns the table associated with the indicated joint
// name.
////////////////////////////////////////////////////////////////////
EggXfmSAnim *XFileAnimationSet::
get_table(const string &joint_name) const {
Tables::const_iterator ti;
ti = _tables.find(joint_name);
if (ti != _tables.end()) {
return (*ti).second._table;
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: XFileAnimationSet::create_frame_data
// Access: Public
// Description: Returns a reference to a new FrameData table
// corresponding to the indicated joint.
////////////////////////////////////////////////////////////////////
XFileAnimationSet::FrameData &XFileAnimationSet::
create_frame_data(const string &joint_name) {
return _joint_data[joint_name];
}
////////////////////////////////////////////////////////////////////
// Function: XFileAnimationSet::mirror_table
// Access: Private
// Description: Builds up a new set of EggTable nodes, as a
// mirror of the existing set of EggGroup (joint)
// nodes, and saves each new table in the _tables
// record.
////////////////////////////////////////////////////////////////////
void XFileAnimationSet::
mirror_table(XFileToEggConverter *converter,
EggGroup *model_node, EggTable *anim_node) {
EggGroupNode::iterator gi;
for (gi = model_node->begin(); gi != model_node->end(); ++gi) {
EggNode *child = (*gi);
if (child->is_of_type(EggGroup::get_class_type())) {
EggGroup *group = DCAST(EggGroup, child);
if (group->get_group_type() == EggGroup::GT_joint) {
// When we come to a <Joint>, create a new Table for it.
EggTable *new_table = new EggTable(group->get_name());
anim_node->add_child(new_table);
CoordinateSystem cs =
converter->get_egg_data()->get_coordinate_system();
EggXfmSAnim *xform = new EggXfmSAnim("xform", cs);
new_table->add_child(xform);
xform->set_fps(converter->_frame_rate);
TablePair &table_pair = _tables[group->get_name()];
table_pair._table = xform;
table_pair._joint = group;
// Now recurse.
mirror_table(converter, group, new_table);
} else {
// If we come to an ordinary <Group>, skip past it.
mirror_table(converter, group, anim_node);
}
}
}
}