mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
add -zero, etc.
This commit is contained in:
parent
c37f62fd9a
commit
6b7baa43d7
@ -30,6 +30,7 @@
|
|||||||
#include "string_utils.h"
|
#include "string_utils.h"
|
||||||
#include "dcast.h"
|
#include "dcast.h"
|
||||||
#include "pset.h"
|
#include "pset.h"
|
||||||
|
#include "compose_matrix.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -76,6 +77,14 @@ EggOptchar() {
|
|||||||
"and objects can be parented to it. This implies -keep.",
|
"and objects can be parented to it. This implies -keep.",
|
||||||
&EggOptchar::dispatch_vector_string_comma, NULL, &_expose_components);
|
&EggOptchar::dispatch_vector_string_comma, NULL, &_expose_components);
|
||||||
|
|
||||||
|
add_option
|
||||||
|
("zero", "joint[,hprxyzijk]", 0,
|
||||||
|
"Zeroes out the animation channels for the named joint. If "
|
||||||
|
"a subset of the component letters hprxyzijk is included, the "
|
||||||
|
"operation is restricted to just those components; otherwise the "
|
||||||
|
"entire transform is cleared.",
|
||||||
|
&EggOptchar::dispatch_name_components, NULL, &_zero_channels);
|
||||||
|
|
||||||
add_option
|
add_option
|
||||||
("keepall", "", 0,
|
("keepall", "", 0,
|
||||||
"Keep all joints and sliders in the character.",
|
"Keep all joints and sliders in the character.",
|
||||||
@ -117,6 +126,10 @@ run() {
|
|||||||
do_reparent();
|
do_reparent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_zero_channels.empty()) {
|
||||||
|
zero_channels();
|
||||||
|
}
|
||||||
|
|
||||||
int num_characters = _collection->get_num_characters();
|
int num_characters = _collection->get_num_characters();
|
||||||
int ci;
|
int ci;
|
||||||
|
|
||||||
@ -150,6 +163,7 @@ run() {
|
|||||||
// The meat of the program: determine which joints are to be
|
// The meat of the program: determine which joints are to be
|
||||||
// removed, and then actually remove them.
|
// removed, and then actually remove them.
|
||||||
determine_removed_components();
|
determine_removed_components();
|
||||||
|
move_vertices();
|
||||||
if (process_joints()) {
|
if (process_joints()) {
|
||||||
do_reparent();
|
do_reparent();
|
||||||
}
|
}
|
||||||
@ -215,6 +229,55 @@ dispatch_vector_string_pair(const string &opt, const string &arg, void *var) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: ProgramBase::dispatch_name_components
|
||||||
|
// Access: Protected, Static
|
||||||
|
// Description: Accepts a name optionally followed by a comma and some
|
||||||
|
// of the nine standard component letters,
|
||||||
|
//
|
||||||
|
// The data pointer is to StringPairs vector; the pair
|
||||||
|
// will be pushed onto the end of the vector.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool EggOptchar::
|
||||||
|
dispatch_name_components(const string &opt, const string &arg, void *var) {
|
||||||
|
StringPairs *ip = (StringPairs *)var;
|
||||||
|
|
||||||
|
vector_string words;
|
||||||
|
tokenize(arg, words, ",");
|
||||||
|
|
||||||
|
StringPair sp;
|
||||||
|
if (words.size() == 1) {
|
||||||
|
sp._a = words[0];
|
||||||
|
|
||||||
|
} else if (words.size() == 2) {
|
||||||
|
sp._a = words[0];
|
||||||
|
sp._b = words[1];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
nout << "-" << opt
|
||||||
|
<< " requires a pair of strings separated by a comma.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sp._b.empty()) {
|
||||||
|
sp._b = matrix_components;
|
||||||
|
} else {
|
||||||
|
for (string::const_iterator si = sp._b.begin(); si != sp._b.end(); ++si) {
|
||||||
|
if (strchr(matrix_components, *si) == NULL) {
|
||||||
|
nout << "Not a standard matrix component: \"" << *si << "\"\n"
|
||||||
|
<< "-" << opt << " requires a joint name followed by a set "
|
||||||
|
<< "of component names. The standard component names are \""
|
||||||
|
<< matrix_components << "\".\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ip->push_back(sp);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggOptchar::determine_removed_components
|
// Function: EggOptchar::determine_removed_components
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -284,6 +347,43 @@ determine_removed_components() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggOptchar::move_vertices
|
||||||
|
// Access: Private
|
||||||
|
// Description: Moves the vertices from joints that are about to be
|
||||||
|
// removed into the first suitable parent. This might
|
||||||
|
// result in fewer joints being removed (because
|
||||||
|
// the parent might suddenly no longer be empty).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void EggOptchar::
|
||||||
|
move_vertices() {
|
||||||
|
int num_characters = _collection->get_num_characters();
|
||||||
|
for (int ci = 0; ci < num_characters; ci++) {
|
||||||
|
EggCharacterData *char_data = _collection->get_character(ci);
|
||||||
|
int num_joints = char_data->get_num_joints();
|
||||||
|
|
||||||
|
for (int i = 0; i < num_joints; i++) {
|
||||||
|
EggJointData *joint_data = char_data->get_joint(i);
|
||||||
|
EggOptcharUserData *user_data =
|
||||||
|
DCAST(EggOptcharUserData, joint_data->get_user_data());
|
||||||
|
|
||||||
|
if ((user_data->_flags & EggOptcharUserData::F_empty) == 0 &&
|
||||||
|
(user_data->_flags & EggOptcharUserData::F_remove) != 0) {
|
||||||
|
// This joint has vertices, but is scheduled to be removed;
|
||||||
|
// find a suitable home for its vertices.
|
||||||
|
EggJointData *best_joint = find_best_vertex_joint(joint_data->get_parent());
|
||||||
|
joint_data->move_vertices_to(best_joint);
|
||||||
|
|
||||||
|
// Now we can't remove the joint.
|
||||||
|
EggOptcharUserData *best_user_data =
|
||||||
|
DCAST(EggOptcharUserData, best_joint->get_user_data());
|
||||||
|
best_user_data->_flags &= ~(EggOptcharUserData::F_empty | EggOptcharUserData::F_remove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggOptchar::process_joints
|
// Function: EggOptchar::process_joints
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -310,16 +410,10 @@ process_joints() {
|
|||||||
EggOptcharUserData *user_data =
|
EggOptcharUserData *user_data =
|
||||||
DCAST(EggOptcharUserData, joint_data->get_user_data());
|
DCAST(EggOptcharUserData, joint_data->get_user_data());
|
||||||
|
|
||||||
EggJointData *best_parent = find_best_parent(joint_data->get_parent());
|
|
||||||
|
|
||||||
if ((user_data->_flags & EggOptcharUserData::F_remove) != 0) {
|
if ((user_data->_flags & EggOptcharUserData::F_remove) != 0) {
|
||||||
// This joint will be removed, so reparent it to nothing.
|
// This joint will be removed, so reparent it to nothing.
|
||||||
joint_data->reparent_to((EggJointData *)NULL);
|
joint_data->reparent_to((EggJointData *)NULL);
|
||||||
|
|
||||||
// Move the vertices associated with this joint into its
|
|
||||||
// parent.
|
|
||||||
joint_data->move_vertices_to(best_parent);
|
|
||||||
|
|
||||||
// Determine what kind of node it is we're removing, for the
|
// Determine what kind of node it is we're removing, for the
|
||||||
// user's information.
|
// user's information.
|
||||||
if ((user_data->_flags & EggOptcharUserData::F_identity) != 0) {
|
if ((user_data->_flags & EggOptcharUserData::F_identity) != 0) {
|
||||||
@ -334,6 +428,7 @@ process_joints() {
|
|||||||
} else {
|
} else {
|
||||||
// This joint will be preserved, but maybe its parent will
|
// This joint will be preserved, but maybe its parent will
|
||||||
// change.
|
// change.
|
||||||
|
EggJointData *best_parent = find_best_parent(joint_data->get_parent());
|
||||||
joint_data->reparent_to(best_parent);
|
joint_data->reparent_to(best_parent);
|
||||||
if ((user_data->_flags & EggOptcharUserData::F_expose) != 0) {
|
if ((user_data->_flags & EggOptcharUserData::F_expose) != 0) {
|
||||||
joint_data->expose();
|
joint_data->expose();
|
||||||
@ -348,7 +443,7 @@ process_joints() {
|
|||||||
} else {
|
} else {
|
||||||
nout << char_data->get_name() << ": of " << num_joints
|
nout << char_data->get_name() << ": of " << num_joints
|
||||||
<< " joints, removing " << num_identity << " identity, "
|
<< " joints, removing " << num_identity << " identity, "
|
||||||
<< num_static << " static, and " << num_empty
|
<< num_static << " unanimated, and " << num_empty
|
||||||
<< " empty joints, leaving " << num_kept << ".\n";
|
<< " empty joints, leaving " << num_kept << ".\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -359,7 +454,7 @@ process_joints() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggOptchar::find_best_parent
|
// Function: EggOptchar::find_best_parent
|
||||||
// Access: Private
|
// Access: Private
|
||||||
// Description: Searches for this first joint at this level or above
|
// Description: Searches for the first joint at this level or above
|
||||||
// that is not scheduled to be removed. This is the
|
// that is not scheduled to be removed. This is the
|
||||||
// joint that the first child of this joint should be
|
// joint that the first child of this joint should be
|
||||||
// reparented to.
|
// reparented to.
|
||||||
@ -371,9 +466,33 @@ find_best_parent(EggJointData *joint_data) const {
|
|||||||
|
|
||||||
if ((user_data->_flags & EggOptcharUserData::F_remove) != 0) {
|
if ((user_data->_flags & EggOptcharUserData::F_remove) != 0) {
|
||||||
// Keep going.
|
// Keep going.
|
||||||
nassertr(joint_data->get_parent() != (EggJointData *)NULL, NULL);
|
if (joint_data->get_parent() != (EggJointData *)NULL) {
|
||||||
return find_best_parent(joint_data->get_parent());
|
return find_best_parent(joint_data->get_parent());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the one!
|
||||||
|
return joint_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggOptchar::find_best_vertex_joint
|
||||||
|
// Access: Private
|
||||||
|
// Description: Searches for the first joint at this level or above
|
||||||
|
// that is not static. This is the joint that the
|
||||||
|
// vertices of this joint should be moved into.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
EggJointData *EggOptchar::
|
||||||
|
find_best_vertex_joint(EggJointData *joint_data) const {
|
||||||
|
EggOptcharUserData *user_data =
|
||||||
|
DCAST(EggOptcharUserData, joint_data->get_user_data());
|
||||||
|
|
||||||
|
if ((user_data->_flags & EggOptcharUserData::F_static) != 0) {
|
||||||
|
// Keep going.
|
||||||
|
if (joint_data->get_parent() != (EggJointData *)NULL) {
|
||||||
|
return find_best_vertex_joint(joint_data->get_parent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This is the one!
|
// This is the one!
|
||||||
return joint_data;
|
return joint_data;
|
||||||
@ -419,6 +538,41 @@ apply_user_reparents() {
|
|||||||
return did_anything;
|
return did_anything;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggOptchar::zero_channels
|
||||||
|
// Access: Private
|
||||||
|
// Description: Zeroes out the channels specified by the user on the
|
||||||
|
// command line.
|
||||||
|
//
|
||||||
|
// Returns true if any operation was performed, false
|
||||||
|
// otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool EggOptchar::
|
||||||
|
zero_channels() {
|
||||||
|
bool did_anything = false;
|
||||||
|
int num_characters = _collection->get_num_characters();
|
||||||
|
|
||||||
|
StringPairs::const_iterator spi;
|
||||||
|
for (spi = _zero_channels.begin(); spi != _zero_channels.end(); ++spi) {
|
||||||
|
const StringPair &p = (*spi);
|
||||||
|
|
||||||
|
for (int ci = 0; ci < num_characters; ci++) {
|
||||||
|
EggCharacterData *char_data = _collection->get_character(ci);
|
||||||
|
EggJointData *joint_data = char_data->find_joint(p._a);
|
||||||
|
|
||||||
|
if (joint_data == (EggJointData *)NULL) {
|
||||||
|
nout << "No joint named " << p._a << " in " << char_data->get_name()
|
||||||
|
<< ".\n";
|
||||||
|
} else {
|
||||||
|
joint_data->zero_channels(p._b);
|
||||||
|
did_anything = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return did_anything;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggOptchar::analyze_joints
|
// Function: EggOptchar::analyze_joints
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -458,7 +612,7 @@ analyze_joints(EggJointData *joint_data) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// This is a second or later matrix.
|
// This is a second or later matrix.
|
||||||
if (!mat.almost_equal(user_data->_static_mat)) {
|
if (!mat.almost_equal(user_data->_static_mat, 0.0001)) {
|
||||||
// It's different than the first one.
|
// It's different than the first one.
|
||||||
different_mat = true;
|
different_mat = true;
|
||||||
}
|
}
|
||||||
@ -472,7 +626,7 @@ analyze_joints(EggJointData *joint_data) {
|
|||||||
user_data->_flags |= EggOptcharUserData::F_static;
|
user_data->_flags |= EggOptcharUserData::F_static;
|
||||||
|
|
||||||
if (num_mats == 0 ||
|
if (num_mats == 0 ||
|
||||||
user_data->_static_mat.almost_equal(LMatrix4d::ident_mat())) {
|
user_data->_static_mat.almost_equal(LMatrix4d::ident_mat(), 0.0001)) {
|
||||||
// It's not only static, but it's the identity matrix.
|
// It's not only static, but it's the identity matrix.
|
||||||
user_data->_flags |= EggOptcharUserData::F_identity;
|
user_data->_flags |= EggOptcharUserData::F_identity;
|
||||||
}
|
}
|
||||||
@ -531,7 +685,7 @@ analyze_sliders(EggCharacterData *char_data) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// This is a second or later value.
|
// This is a second or later value.
|
||||||
if (!IS_NEARLY_EQUAL(value, user_data->_static_value)) {
|
if (!IS_THRESHOLD_EQUAL(value, user_data->_static_value, 0.0001)) {
|
||||||
// It's different than the first one.
|
// It's different than the first one.
|
||||||
different_value = true;
|
different_value = true;
|
||||||
}
|
}
|
||||||
@ -544,7 +698,7 @@ analyze_sliders(EggCharacterData *char_data) {
|
|||||||
// All the values are the same for this slider.
|
// All the values are the same for this slider.
|
||||||
user_data->_flags |= EggOptcharUserData::F_static;
|
user_data->_flags |= EggOptcharUserData::F_static;
|
||||||
|
|
||||||
if (num_values == 0 || IS_NEARLY_EQUAL(user_data->_static_value, 0.0)) {
|
if (num_values == 0 || IS_THRESHOLD_ZERO(user_data->_static_value, 0.0001)) {
|
||||||
// It's not only static, but it's the identity value.
|
// It's not only static, but it's the identity value.
|
||||||
user_data->_flags |= EggOptcharUserData::F_identity;
|
user_data->_flags |= EggOptcharUserData::F_identity;
|
||||||
}
|
}
|
||||||
|
@ -51,12 +51,16 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static bool dispatch_vector_string_pair(const string &opt, const string &arg, void *var);
|
static bool dispatch_vector_string_pair(const string &opt, const string &arg, void *var);
|
||||||
|
static bool dispatch_name_components(const string &opt, const string &arg, void *var);
|
||||||
|
|
||||||
void determine_removed_components();
|
void determine_removed_components();
|
||||||
|
void move_vertices();
|
||||||
bool process_joints();
|
bool process_joints();
|
||||||
EggJointData *find_best_parent(EggJointData *joint_data) const;
|
EggJointData *find_best_parent(EggJointData *joint_data) const;
|
||||||
|
EggJointData *find_best_vertex_joint(EggJointData *joint_data) const;
|
||||||
|
|
||||||
bool apply_user_reparents();
|
bool apply_user_reparents();
|
||||||
|
bool zero_channels();
|
||||||
void analyze_joints(EggJointData *joint_data);
|
void analyze_joints(EggJointData *joint_data);
|
||||||
void analyze_sliders(EggCharacterData *char_data);
|
void analyze_sliders(EggCharacterData *char_data);
|
||||||
void list_joints(EggJointData *joint_data, int indent_level);
|
void list_joints(EggJointData *joint_data, int indent_level);
|
||||||
@ -80,6 +84,7 @@ private:
|
|||||||
};
|
};
|
||||||
typedef pvector<StringPair> StringPairs;
|
typedef pvector<StringPair> StringPairs;
|
||||||
StringPairs _reparent_joints;
|
StringPairs _reparent_joints;
|
||||||
|
StringPairs _zero_channels;
|
||||||
|
|
||||||
vector_string _keep_components;
|
vector_string _keep_components;
|
||||||
vector_string _expose_components;
|
vector_string _expose_components;
|
||||||
|
@ -175,8 +175,13 @@ do_reparent() {
|
|||||||
// hierarchy.
|
// hierarchy.
|
||||||
if (joint_data->get_parent() != (EggJointData *)NULL) {
|
if (joint_data->get_parent() != (EggJointData *)NULL) {
|
||||||
nout << "Warning: reparenting " << joint_data->get_name()
|
nout << "Warning: reparenting " << joint_data->get_name()
|
||||||
<< " to " << joint_data->get_parent()->get_name()
|
<< " to ";
|
||||||
<< " results in a skew transform.\n";
|
if (joint_data->get_parent() == _root_joint) {
|
||||||
|
nout << "the root";
|
||||||
|
} else {
|
||||||
|
nout << joint_data->get_parent()->get_name();
|
||||||
|
}
|
||||||
|
nout << " results in a skew transform.\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,6 +224,31 @@ expose(EggGroup::DCSType dcs_type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggJointData::zero_channels
|
||||||
|
// Access: Public
|
||||||
|
// Description: Calls zero_channels() on all models, and recursively on
|
||||||
|
// all joints at this node and below.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void EggJointData::
|
||||||
|
zero_channels(const string &components) {
|
||||||
|
BackPointers::iterator bpi;
|
||||||
|
for (bpi = _back_pointers.begin(); bpi != _back_pointers.end(); ++bpi) {
|
||||||
|
EggBackPointer *back = (*bpi);
|
||||||
|
if (back != (EggBackPointer *)NULL) {
|
||||||
|
EggJointPointer *joint;
|
||||||
|
DCAST_INTO_V(joint, back);
|
||||||
|
joint->zero_channels(components);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Children::iterator ci;
|
||||||
|
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||||
|
EggJointData *child = (*ci);
|
||||||
|
child->zero_channels(components);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggJointData::add_back_pointer
|
// Function: EggJointData::add_back_pointer
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -53,6 +53,7 @@ public:
|
|||||||
bool do_rebuild();
|
bool do_rebuild();
|
||||||
void optimize();
|
void optimize();
|
||||||
void expose(EggGroup::DCSType dcs_type = EggGroup::DC_default);
|
void expose(EggGroup::DCSType dcs_type = EggGroup::DC_default);
|
||||||
|
void zero_channels(const string &components);
|
||||||
|
|
||||||
virtual void add_back_pointer(int model_index, EggObject *egg_object);
|
virtual void add_back_pointer(int model_index, EggObject *egg_object);
|
||||||
virtual void write(ostream &out, int indent_level = 0) const;
|
virtual void write(ostream &out, int indent_level = 0) const;
|
||||||
|
@ -115,3 +115,13 @@ optimize() {
|
|||||||
void EggJointPointer::
|
void EggJointPointer::
|
||||||
expose(EggGroup::DCSType) {
|
expose(EggGroup::DCSType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggJointPointer::zero_channels
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Zeroes out the named components of the transform in
|
||||||
|
// the animation frames.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void EggJointPointer::
|
||||||
|
zero_channels(const string &) {
|
||||||
|
}
|
||||||
|
@ -52,6 +52,7 @@ public:
|
|||||||
|
|
||||||
virtual void optimize();
|
virtual void optimize();
|
||||||
virtual void expose(EggGroup::DCSType dcs_type);
|
virtual void expose(EggGroup::DCSType dcs_type);
|
||||||
|
virtual void zero_channels(const string &components);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef pvector<LMatrix4d> RebuildFrames;
|
typedef pvector<LMatrix4d> RebuildFrames;
|
||||||
|
@ -200,3 +200,27 @@ optimize() {
|
|||||||
_xform->optimize();
|
_xform->optimize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggMatrixTablePointer::zero_channels
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Zeroes out the named components of the transform in
|
||||||
|
// the animation frames.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void EggMatrixTablePointer::
|
||||||
|
zero_channels(const string &components) {
|
||||||
|
if (_xform == (EggXfmSAnim *)NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is particularly easy: we only have to remove children from
|
||||||
|
// the _xform object whose name is listed in the components.
|
||||||
|
string::const_iterator si;
|
||||||
|
for (si = components.begin(); si != components.end(); ++si) {
|
||||||
|
string table_name(1, *si);
|
||||||
|
EggNode *child = _xform->find_child(table_name);
|
||||||
|
if (child != (EggNode *)NULL) {
|
||||||
|
_xform->remove_child(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -48,6 +48,7 @@ public:
|
|||||||
virtual bool do_rebuild();
|
virtual bool do_rebuild();
|
||||||
|
|
||||||
virtual void optimize();
|
virtual void optimize();
|
||||||
|
virtual void zero_channels(const string &components);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PT(EggTable) _table;
|
PT(EggTable) _table;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user