mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 17:35:34 -04:00
add egg-optchar -qa
This commit is contained in:
parent
21483c7e2b
commit
b8ade26846
@ -149,11 +149,24 @@ EggOptchar() {
|
||||
add_option
|
||||
("q", "quantum", 0,
|
||||
"Quantize joint membership values to the given unit. This is "
|
||||
"the smallest significant change in joint membership. The "
|
||||
"default is 0.01; specifying 0 means to preserve the original "
|
||||
"values.",
|
||||
"the smallest significant change in joint membership. There can "
|
||||
"be a significant performance (and memory utilization) runtime "
|
||||
"benefit for eliminating small differences in joint memberships "
|
||||
"between neighboring vertices. The default is 0.01; specifying "
|
||||
"0 means to preserve the original values.",
|
||||
&EggOptchar::dispatch_double, NULL, &_vref_quantum);
|
||||
|
||||
add_option
|
||||
("qa", "quantum[,hprxyzijkabc]", 0,
|
||||
"Quantizes animation channels to the given unit. This rounds each "
|
||||
"of the named components of all joints to the nearest multiple of unit. "
|
||||
"There is no performance benefit, and little compression benefit, "
|
||||
"for doing this; and this may introduce visible artifacts to the "
|
||||
"animation. However, sometimes it is a useful tool for animation "
|
||||
"analysis and comparison. This option may be repeated several times "
|
||||
"to quantize different channels by a different amount.",
|
||||
&EggOptchar::dispatch_double_components, NULL, &_quantize_anims);
|
||||
|
||||
_optimal_hierarchy = false;
|
||||
_vref_quantum = 0.01;
|
||||
}
|
||||
@ -218,15 +231,18 @@ run() {
|
||||
do_reparent();
|
||||
}
|
||||
|
||||
// We currently do not implement optimizing morph sliders. Need
|
||||
// to add this at some point; it's quite easy. Identity and empty
|
||||
// morph sliders can simply be removed, while static sliders need
|
||||
// to be applied to the vertices and then removed.
|
||||
|
||||
// Quantize the vertex memberships. We call this even if
|
||||
// _vref_quantum is 0, because this also normalizes the vertex
|
||||
// memberships.
|
||||
quantize_vertices();
|
||||
|
||||
// We currently do not implement optimizing morph sliders. Need
|
||||
// to add this at some point; it's quite easy. Identity and empty
|
||||
// morph sliders can simply be removed, while static sliders need
|
||||
// to be applied to the vertices and then removed.
|
||||
// Also quantize the animation channels, if the user so requested.
|
||||
quantize_channels();
|
||||
|
||||
// Finally, flag all the groups as the user requested.
|
||||
if (!_flag_groups.empty()) {
|
||||
@ -336,6 +352,63 @@ dispatch_name_components(const string &opt, const string &arg, void *var) {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ProgramBase::dispatch_double_components
|
||||
// Access: Protected, Static
|
||||
// Description: Accepts a double value optionally followed by a comma
|
||||
// and some of the nine standard component letters,
|
||||
//
|
||||
// The data pointer is to a DoubleStrings vector; the
|
||||
// pair will be pushed onto the end of the vector.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggOptchar::
|
||||
dispatch_double_components(const string &opt, const string &arg, void *var) {
|
||||
DoubleStrings *ip = (DoubleStrings *)var;
|
||||
|
||||
vector_string words;
|
||||
tokenize(arg, words, ",");
|
||||
|
||||
bool valid_double = false;
|
||||
|
||||
DoubleString sp;
|
||||
if (words.size() == 1) {
|
||||
valid_double = string_to_double(words[0], sp._a);
|
||||
|
||||
} else if (words.size() == 2) {
|
||||
valid_double = string_to_double(words[0], sp._a);
|
||||
sp._b = words[1];
|
||||
|
||||
} else {
|
||||
nout << "-" << opt
|
||||
<< " requires a numeric value followed by a string.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!valid_double) {
|
||||
nout << "-" << opt
|
||||
<< " requires a numeric value followed by a string.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sp._b.empty()) {
|
||||
sp._b = matrix_component_letters;
|
||||
} else {
|
||||
for (string::const_iterator si = sp._b.begin(); si != sp._b.end(); ++si) {
|
||||
if (strchr(matrix_component_letters, *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_component_letters << "\".\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ip->push_back(sp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ProgramBase::dispatch_flag_groups
|
||||
// Access: Protected, Static
|
||||
@ -775,6 +848,38 @@ zero_channels() {
|
||||
return did_anything;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggOptchar::quantize_channels
|
||||
// Access: Private
|
||||
// Description: Quantizes the channels specified by the user on the
|
||||
// command line.
|
||||
//
|
||||
// Returns true if any operation was performed, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggOptchar::
|
||||
quantize_channels() {
|
||||
bool did_anything = false;
|
||||
int num_characters = _collection->get_num_characters();
|
||||
|
||||
DoubleStrings::const_iterator spi;
|
||||
for (spi = _quantize_anims.begin(); spi != _quantize_anims.end(); ++spi) {
|
||||
const DoubleString &p = (*spi);
|
||||
|
||||
for (int ci = 0; ci < num_characters; ci++) {
|
||||
EggCharacterData *char_data = _collection->get_character(ci);
|
||||
EggJointData *joint_data = char_data->get_root_joint();
|
||||
|
||||
if (joint_data != (EggJointData *)NULL) {
|
||||
joint_data->quantize_channels(p._b, p._a);
|
||||
did_anything = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return did_anything;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggOptchar::analyze_joints
|
||||
// Access: Private
|
||||
|
@ -54,6 +54,7 @@ protected:
|
||||
private:
|
||||
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);
|
||||
static bool dispatch_double_components(const string &opt, const string &arg, void *var);
|
||||
static bool dispatch_flag_groups(const string &opt, const string &arg, void *var);
|
||||
|
||||
void determine_removed_components();
|
||||
@ -64,6 +65,7 @@ private:
|
||||
|
||||
bool apply_user_reparents();
|
||||
bool zero_channels();
|
||||
bool quantize_channels();
|
||||
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);
|
||||
@ -99,6 +101,14 @@ private:
|
||||
vector_string _drop_components;
|
||||
vector_string _expose_components;
|
||||
|
||||
class DoubleString {
|
||||
public:
|
||||
double _a;
|
||||
string _b;
|
||||
};
|
||||
typedef pvector<DoubleString> DoubleStrings;
|
||||
DoubleStrings _quantize_anims;
|
||||
|
||||
typedef pvector<GlobPattern> Globs;
|
||||
|
||||
class FlagGroupsEntry {
|
||||
|
@ -400,6 +400,31 @@ zero_channels(const string &components) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggJointData::quantize_channels
|
||||
// Access: Public
|
||||
// Description: Calls quantize_channels() on all models for this joint,
|
||||
// and then recurses downwards to all joints below.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggJointData::
|
||||
quantize_channels(const string &components, double quantum) {
|
||||
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->quantize_channels(components, quantum);
|
||||
}
|
||||
}
|
||||
|
||||
Children::iterator ci;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
EggJointData *child = (*ci);
|
||||
child->quantize_channels(components, quantum);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggJointData::add_back_pointer
|
||||
// Access: Public, Virtual
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
void optimize();
|
||||
void expose(EggGroup::DCSType dcs_type = EggGroup::DC_default);
|
||||
void zero_channels(const string &components);
|
||||
void quantize_channels(const string &components, double quantum);
|
||||
|
||||
virtual void add_back_pointer(int model_index, EggObject *egg_object);
|
||||
virtual void write(ostream &out, int indent_level = 0) const;
|
||||
|
@ -125,3 +125,13 @@ expose(EggGroup::DCSType) {
|
||||
void EggJointPointer::
|
||||
zero_channels(const string &) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggJointPointer::quantize_channels
|
||||
// Access: Public, Virtual
|
||||
// Description: Rounds the named components of the transform to the
|
||||
// nearest multiple of quantum.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggJointPointer::
|
||||
quantize_channels(const string &, double) {
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ public:
|
||||
virtual void optimize();
|
||||
virtual void expose(EggGroup::DCSType dcs_type);
|
||||
virtual void zero_channels(const string &components);
|
||||
virtual void quantize_channels(const string &components, double quantum);
|
||||
|
||||
virtual EggJointPointer *make_new_joint(const string &name)=0;
|
||||
|
||||
|
@ -250,6 +250,32 @@ zero_channels(const string &components) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMatrixTablePointer::quantize_channels
|
||||
// Access: Public, Virtual
|
||||
// Description: Rounds the named components of the transform to the
|
||||
// nearest multiple of quantum.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMatrixTablePointer::
|
||||
quantize_channels(const string &components, double quantum) {
|
||||
if (_xform == (EggXfmSAnim *)NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is similar to the above: we quantize children of 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 &&
|
||||
child->is_of_type(EggSAnimData::get_class_type())) {
|
||||
EggSAnimData *anim = DCAST(EggSAnimData, child);
|
||||
anim->quantize(quantum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMatrixTablePointer::make_new_joint
|
||||
// Access: Public, Virtual
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
|
||||
virtual void optimize();
|
||||
virtual void zero_channels(const string &components);
|
||||
virtual void quantize_channels(const string &components, double quantum);
|
||||
|
||||
virtual EggJointPointer *make_new_joint(const string &name);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user