mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
add fixrest
This commit is contained in:
parent
8e132cb763
commit
85636c31ca
@ -45,6 +45,7 @@ EggOptchar() {
|
||||
add_path_store_options();
|
||||
add_normals_options();
|
||||
add_transform_options();
|
||||
add_fixrest_option();
|
||||
|
||||
set_program_description
|
||||
("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.
|
||||
//
|
||||
// In addition to reporting this errors, calling this
|
||||
// function will also ensure that they are all repaired
|
||||
// (although certain kinds of errors will be repaired
|
||||
// regardless).
|
||||
// function will also ensure that they are all repaired.
|
||||
// Pass force_initial_rest_frame as true to also force
|
||||
// rest frames from different models to be the same if
|
||||
// they are initially different.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggCharacterCollection::
|
||||
check_errors(ostream &out) {
|
||||
check_errors(ostream &out, bool force_initial_rest_frame) {
|
||||
Characters::const_iterator ci;
|
||||
for (ci = _characters.begin(); ci != _characters.end(); ++ci) {
|
||||
EggCharacterData *char_data = (*ci);
|
||||
int num_joints = char_data->get_num_joints();
|
||||
for (int j = 0; j < num_joints; j++) {
|
||||
EggJointData *joint_data = char_data->get_joint(j);
|
||||
if (joint_data->_forced_rest_frames_equal) {
|
||||
out << "Warning: rest frames for " << joint_data->get_name()
|
||||
<< " were different.\n";
|
||||
if (joint_data->rest_frames_differ()) {
|
||||
if (force_initial_rest_frame) {
|
||||
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;
|
||||
|
||||
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 EggJointData *make_joint_data(EggCharacterData *char_data);
|
||||
|
@ -29,6 +29,8 @@
|
||||
EggCharacterFilter::
|
||||
EggCharacterFilter() : EggMultiFilter(false) {
|
||||
_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
|
||||
@ -70,7 +89,7 @@ post_command_line() {
|
||||
}
|
||||
}
|
||||
|
||||
_collection->check_errors(nout);
|
||||
_collection->check_errors(nout, _force_initial_rest_frame);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ public:
|
||||
EggCharacterFilter();
|
||||
virtual ~EggCharacterFilter();
|
||||
|
||||
void add_fixrest_option();
|
||||
|
||||
protected:
|
||||
virtual bool post_command_line();
|
||||
virtual void write_eggs();
|
||||
@ -49,6 +51,7 @@ protected:
|
||||
virtual EggCharacterCollection *make_collection();
|
||||
|
||||
EggCharacterCollection *_collection;
|
||||
bool _force_initial_rest_frame;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -61,6 +61,19 @@ has_rest_frame() const {
|
||||
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
|
||||
// Access: Public
|
||||
|
@ -41,7 +41,7 @@ EggJointData(EggCharacterCollection *collection,
|
||||
_parent = (EggJointData *)NULL;
|
||||
_new_parent = (EggJointData *)NULL;
|
||||
_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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
// Access: Public
|
||||
@ -185,8 +212,8 @@ optimize() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggJointData::expose
|
||||
// Access: Public
|
||||
// Description: Calls expose() on all models, and recursively on
|
||||
// all joints at this node and below.
|
||||
// Description: Calls expose() on all models for this joint, but does
|
||||
// not recurse downwards.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggJointData::
|
||||
expose(EggGroup::DCSType dcs_type) {
|
||||
@ -199,19 +226,13 @@ expose(EggGroup::DCSType 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
|
||||
// Access: Public
|
||||
// Description: Calls zero_channels() on all models, and recursively on
|
||||
// all joints at this node and below.
|
||||
// Description: Calls zero_channels() on all models for this joint,
|
||||
// but does not recurse downwards.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggJointData::
|
||||
zero_channels(const string &components) {
|
||||
@ -224,12 +245,6 @@ zero_channels(const string &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
|
||||
// of our first reading of this joint's rest frame, set a
|
||||
// warning flag.
|
||||
if (!_rest_frame.almost_equal(joint->get_frame(0), 0.001)) {
|
||||
_forced_rest_frames_equal = true;
|
||||
if (!_rest_frame.almost_equal(joint->get_frame(0), 0.0001)) {
|
||||
_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())) {
|
||||
|
@ -47,7 +47,9 @@ public:
|
||||
LMatrix4d get_net_frame(int model_index, int n) const;
|
||||
|
||||
INLINE bool has_rest_frame() const;
|
||||
INLINE bool rest_frames_differ() const;
|
||||
INLINE const LMatrix4d &get_rest_frame() const;
|
||||
void force_initial_rest_frame();
|
||||
|
||||
INLINE void reparent_to(EggJointData *new_parent);
|
||||
void move_vertices_to(EggJointData *new_owner);
|
||||
@ -72,7 +74,7 @@ private:
|
||||
LMatrix4d get_new_frame(int model_index, int n);
|
||||
|
||||
bool _has_rest_frame;
|
||||
bool _forced_rest_frames_equal;
|
||||
bool _rest_frames_differ;
|
||||
LMatrix4d _rest_frame;
|
||||
|
||||
// These are used to cache the above results for optimizing
|
||||
|
Loading…
x
Reference in New Issue
Block a user