mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
add fixrest
This commit is contained in:
parent
8e132cb763
commit
85636c31ca
@ -45,6 +45,7 @@ EggOptchar() {
|
|||||||
add_path_store_options();
|
add_path_store_options();
|
||||||
add_normals_options();
|
add_normals_options();
|
||||||
add_transform_options();
|
add_transform_options();
|
||||||
|
add_fixrest_option();
|
||||||
|
|
||||||
set_program_description
|
set_program_description
|
||||||
("egg-optchar performs basic optimizations of a character model "
|
("egg-optchar performs basic optimizations of a character model "
|
||||||
|
@ -673,21 +673,28 @@ write(ostream &out, int indent_level) const {
|
|||||||
// detected, such as inconsistent animation tables.
|
// detected, such as inconsistent animation tables.
|
||||||
//
|
//
|
||||||
// In addition to reporting this errors, calling this
|
// In addition to reporting this errors, calling this
|
||||||
// function will also ensure that they are all repaired
|
// function will also ensure that they are all repaired.
|
||||||
// (although certain kinds of errors will be repaired
|
// Pass force_initial_rest_frame as true to also force
|
||||||
// regardless).
|
// rest frames from different models to be the same if
|
||||||
|
// they are initially different.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void EggCharacterCollection::
|
void EggCharacterCollection::
|
||||||
check_errors(ostream &out) {
|
check_errors(ostream &out, bool force_initial_rest_frame) {
|
||||||
Characters::const_iterator ci;
|
Characters::const_iterator ci;
|
||||||
for (ci = _characters.begin(); ci != _characters.end(); ++ci) {
|
for (ci = _characters.begin(); ci != _characters.end(); ++ci) {
|
||||||
EggCharacterData *char_data = (*ci);
|
EggCharacterData *char_data = (*ci);
|
||||||
int num_joints = char_data->get_num_joints();
|
int num_joints = char_data->get_num_joints();
|
||||||
for (int j = 0; j < num_joints; j++) {
|
for (int j = 0; j < num_joints; j++) {
|
||||||
EggJointData *joint_data = char_data->get_joint(j);
|
EggJointData *joint_data = char_data->get_joint(j);
|
||||||
if (joint_data->_forced_rest_frames_equal) {
|
if (joint_data->rest_frames_differ()) {
|
||||||
out << "Warning: rest frames for " << joint_data->get_name()
|
if (force_initial_rest_frame) {
|
||||||
<< " were different.\n";
|
joint_data->force_initial_rest_frame();
|
||||||
|
out << "Forced rest frames the same for " << joint_data->get_name()
|
||||||
|
<< ".\n";
|
||||||
|
} else {
|
||||||
|
out << "Warning: rest frames for " << joint_data->get_name()
|
||||||
|
<< " differ.\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
INLINE EggCharacterData *get_character_by_model_index(int model_index) const;
|
INLINE EggCharacterData *get_character_by_model_index(int model_index) const;
|
||||||
|
|
||||||
virtual void write(ostream &out, int indent_level = 0) const;
|
virtual void write(ostream &out, int indent_level = 0) const;
|
||||||
void check_errors(ostream &out);
|
void check_errors(ostream &out, bool force_initial_rest_frame);
|
||||||
|
|
||||||
virtual EggCharacterData *make_character_data();
|
virtual EggCharacterData *make_character_data();
|
||||||
virtual EggJointData *make_joint_data(EggCharacterData *char_data);
|
virtual EggJointData *make_joint_data(EggCharacterData *char_data);
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
EggCharacterFilter::
|
EggCharacterFilter::
|
||||||
EggCharacterFilter() : EggMultiFilter(false) {
|
EggCharacterFilter() : EggMultiFilter(false) {
|
||||||
_collection = (EggCharacterCollection *)NULL;
|
_collection = (EggCharacterCollection *)NULL;
|
||||||
|
|
||||||
|
_force_initial_rest_frame = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -43,6 +45,23 @@ EggCharacterFilter::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggCharacterFilter::add_fixrest_option
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void EggCharacterFilter::
|
||||||
|
add_fixrest_option() {
|
||||||
|
add_option
|
||||||
|
("fixrest", "", 50,
|
||||||
|
"Specify this to force all the initial rest frames of the various "
|
||||||
|
"model files to the same value as the first model specified. This "
|
||||||
|
"is a fairly drastic way to repair models whose initial rest frame "
|
||||||
|
"values are completely bogus, but should not be performed when the "
|
||||||
|
"input models are correct.",
|
||||||
|
&EggCharacterFilter::dispatch_none, &_force_initial_rest_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggCharacterFilter::post_command_line
|
// Function: EggCharacterFilter::post_command_line
|
||||||
@ -70,7 +89,7 @@ post_command_line() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_collection->check_errors(nout);
|
_collection->check_errors(nout, _force_initial_rest_frame);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,8 @@ public:
|
|||||||
EggCharacterFilter();
|
EggCharacterFilter();
|
||||||
virtual ~EggCharacterFilter();
|
virtual ~EggCharacterFilter();
|
||||||
|
|
||||||
|
void add_fixrest_option();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool post_command_line();
|
virtual bool post_command_line();
|
||||||
virtual void write_eggs();
|
virtual void write_eggs();
|
||||||
@ -49,6 +51,7 @@ protected:
|
|||||||
virtual EggCharacterCollection *make_collection();
|
virtual EggCharacterCollection *make_collection();
|
||||||
|
|
||||||
EggCharacterCollection *_collection;
|
EggCharacterCollection *_collection;
|
||||||
|
bool _force_initial_rest_frame;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -61,6 +61,19 @@ has_rest_frame() const {
|
|||||||
return _has_rest_frame;
|
return _has_rest_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggJointData::rest_frames_differ
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns true if the rest frames for different models
|
||||||
|
// differ in their initial value. This is not
|
||||||
|
// technically an error, but it is unusual enough to be
|
||||||
|
// suspicious.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool EggJointData::
|
||||||
|
rest_frames_differ() const {
|
||||||
|
return _rest_frames_differ;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggJointData::get_rest_frame
|
// Function: EggJointData::get_rest_frame
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -41,7 +41,7 @@ EggJointData(EggCharacterCollection *collection,
|
|||||||
_parent = (EggJointData *)NULL;
|
_parent = (EggJointData *)NULL;
|
||||||
_new_parent = (EggJointData *)NULL;
|
_new_parent = (EggJointData *)NULL;
|
||||||
_has_rest_frame = false;
|
_has_rest_frame = false;
|
||||||
_forced_rest_frames_equal = false;
|
_rest_frames_differ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -103,6 +103,33 @@ get_net_frame(int model_index, int n) const {
|
|||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggJointData::force_initial_rest_frame
|
||||||
|
// Access: Public
|
||||||
|
// Description: Forces all of the joints to have the same rest frame
|
||||||
|
// value as the first joint read in. This is a drastic
|
||||||
|
// way to repair models whose rest frame values are
|
||||||
|
// completely bogus, but should not be performed on
|
||||||
|
// models that are otherwise correct.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void EggJointData::
|
||||||
|
force_initial_rest_frame() {
|
||||||
|
if (!has_rest_frame()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int num_models = get_num_models();
|
||||||
|
for (int model_index = 0; model_index < num_models; model_index++) {
|
||||||
|
if (has_model(model_index)) {
|
||||||
|
EggJointPointer *joint;
|
||||||
|
DCAST_INTO_V(joint, get_model(model_index));
|
||||||
|
if (joint->is_of_type(EggJointNodePointer::get_class_type())) {
|
||||||
|
joint->set_frame(0, get_rest_frame());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_rest_frames_differ = false;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggJointData::move_vertices_to
|
// Function: EggJointData::move_vertices_to
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -185,8 +212,8 @@ optimize() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggJointData::expose
|
// Function: EggJointData::expose
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: Calls expose() on all models, and recursively on
|
// Description: Calls expose() on all models for this joint, but does
|
||||||
// all joints at this node and below.
|
// not recurse downwards.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void EggJointData::
|
void EggJointData::
|
||||||
expose(EggGroup::DCSType dcs_type) {
|
expose(EggGroup::DCSType dcs_type) {
|
||||||
@ -199,19 +226,13 @@ expose(EggGroup::DCSType dcs_type) {
|
|||||||
joint->expose(dcs_type);
|
joint->expose(dcs_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Children::iterator ci;
|
|
||||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
|
||||||
EggJointData *child = (*ci);
|
|
||||||
child->expose(dcs_type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggJointData::zero_channels
|
// Function: EggJointData::zero_channels
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: Calls zero_channels() on all models, and recursively on
|
// Description: Calls zero_channels() on all models for this joint,
|
||||||
// all joints at this node and below.
|
// but does not recurse downwards.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void EggJointData::
|
void EggJointData::
|
||||||
zero_channels(const string &components) {
|
zero_channels(const string &components) {
|
||||||
@ -224,12 +245,6 @@ zero_channels(const string &components) {
|
|||||||
joint->zero_channels(components);
|
joint->zero_channels(components);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Children::iterator ci;
|
|
||||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
|
||||||
EggJointData *child = (*ci);
|
|
||||||
child->zero_channels(components);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -253,21 +268,9 @@ add_back_pointer(int model_index, EggObject *egg_object) {
|
|||||||
// If this new node doesn't come within an acceptable tolerance
|
// If this new node doesn't come within an acceptable tolerance
|
||||||
// of our first reading of this joint's rest frame, set a
|
// of our first reading of this joint's rest frame, set a
|
||||||
// warning flag.
|
// warning flag.
|
||||||
if (!_rest_frame.almost_equal(joint->get_frame(0), 0.001)) {
|
if (!_rest_frame.almost_equal(joint->get_frame(0), 0.0001)) {
|
||||||
_forced_rest_frames_equal = true;
|
_rest_frames_differ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In any case, ensure the rest frames are exactly equal.
|
|
||||||
|
|
||||||
// Actually, this may not be a good idea; it is, in fact, valid
|
|
||||||
// (although unusual) for different models to have different
|
|
||||||
// rest frames, provided their vertices appriopriately reflect
|
|
||||||
// the different rest frames. But we do have at least one
|
|
||||||
// character, Mickey, for which some of the lower-level LOD's
|
|
||||||
// have different rest frames that are in fact completely wrong,
|
|
||||||
// so forcing them all to the same value is correct in that
|
|
||||||
// case. Maybe this should be a command-line option.
|
|
||||||
joint->set_frame(0, _rest_frame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (egg_object->is_of_type(EggTable::get_class_type())) {
|
} else if (egg_object->is_of_type(EggTable::get_class_type())) {
|
||||||
|
@ -47,7 +47,9 @@ public:
|
|||||||
LMatrix4d get_net_frame(int model_index, int n) const;
|
LMatrix4d get_net_frame(int model_index, int n) const;
|
||||||
|
|
||||||
INLINE bool has_rest_frame() const;
|
INLINE bool has_rest_frame() const;
|
||||||
|
INLINE bool rest_frames_differ() const;
|
||||||
INLINE const LMatrix4d &get_rest_frame() const;
|
INLINE const LMatrix4d &get_rest_frame() const;
|
||||||
|
void force_initial_rest_frame();
|
||||||
|
|
||||||
INLINE void reparent_to(EggJointData *new_parent);
|
INLINE void reparent_to(EggJointData *new_parent);
|
||||||
void move_vertices_to(EggJointData *new_owner);
|
void move_vertices_to(EggJointData *new_owner);
|
||||||
@ -72,7 +74,7 @@ private:
|
|||||||
LMatrix4d get_new_frame(int model_index, int n);
|
LMatrix4d get_new_frame(int model_index, int n);
|
||||||
|
|
||||||
bool _has_rest_frame;
|
bool _has_rest_frame;
|
||||||
bool _forced_rest_frames_equal;
|
bool _rest_frames_differ;
|
||||||
LMatrix4d _rest_frame;
|
LMatrix4d _rest_frame;
|
||||||
|
|
||||||
// These are used to cache the above results for optimizing
|
// These are used to cache the above results for optimizing
|
||||||
|
Loading…
x
Reference in New Issue
Block a user