15 #include "xFileToEggConverter.h" 16 #include "xFileMesh.h" 17 #include "xFileMaterial.h" 18 #include "xFileAnimationSet.h" 19 #include "config_xfile.h" 23 #include "eggXfmSAnim.h" 24 #include "eggGroupUniquifier.h" 26 #include "eggMaterialCollection.h" 27 #include "eggTextureCollection.h" 36 XFileToEggConverter() {
39 _x_file =
new XFile(
true);
51 _make_char(copy._make_char)
53 _x_file =
new XFile(
true);
63 ~XFileToEggConverter() {
129 if (!_x_file->read(filename)) {
130 nout <<
"Unable to open X file: " << filename <<
"\n";
134 if (_char_name.empty()) {
138 if (_egg_data->get_coordinate_system() == CS_default) {
139 _egg_data->set_coordinate_system(CS_yup_left);
142 if (!get_toplevel()) {
146 if (!create_polygons()) {
156 if (!create_hierarchy()) {
160 if (_keep_model && !_keep_animation) {
164 if (_keep_animation && !_keep_model) {
182 Meshes::const_iterator mi;
183 for (mi = _meshes.begin(); mi != _meshes.end(); ++mi) {
188 AnimationSets::const_iterator asi;
189 for (asi = _animation_sets.begin(); asi != _animation_sets.end(); ++asi) {
192 _animation_sets.clear();
206 EggGroupNode::iterator i;
207 for (i=_egg_data->begin(); i!=_egg_data->end(); ++i) {
210 garbage.push_back(node);
213 for (
int n=0; n<(int)garbage.size(); n++) {
214 _egg_data->remove_child(garbage[n]);
264 ji = _joints.find(joint_name);
265 if (ji != _joints.end()) {
280 <<
"Joint name " << joint_name <<
" in animation data is undefined.\n";
282 _joints[joint_name] = NULL;
294 bool XFileToEggConverter::
296 int num_objects = _x_file->get_num_objects();
299 _ticks_per_second = 4800;
304 _any_animation =
false;
305 for (i = 0; i < num_objects; i++) {
310 _any_animation =
true;
315 if (_any_animation) {
324 _dart_node =
new EggGroup(_char_name);
326 _dart_node->set_dart_type(EggGroup::DT_default);
327 egg_parent = _dart_node;
331 for (i = 0; i < num_objects; i++) {
332 if (!convert_toplevel_object(_x_file->get_object(i), egg_parent)) {
346 bool XFileToEggConverter::
356 if (!convert_frame(obj, egg_parent)) {
361 if (!convert_animation_set(obj)) {
366 _ticks_per_second = (*obj)[0].i();
375 if (!convert_mesh(obj, egg_parent)) {
381 if (xfile_cat.is_debug()) {
383 <<
"Ignoring toplevel object of unknown type: " 397 bool XFileToEggConverter::
403 if (!convert_frame(obj, egg_parent)) {
408 if (!convert_transform(obj, egg_parent)) {
413 if (!convert_mesh(obj, egg_parent)) {
418 if (xfile_cat.is_debug()) {
420 <<
"Ignoring object of unknown type: " 434 bool XFileToEggConverter::
437 string name = obj->get_name();
442 group->set_group_type(EggGroup::GT_joint);
445 group->set_name(
"unnamed");
448 bool inserted = _joints.insert(Joints::value_type(name, group)).second;
451 <<
"Nonunique Frame name " << name
452 <<
" encountered; animation will be ambiguous.\n";
459 for (
int i = 0; i < num_objects; i++) {
460 if (!convert_object(obj->
get_object(i), group)) {
477 bool XFileToEggConverter::
479 LMatrix4d mat = (*obj)[
"frameMatrix"][
"matrix"].mat4();
481 if (egg_parent->
is_of_type(EggGroup::get_class_type())) {
487 <<
"Transform " << obj->get_name()
488 <<
" encountered without frame!\n";
501 bool XFileToEggConverter::
504 animation_set->set_name(obj->get_name());
506 _total_tick_deltas = 0;
512 for (
int i = 0; i < num_objects; i++) {
513 if (!convert_animation_set_object(obj->
get_object(i), *animation_set)) {
518 animation_set->_frame_rate = _frame_rate;
519 if (_num_ticks != 0 && _frame_rate == 0.0) {
521 double delta = (double)_total_tick_deltas / (
double)_num_ticks;
523 animation_set->_frame_rate = (double)_ticks_per_second / delta;
527 _animation_sets.push_back(animation_set);
538 bool XFileToEggConverter::
542 if (!convert_animation(obj, animation_set)) {
547 if (xfile_cat.is_debug()) {
549 <<
"Ignoring animation set object of unknown type: " 562 bool XFileToEggConverter::
572 bool got_frame_name =
false;
576 for (i = 0; i < num_objects; i++) {
579 frame_name = child->get_name();
580 got_frame_name =
true;
584 if (!got_frame_name) {
586 <<
"Animation " << obj->get_name()
587 <<
" includes no reference to a frame.\n";
594 for (i = 0; i < num_objects; i++) {
595 if (!convert_animation_object(obj->
get_object(i), frame_name, table)) {
609 bool XFileToEggConverter::
610 convert_animation_object(
XFileDataNode *obj,
const string &joint_name,
619 if (!convert_animation_key(obj, joint_name, table)) {
624 if (xfile_cat.is_debug()) {
626 <<
"Ignoring animation object of unknown type: " 639 bool XFileToEggConverter::
640 convert_animation_key(
XFileDataNode *obj,
const string &joint_name,
642 int key_type = (*obj)[
"keyType"].i();
647 for (
int i = 0; i < keys.
size(); i++) {
655 int this_time = keys[i][
"time"].
i();
657 int delta = this_time - last_time;
658 _total_tick_deltas += delta;
661 last_time = this_time;
664 if (!set_animation_frame(joint_name, table, i, key_type, values)) {
677 bool XFileToEggConverter::
678 set_animation_frame(
const string &joint_name,
681 if ((
int)table._entries.size() <= frame) {
682 nassertr((
int)table._entries.size() == frame,
false);
694 if (values.
size() != 4) {
696 <<
"Incorrect number of values in animation table: " 697 << values.
size() <<
" for rotation data.\n";
701 table._flags |= XFileAnimationSet::FDF_rot;
705 if (values.
size() != 3) {
707 <<
"Incorrect number of values in animation table: " 708 << values.
size() <<
" for scale data.\n";
711 frame_entry._scale = values.
vec3();
712 table._flags |= XFileAnimationSet::FDF_scale;
717 if (values.
size() != 3) {
719 <<
"Incorrect number of values in animation table: " 720 << values.
size() <<
" for position data.\n";
723 frame_entry._trans = values.
vec3();
724 table._flags |= XFileAnimationSet::FDF_trans;
735 if (values.
size() != 16) {
737 <<
"Incorrect number of values in animation table: " 738 << values.
size() <<
" for matrix data.\n";
741 frame_entry._mat = values.
mat4();
742 table._flags |= XFileAnimationSet::FDF_mat;
747 <<
"Unsupported key type " << key_type <<
" in animation table.\n";
760 bool XFileToEggConverter::
763 mesh->set_name(obj->get_name());
771 _meshes.push_back(mesh);
782 bool XFileToEggConverter::
786 Meshes::const_iterator mi;
787 for (mi = _meshes.begin(); mi != _meshes.end(); ++mi) {
788 if (!(*mi)->create_polygons(
this)) {
804 bool XFileToEggConverter::
808 AnimationSets::const_iterator asi;
809 for (asi = _animation_sets.begin(); asi != _animation_sets.end(); ++asi) {
811 if (!(*asi)->create_hierarchy(
this)) {
817 _animation_sets.clear();
EggGroup * get_dart_node() const
Returns the root of the joint hierarchy, if _make_char is true, or NULL otherwise.
EggGroup * find_joint(const string &joint_name)
This is called by set_animation_frame, for the purposes of building the frame data for the animationâ€...
bool fill_mesh(XFileDataNode *obj)
Fills the structure based on the raw data from the X file's Mesh object.
EggTexture * create_unique_texture(const EggTexture ©, int eq)
Creates a new texture if there is not already one equivalent (according to eq, see EggTexture::is_equ...
This is a 4-by-4 transform matrix.
void close()
Finalizes and closes the file previously opened via convert_file().
FrameData & create_frame_data(const string &joint_name)
Returns a reference to a new FrameData table corresponding to the indicated joint.
bool had_error() const
Returns true if an error was detected during the conversion process (unless _allow_errors is true)...
This is a collection of polygons; i.e.
virtual bool supports_compressed() const
Returns true if this file type can transparently load compressed files (with a .pz extension)...
A base class for nodes in the hierarchy that are not leaf nodes.
int i() const
Unambiguously returns the object's representation as an integer, or 0 if the object has no integer re...
This is the base quaternion class.
Defines a texture map that may be applied to geometry.
This is a specialization of EggNameUniquifier to generate unique names for EggGroup nodes...
virtual string get_name() const
Returns the English name of the file type this converter supports.
This represents a tree of EggTables, corresponding to Animation entries in the X file.
EggMaterial * create_unique_material(const EggMaterial ©)
Returns an EggMaterial pointer whose properties match that of the the given EggMaterial, except for the mref name.
int get_num_objects() const
Returns the list of child objects of this node.
const string & get_template_name() const
A convenience function to return the name of the template used to define this data object...
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
void clear_error()
Resets the error flag to the no-error state.
void strip_nodes(TypeHandle t)
Removes all groups of the given type.
virtual bool convert_file(const Filename &filename)
Handles the reading of the input file and converting it to egg.
The name of a file, such as a texture file or an Egg file.
void set_egg_parent(EggGroupNode *egg_parent)
Specifies the egg node that will eventually be the parent of this mesh, when create_polygons() is lat...
virtual string get_extension() const
Returns the common extension of the file type this converter supports.
LVecBase4d vec4() const
Returns the object's representation as an LVecBase4d.
void uniquify(EggNode *node)
Begins the traversal from the indicated node.
virtual bool is_reference() const
Returns true if this node represents an indirect reference to an object defined previously in the fil...
string get_basename_wo_extension() const
Returns the basename part of the filename, without the file extension.
int size() const
Returns the number of nested data objects within this object.
bool invert_from(const LQuaterniond &other)
Computes the inverse of the other quat, and stores the result in this quat.
virtual bool is_standard_object(const string &template_name) const
Returns true if this node represents an instance of the standard template with the indicated name...
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
LMatrix4d mat4() const
Returns the object's representation as an LMatrix4d.
A base class for things that may be directly added into the egg hierarchy.
This is an abstract base class for an XFileNode which is also an XFileDataObject. ...
EggMaterial * create_unique_material(const EggMaterial ©, int eq)
Creates a new material if there is not already one equivalent (according to eq, see EggMaterial::is_e...
This represents the complete contents of an X file (file.x) in memory.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
EggTexture * create_unique_texture(const EggTexture ©)
Returns an EggTexture pointer whose properties match that of the the given EggTexture, except for the tref name.
XFileDataNode * get_object(int n) const
Returns the nth child object of this node.
TypeHandle is the identifier used to differentiate C++ class types.
LVecBase3d vec3() const
Returns the object's representation as an LVecBase3d.
This is a base class for a family of converter classes that manage a conversion from some file type t...
The abstract base class for a number of different types of data elements that may be stored in the X ...
virtual SomethingToEggConverter * make_copy()
Allocates and returns a new copy of the converter.