mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
add egg-optchar -qa
This commit is contained in:
parent
21483c7e2b
commit
b8ade26846
@ -149,11 +149,24 @@ EggOptchar() {
|
|||||||
add_option
|
add_option
|
||||||
("q", "quantum", 0,
|
("q", "quantum", 0,
|
||||||
"Quantize joint membership values to the given unit. This is "
|
"Quantize joint membership values to the given unit. This is "
|
||||||
"the smallest significant change in joint membership. The "
|
"the smallest significant change in joint membership. There can "
|
||||||
"default is 0.01; specifying 0 means to preserve the original "
|
"be a significant performance (and memory utilization) runtime "
|
||||||
"values.",
|
"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);
|
&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;
|
_optimal_hierarchy = false;
|
||||||
_vref_quantum = 0.01;
|
_vref_quantum = 0.01;
|
||||||
}
|
}
|
||||||
@ -218,15 +231,18 @@ run() {
|
|||||||
do_reparent();
|
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
|
// Quantize the vertex memberships. We call this even if
|
||||||
// _vref_quantum is 0, because this also normalizes the vertex
|
// _vref_quantum is 0, because this also normalizes the vertex
|
||||||
// memberships.
|
// memberships.
|
||||||
quantize_vertices();
|
quantize_vertices();
|
||||||
|
|
||||||
// We currently do not implement optimizing morph sliders. Need
|
// Also quantize the animation channels, if the user so requested.
|
||||||
// to add this at some point; it's quite easy. Identity and empty
|
quantize_channels();
|
||||||
// morph sliders can simply be removed, while static sliders need
|
|
||||||
// to be applied to the vertices and then removed.
|
|
||||||
|
|
||||||
// Finally, flag all the groups as the user requested.
|
// Finally, flag all the groups as the user requested.
|
||||||
if (!_flag_groups.empty()) {
|
if (!_flag_groups.empty()) {
|
||||||
@ -336,6 +352,63 @@ dispatch_name_components(const string &opt, const string &arg, void *var) {
|
|||||||
return true;
|
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
|
// Function: ProgramBase::dispatch_flag_groups
|
||||||
// Access: Protected, Static
|
// Access: Protected, Static
|
||||||
@ -775,6 +848,38 @@ zero_channels() {
|
|||||||
return did_anything;
|
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
|
// Function: EggOptchar::analyze_joints
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -54,6 +54,7 @@ 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);
|
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);
|
static bool dispatch_flag_groups(const string &opt, const string &arg, void *var);
|
||||||
|
|
||||||
void determine_removed_components();
|
void determine_removed_components();
|
||||||
@ -64,6 +65,7 @@ private:
|
|||||||
|
|
||||||
bool apply_user_reparents();
|
bool apply_user_reparents();
|
||||||
bool zero_channels();
|
bool zero_channels();
|
||||||
|
bool quantize_channels();
|
||||||
void analyze_joints(EggJointData *joint_data, int level);
|
void analyze_joints(EggJointData *joint_data, int level);
|
||||||
void analyze_sliders(EggCharacterData *char_data);
|
void analyze_sliders(EggCharacterData *char_data);
|
||||||
void list_joints(EggJointData *joint_data, int indent_level, bool verbose);
|
void list_joints(EggJointData *joint_data, int indent_level, bool verbose);
|
||||||
@ -99,6 +101,14 @@ private:
|
|||||||
vector_string _drop_components;
|
vector_string _drop_components;
|
||||||
vector_string _expose_components;
|
vector_string _expose_components;
|
||||||
|
|
||||||
|
class DoubleString {
|
||||||
|
public:
|
||||||
|
double _a;
|
||||||
|
string _b;
|
||||||
|
};
|
||||||
|
typedef pvector<DoubleString> DoubleStrings;
|
||||||
|
DoubleStrings _quantize_anims;
|
||||||
|
|
||||||
typedef pvector<GlobPattern> Globs;
|
typedef pvector<GlobPattern> Globs;
|
||||||
|
|
||||||
class FlagGroupsEntry {
|
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
|
// Function: EggJointData::add_back_pointer
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -61,6 +61,7 @@ public:
|
|||||||
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);
|
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 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;
|
||||||
|
@ -125,3 +125,13 @@ expose(EggGroup::DCSType) {
|
|||||||
void EggJointPointer::
|
void EggJointPointer::
|
||||||
zero_channels(const string &) {
|
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 optimize();
|
||||||
virtual void expose(EggGroup::DCSType dcs_type);
|
virtual void expose(EggGroup::DCSType dcs_type);
|
||||||
virtual void zero_channels(const string &components);
|
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;
|
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
|
// Function: EggMatrixTablePointer::make_new_joint
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -50,6 +50,7 @@ public:
|
|||||||
|
|
||||||
virtual void optimize();
|
virtual void optimize();
|
||||||
virtual void zero_channels(const string &components);
|
virtual void zero_channels(const string &components);
|
||||||
|
virtual void quantize_channels(const string &components, double quantum);
|
||||||
|
|
||||||
virtual EggJointPointer *make_new_joint(const string &name);
|
virtual EggJointPointer *make_new_joint(const string &name);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user