mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 19:08:55 -04:00
171 lines
6.1 KiB
C++
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);
|
|
}
|
|
}
|
|
}
|
|
}
|