fix problem with misassignment of vertices when eliminating top joint

This commit is contained in:
David Rose 2004-03-01 23:55:04 +00:00
parent 54ae975f3c
commit b37e90743e
4 changed files with 42 additions and 9 deletions

View File

@ -185,7 +185,7 @@ run() {
// Now we can analyze the joints for their properties.
for (ci = 0; ci < num_characters; ci++) {
EggCharacterData *char_data = _collection->get_character(ci);
analyze_joints(char_data->get_root_joint());
analyze_joints(char_data->get_root_joint(), 0);
analyze_sliders(char_data);
}
@ -419,7 +419,7 @@ determine_removed_components() {
for (int ci = 0; ci < num_characters; ci++) {
EggCharacterData *char_data = _collection->get_character(ci);
int num_components = char_data->get_num_components();
cerr << char_data->get_name() << " has " << num_components << " components.\n";
nout << char_data->get_name() << " has " << num_components << " components.\n";
for (int i = 0; i < num_components; i++) {
EggComponentData *comp_data = char_data->get_component(i);
nassertv(comp_data != (EggComponentData *)NULL);
@ -446,7 +446,19 @@ determine_removed_components() {
} else {
// Remove this component if it's unanimated or empty.
if ((user_data->_flags & (EggOptcharUserData::F_static | EggOptcharUserData::F_empty)) != 0) {
user_data->_flags |= EggOptcharUserData::F_remove;
if ((user_data->_flags & (EggOptcharUserData::F_top | EggOptcharUserData::F_empty)) == EggOptcharUserData::F_top) {
// Actually, we can't remove it if it's a top joint,
// unless it's also empty. That's because vertices that
// are partially assigned to this joint would then have no
// joint to represent the same partial assignment, and
// they would then appear to be wholly assigned to their
// other joint, which would be incorrect.
} else {
// But joints that aren't top joints (or that are empty)
// are o.k. to remove.
user_data->_flags |= EggOptcharUserData::F_remove;
}
}
}
}
@ -523,7 +535,6 @@ move_vertices() {
////////////////////////////////////////////////////////////////////
bool EggOptchar::
process_joints() {
cerr << "process_joints\n";
bool removed_any = false;
int num_characters = _collection->get_num_characters();
for (int ci = 0; ci < num_characters; ci++) {
@ -772,10 +783,17 @@ zero_channels() {
// joint.
////////////////////////////////////////////////////////////////////
void EggOptchar::
analyze_joints(EggJointData *joint_data) {
analyze_joints(EggJointData *joint_data, int level) {
PT(EggOptcharUserData) user_data = new EggOptcharUserData;
joint_data->set_user_data(user_data);
if (level == 1) {
// The child joints of the root joint are deemed "top" joints.
// These may not be removed unless they are empty (because their
// vertices have no joint to be moved into).
user_data->_flags |= EggOptcharUserData::F_top;
}
// Analyze the table of matrices for this joint, checking to see if
// they're all the same across all frames, or if any of them are
// different; also look for empty joints (that control no vertices).
@ -831,7 +849,7 @@ analyze_joints(EggJointData *joint_data) {
int num_children = joint_data->get_num_children();
for (i = 0; i < num_children; i++) {
analyze_joints(joint_data->get_child(i));
analyze_joints(joint_data->get_child(i), level + 1);
}
}
@ -999,6 +1017,9 @@ describe_component(EggComponentData *comp_data, int indent_level,
if (user_data->is_empty()) {
cout << " (empty)";
}
if (user_data->is_top()) {
cout << " (top)";
}
}
cout << "\n";
}

View File

@ -64,7 +64,7 @@ private:
bool apply_user_reparents();
bool zero_channels();
void analyze_joints(EggJointData *joint_data);
void analyze_joints(EggJointData *joint_data, int level);
void analyze_sliders(EggCharacterData *char_data);
void list_joints(EggJointData *joint_data, int indent_level, bool verbose);
void list_joints_p(EggJointData *joint_data, int &col);

View File

@ -87,3 +87,13 @@ INLINE bool EggOptcharUserData::
is_empty() const {
return (_flags & F_empty) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: EggOptcharUserData::is_top
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool EggOptcharUserData::
is_top() const {
return (_flags & F_top) != 0;
}

View File

@ -38,13 +38,15 @@ public:
INLINE bool is_static() const;
INLINE bool is_identity() const;
INLINE bool is_empty() const;
INLINE bool is_top() const;
enum Flags {
F_static = 0x0001,
F_identity = 0x0002,
F_empty = 0x0004,
F_remove = 0x0008,
F_expose = 0x0010,
F_top = 0x0008,
F_remove = 0x0010,
F_expose = 0x0020,
};
int _flags;
LMatrix4d _static_mat;