From fc74bc81f0ff72a9977ef2257a0a527c684b2377 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 13 Oct 2004 21:39:35 +0000 Subject: [PATCH] x2egg now uses native parser --- pandatool/src/progbase/withOutputFile.cxx | 5 +- pandatool/src/ptloader/Sources.pp | 5 - pandatool/src/ptloader/config_ptloader.cxx | 5 - pandatool/src/xfile/Sources.pp | 14 - pandatool/src/xfile/xFileDataDef.cxx | 11 +- pandatool/src/xfile/xFileDataNode.I | 12 + pandatool/src/xfile/xFileDataNode.cxx | 47 + pandatool/src/xfile/xFileDataNode.h | 5 + .../src/xfile/xFileDataNodeReference.cxx | 36 +- pandatool/src/xfile/xFileDataNodeReference.h | 5 +- pandatool/src/xfile/xFileDataNodeTemplate.cxx | 18 - pandatool/src/xfile/xFileDataNodeTemplate.h | 2 - pandatool/src/xfile/xFileDataObject.I | 202 ++- pandatool/src/xfile/xFileDataObject.cxx | 78 +- pandatool/src/xfile/xFileDataObject.h | 19 + pandatool/src/xfile/xFileNode.I | 33 +- pandatool/src/xfile/xFileNode.cxx | 78 +- pandatool/src/xfile/xFileNode.h | 12 + pandatool/src/xfile/xFileTemplate.cxx | 18 + pandatool/src/xfile/xFileTemplate.h | 2 + pandatool/src/xfile/xParser.cxx.prebuilt | 102 +- pandatool/src/xfile/xParser.yxx | 2 +- pandatool/src/xfileegg/Sources.pp | 14 +- pandatool/src/xfileegg/xFileAnimationSet.cxx | 1 - pandatool/src/xfileegg/xFileMaker.cxx | 56 +- pandatool/src/xfileegg/xFileMaterial.cxx | 70 +- pandatool/src/xfileegg/xFileMaterial.h | 5 +- pandatool/src/xfileegg/xFileMesh.cxx | 277 +++-- pandatool/src/xfileegg/xFileMesh.h | 16 +- pandatool/src/xfileegg/xFileNormal.cxx | 2 +- pandatool/src/xfileegg/xFileNormal.h | 2 +- pandatool/src/xfileegg/xFileTemplates.cxx | 34 - pandatool/src/xfileegg/xFileTemplates.h | 54 - .../src/xfileegg/xFileToEggConverter.cxx | 1097 ++--------------- pandatool/src/xfileegg/xFileToEggConverter.h | 78 +- pandatool/src/xfileegg/xFileVertex.cxx | 4 +- pandatool/src/xfileegg/xFileVertex.h | 4 +- .../src/xfileegg/xfileegg_composite1.cxx | 1 - pandatool/src/xfileprogs/Sources.pp | 27 +- .../src/{xfile => xfileprogs}/xFileTrans.cxx | 3 +- .../src/{xfile => xfileprogs}/xFileTrans.h | 0 41 files changed, 933 insertions(+), 1523 deletions(-) delete mode 100644 pandatool/src/xfileegg/xFileTemplates.cxx delete mode 100644 pandatool/src/xfileegg/xFileTemplates.h rename pandatool/src/{xfile => xfileprogs}/xFileTrans.cxx (97%) rename pandatool/src/{xfile => xfileprogs}/xFileTrans.h (100%) diff --git a/pandatool/src/progbase/withOutputFile.cxx b/pandatool/src/progbase/withOutputFile.cxx index c1d6e9e50a..26d04525d5 100644 --- a/pandatool/src/progbase/withOutputFile.cxx +++ b/pandatool/src/progbase/withOutputFile.cxx @@ -57,7 +57,10 @@ get_output() { if (_output_ptr == (ostream *)NULL) { if (!_got_output_filename) { // No filename given; use standard output. - nassertr(_allow_stdout, _output_stream); + if (!_allow_stdout) { + nout << "No output filename specified.\n"; + exit(1); + } _output_ptr = &cout; } else { diff --git a/pandatool/src/ptloader/Sources.pp b/pandatool/src/ptloader/Sources.pp index f56817d6a4..c4fbb53bd2 100644 --- a/pandatool/src/ptloader/Sources.pp +++ b/pandatool/src/ptloader/Sources.pp @@ -1,5 +1,3 @@ -#define USE_PACKAGES dx - #begin lib_target #define TARGET ptloader #define BUILDING_DLL BUILDING_PTLOADER @@ -20,9 +18,6 @@ #define UNIX_SYS_LIBS \ m - #define WIN_SYS_LIBS \ - d3dxof.lib dxguid.lib d3d8.lib d3dx8.lib dxerr8.lib - #define SOURCES \ config_ptloader.cxx config_ptloader.h \ loaderFileTypePandatool.cxx loaderFileTypePandatool.h diff --git a/pandatool/src/ptloader/config_ptloader.cxx b/pandatool/src/ptloader/config_ptloader.cxx index 5f6879e99c..7144562a98 100644 --- a/pandatool/src/ptloader/config_ptloader.cxx +++ b/pandatool/src/ptloader/config_ptloader.cxx @@ -25,11 +25,8 @@ #include "lwoToEggConverter.h" #include "dxfToEggConverter.h" #include "vrmlToEggConverter.h" - -#ifdef HAVE_DX #include "config_xfile.h" #include "xFileToEggConverter.h" -#endif #include "dconfig.h" #include "loaderFileTypeRegistry.h" @@ -87,11 +84,9 @@ init_libptloader() { VRMLToEggConverter *vrml = new VRMLToEggConverter; reg->register_type(new LoaderFileTypePandatool(vrml)); -#ifdef HAVE_DX init_libxfile(); XFileToEggConverter *xfile = new XFileToEggConverter; reg->register_type(new LoaderFileTypePandatool(xfile)); -#endif #ifdef HAVE_MAYA // Register the Maya converter as a deferred type. We don't compile diff --git a/pandatool/src/xfile/Sources.pp b/pandatool/src/xfile/Sources.pp index 361b529074..2df1dadb77 100644 --- a/pandatool/src/xfile/Sources.pp +++ b/pandatool/src/xfile/Sources.pp @@ -32,17 +32,3 @@ xFileTemplate.cxx xFileTemplate.I xFileTemplate.h #end ss_lib_target - -#begin test_bin_target - #define TARGET x-trans - #define LOCAL_LIBS \ - progbase xfile - #define OTHER_LIBS \ - linmath:c panda:m \ - express:c pandaexpress:m \ - dtoolutil:c dtoolbase:c dconfig:c dtoolconfig:m dtool:m pystub - - #define SOURCES \ - xFileTrans.cxx xFileTrans.h - -#end test_bin_target diff --git a/pandatool/src/xfile/xFileDataDef.cxx b/pandatool/src/xfile/xFileDataDef.cxx index df07b79a84..91aa990a74 100644 --- a/pandatool/src/xfile/xFileDataDef.cxx +++ b/pandatool/src/xfile/xFileDataDef.cxx @@ -155,11 +155,6 @@ repack_data(XFileDataObject *object, const XFileParseDataList &parse_data_list, XFileDataDef::PrevData &prev_data, size_t &index, size_t &sub_index) const { - if (index >= parse_data_list._list.size()) { - xyyerror("Not enough data elements in structure."); - return false; - } - // We'll fill this in with the data value we pack, if any. PT(XFileDataObject) data_value; @@ -434,6 +429,10 @@ unpack_value(const XFileParseDataList &parse_data_list, int array_index, PT(XFileDataObject) data_value; if (array_index == (int)_array_def.size()) { + if (index >= parse_data_list._list.size()) { + xyyerror("Not enough data elements in structure at " + get_name()); + return NULL; + } data_value = (this->*unpack_method)(parse_data_list, prev_data, index, sub_index); @@ -453,7 +452,7 @@ unpack_value(const XFileParseDataList &parse_data_list, int array_index, prev_data, index, sub_index, unpack_method); if (array_element == (XFileDataObject *)NULL) { - return NULL; + return data_value; } data_value->add_element(array_element); } diff --git a/pandatool/src/xfile/xFileDataNode.I b/pandatool/src/xfile/xFileDataNode.I index 64775198a0..b32cadb941 100644 --- a/pandatool/src/xfile/xFileDataNode.I +++ b/pandatool/src/xfile/xFileDataNode.I @@ -46,3 +46,15 @@ INLINE XFileTemplate *XFileDataNode:: get_template() const { return _template; } + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataNode::get_template_name +// Access: Public +// Description: A convenience function to return the name of the +// template used to define this data object. +//////////////////////////////////////////////////////////////////// +INLINE const string &XFileDataNode:: +get_template_name() const { + return _template->get_name(); +} + diff --git a/pandatool/src/xfile/xFileDataNode.cxx b/pandatool/src/xfile/xFileDataNode.cxx index 89a81e5cff..28d80f7f4e 100644 --- a/pandatool/src/xfile/xFileDataNode.cxx +++ b/pandatool/src/xfile/xFileDataNode.cxx @@ -33,3 +33,50 @@ XFileDataNode(XFile *x_file, const string &name, _template(xtemplate) { } + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataNode::is_object +// Access: Public, Virtual +// Description: Returns true if this node represents a data object +// that is the instance of some template, or false +// otherwise. This also returns true for references to +// objects (which are generally treated just like the +// objects themselves). +// +// If this returns true, the node must be of type +// XFileDataNode (it is either an XFileDataNodeTemplate +// or an XFileDataNodeReference). +//////////////////////////////////////////////////////////////////// +bool XFileDataNode:: +is_object() const { + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataNode::is_standard_object +// Access: Public, Virtual +// Description: Returns true if this node represents an instance of +// the standard template with the indicated name, or +// false otherwise. If this returns true, the object +// must be of type XFileDataNode. +//////////////////////////////////////////////////////////////////// +bool XFileDataNode:: +is_standard_object(const string &template_name) const { + if (_template->is_standard() && + _template->get_name() == template_name) { + return true; + } + + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataNode::get_type_name +// Access: Public, Virtual +// Description: Returns a string that represents the type of object +// this data object represents. +//////////////////////////////////////////////////////////////////// +string XFileDataNode:: +get_type_name() const { + return _template->get_name(); +} diff --git a/pandatool/src/xfile/xFileDataNode.h b/pandatool/src/xfile/xFileDataNode.h index dcb936f464..b6b5796c93 100644 --- a/pandatool/src/xfile/xFileDataNode.h +++ b/pandatool/src/xfile/xFileDataNode.h @@ -42,9 +42,14 @@ public: XFileDataNode(XFile *x_file, const string &name, XFileTemplate *xtemplate); + virtual bool is_object() const; + virtual bool is_standard_object(const string &template_name) const; + virtual string get_type_name() const; + INLINE const XFileDataNode &get_data_child(int n) const; INLINE XFileTemplate *get_template() const; + INLINE const string &get_template_name() const; protected: PT(XFileTemplate) _template; diff --git a/pandatool/src/xfile/xFileDataNodeReference.cxx b/pandatool/src/xfile/xFileDataNodeReference.cxx index 45e6e499f9..162ba26b6b 100644 --- a/pandatool/src/xfile/xFileDataNodeReference.cxx +++ b/pandatool/src/xfile/xFileDataNodeReference.cxx @@ -32,6 +32,34 @@ XFileDataNodeReference(XFileDataNodeTemplate *object) : object->get_template()), _object(object) { + // We steal a copy of the referenced object's children. This is + // just a one-time copy, so if you go and change the list of + // children of the referenced object, it won't be reflected here in + // the reference. Since presumably the reference is only used when + // parsing static files, that shouldn't be a problem; but you do + // need to be aware of it. + _children = object->_children; + _objects = object->_objects; + _children_by_name = object->_children_by_name; +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataNodeReference::is_reference +// Access: Public, Virtual +// Description: Returns true if this node represents an indirect +// reference to an object defined previously in the +// file. References are generally transparent, so in +// most cases you never need to call this, unless you +// actually need to differentiate between references and +// instances; you can simply use the reference node as +// if it were itself the object it references. +// +// If this returns true, the node must be of type +// XFileDataNodeReference. +//////////////////////////////////////////////////////////////////// +bool XFileDataNodeReference:: +is_reference() const { + return true; } //////////////////////////////////////////////////////////////////// @@ -76,8 +104,8 @@ get_num_elements() const { // Description: Returns the nth nested data element within the // object. //////////////////////////////////////////////////////////////////// -const XFileDataObject *XFileDataNodeReference:: -get_element(int n) const { +XFileDataObject *XFileDataNodeReference:: +get_element(int n) { return &((*_object)[n]); } @@ -87,7 +115,7 @@ get_element(int n) const { // Description: Returns the nested data element within the // object that has the indicated name. //////////////////////////////////////////////////////////////////// -const XFileDataObject *XFileDataNodeReference:: -get_element(const string &name) const { +XFileDataObject *XFileDataNodeReference:: +get_element(const string &name) { return &((*_object)[name]); } diff --git a/pandatool/src/xfile/xFileDataNodeReference.h b/pandatool/src/xfile/xFileDataNodeReference.h index 67d9272e90..34020e9676 100644 --- a/pandatool/src/xfile/xFileDataNodeReference.h +++ b/pandatool/src/xfile/xFileDataNodeReference.h @@ -39,14 +39,15 @@ public: INLINE XFileTemplate *get_template() const; INLINE XFileDataNodeTemplate *get_object() const; + virtual bool is_reference() const; virtual bool is_complex_object() const; virtual void write_text(ostream &out, int indent_level) const; protected: virtual int get_num_elements() const; - virtual const XFileDataObject *get_element(int n) const; - virtual const XFileDataObject *get_element(const string &name) const; + virtual XFileDataObject *get_element(int n); + virtual XFileDataObject *get_element(const string &name); private: PT(XFileDataNodeTemplate) _object; diff --git a/pandatool/src/xfile/xFileDataNodeTemplate.cxx b/pandatool/src/xfile/xFileDataNodeTemplate.cxx index f8673d7313..a19221d0ac 100644 --- a/pandatool/src/xfile/xFileDataNodeTemplate.cxx +++ b/pandatool/src/xfile/xFileDataNodeTemplate.cxx @@ -36,24 +36,6 @@ XFileDataNodeTemplate(XFile *x_file, const string &name, { } -//////////////////////////////////////////////////////////////////// -// Function: XFileDataNodeTemplate::is_standard_object -// Access: Public, Virtual -// Description: Returns true if this node represents an instance of -// the standard template with the indicated name, or -// false otherwise. If this returns true, the object -// must be of type XFileDataNodeTemplate. -//////////////////////////////////////////////////////////////////// -bool XFileDataNodeTemplate:: -is_standard_object(const string &template_name) const { - if (_template->is_standard() && - _template->get_name() == template_name) { - return true; - } - - return false; -} - //////////////////////////////////////////////////////////////////// // Function: XFileDataNodeTemplate::zero_fill // Access: Public diff --git a/pandatool/src/xfile/xFileDataNodeTemplate.h b/pandatool/src/xfile/xFileDataNodeTemplate.h index b4827ec700..2791d9e614 100644 --- a/pandatool/src/xfile/xFileDataNodeTemplate.h +++ b/pandatool/src/xfile/xFileDataNodeTemplate.h @@ -40,8 +40,6 @@ public: XFileDataNodeTemplate(XFile *x_file, const string &name, XFileTemplate *xtemplate); - virtual bool is_standard_object(const string &template_name) const; - void zero_fill(); virtual bool is_complex_object() const; diff --git a/pandatool/src/xfile/xFileDataObject.I b/pandatool/src/xfile/xFileDataObject.I index 6a4346ab0a..4a5ec20dca 100644 --- a/pandatool/src/xfile/xFileDataObject.I +++ b/pandatool/src/xfile/xFileDataObject.I @@ -48,7 +48,7 @@ get_data_def() const { //////////////////////////////////////////////////////////////////// INLINE void XFileDataObject:: operator = (int int_value) { - set_int_value(int_value); + set(int_value); } //////////////////////////////////////////////////////////////////// @@ -61,7 +61,7 @@ operator = (int int_value) { //////////////////////////////////////////////////////////////////// INLINE void XFileDataObject:: operator = (double double_value) { - set_double_value(double_value); + set(double_value); } //////////////////////////////////////////////////////////////////// @@ -74,9 +74,151 @@ operator = (double double_value) { //////////////////////////////////////////////////////////////////// INLINE void XFileDataObject:: operator = (const string &string_value) { + set(string_value); +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::operator = (vec2) +// Access: Public +// Description: Stores the indicated Vec2 value into the object, +// if it makes sense to do so. It is an error to call +// this on an object that does not store two +// floating-point values. +//////////////////////////////////////////////////////////////////// +INLINE void XFileDataObject:: +operator = (const LVecBase2d &vec) { + set(vec); +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::operator = (vec3) +// Access: Public +// Description: Stores the indicated Vec3 value into the object, +// if it makes sense to do so. It is an error to call +// this on an object that does not store three +// floating-point values. +//////////////////////////////////////////////////////////////////// +INLINE void XFileDataObject:: +operator = (const LVecBase3d &vec) { + set(vec); +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::operator = (vec4) +// Access: Public +// Description: Stores the indicated Vec4 value into the object, +// if it makes sense to do so. It is an error to call +// this on an object that does not store four +// floating-point values. +//////////////////////////////////////////////////////////////////// +INLINE void XFileDataObject:: +operator = (const LVecBase4d &vec) { + set(vec); +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::operator = (mat) +// Access: Public +// Description: Stores the indicated Matrix value into the object, +// if it makes sense to do so. It is an error to call +// this on an object that does not store sixteen +// floating-point values. +//////////////////////////////////////////////////////////////////// +INLINE void XFileDataObject:: +operator = (const LMatrix4d &mat) { + set(mat); +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::set(int) +// Access: Public +// Description: Stores the indicated integer value into the object, +// if it makes sense to do so. It is an error to call +// this on an object that cannot accept an integer value. +//////////////////////////////////////////////////////////////////// +INLINE void XFileDataObject:: +set(int int_value) { + set_int_value(int_value); +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::set(double) +// Access: Public +// Description: Stores the indicated floating-point value into the +// object, if it makes sense to do so. It is an error +// to call this on an object that cannot accept a +// floating-point value. +//////////////////////////////////////////////////////////////////// +INLINE void XFileDataObject:: +set(double double_value) { + set_double_value(double_value); +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::set(string) +// Access: Public +// Description: Stores the indicated string value into the +// object, if it makes sense to do so. It is an error +// to call this on an object that cannot accept a +// string value. +//////////////////////////////////////////////////////////////////// +INLINE void XFileDataObject:: +set(const string &string_value) { set_string_value(string_value); } +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::set(vec2) +// Access: Public +// Description: Stores the indicated Vec2 value into the object, +// if it makes sense to do so. It is an error to call +// this on an object that does not store two +// floating-point values. +//////////////////////////////////////////////////////////////////// +INLINE void XFileDataObject:: +set(const LVecBase2d &vec) { + store_double_array(2, vec.get_data()); +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::set(vec3) +// Access: Public +// Description: Stores the indicated Vec3 value into the object, +// if it makes sense to do so. It is an error to call +// this on an object that does not store three +// floating-point values. +//////////////////////////////////////////////////////////////////// +INLINE void XFileDataObject:: +set(const LVecBase3d &vec) { + store_double_array(3, vec.get_data()); +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::set(vec4) +// Access: Public +// Description: Stores the indicated Vec4 value into the object, +// if it makes sense to do so. It is an error to call +// this on an object that does not store four +// floating-point values. +//////////////////////////////////////////////////////////////////// +INLINE void XFileDataObject:: +set(const LVecBase4d &vec) { + store_double_array(4, vec.get_data()); +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::set(mat) +// Access: Public +// Description: Stores the indicated Matrix value into the object, +// if it makes sense to do so. It is an error to call +// this on an object that does not store sixteen +// floating-point values. +//////////////////////////////////////////////////////////////////// +INLINE void XFileDataObject:: +set(const LMatrix4d &mat) { + store_double_array(16, mat.get_data()); +} + //////////////////////////////////////////////////////////////////// // Function: XFileDataObject::i // Access: Public @@ -116,6 +258,62 @@ s() const { return get_string_value(); } +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::vec2 +// Access: Public +// Description: Returns the object's representation as an LVecBase2d. +// It is an error if the object does not have two nested +// objects that store a double value. +//////////////////////////////////////////////////////////////////// +INLINE LVecBase2d XFileDataObject:: +vec2() const { + LVecBase2d vec; + get_double_array(2, &vec[0]); + return vec; +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::vec3 +// Access: Public +// Description: Returns the object's representation as an LVecBase3d. +// It is an error if the object does not have three nested +// objects that store a double value. +//////////////////////////////////////////////////////////////////// +INLINE LVecBase3d XFileDataObject:: +vec3() const { + LVecBase3d vec; + get_double_array(3, &vec[0]); + return vec; +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::vec4 +// Access: Public +// Description: Returns the object's representation as an LVecBase4d. +// It is an error if the object does not have four nested +// objects that store a double value. +//////////////////////////////////////////////////////////////////// +INLINE LVecBase4d XFileDataObject:: +vec4() const { + LVecBase4d vec; + get_double_array(4, &vec[0]); + return vec; +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::mat4 +// Access: Public +// Description: Returns the object's representation as an LMatrix4d. +// It is an error if the object does not have sixteen +// nested objects that store a double value. +//////////////////////////////////////////////////////////////////// +INLINE LMatrix4d XFileDataObject:: +mat4() const { + LMatrix4d mat; + get_double_array(16, &mat(0, 0)); + return mat; +} + //////////////////////////////////////////////////////////////////// // Function: XFileDataObject::size // Access: Public diff --git a/pandatool/src/xfile/xFileDataObject.cxx b/pandatool/src/xfile/xFileDataObject.cxx index 758eb6b317..ae0aa849a7 100644 --- a/pandatool/src/xfile/xFileDataObject.cxx +++ b/pandatool/src/xfile/xFileDataObject.cxx @@ -49,6 +49,17 @@ is_complex_object() const { return false; } +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::get_type_name +// Access: Public, Virtual +// Description: Returns a string that represents the type of object +// this data object represents. +//////////////////////////////////////////////////////////////////// +string XFileDataObject:: +get_type_name() const { + return get_type().get_name(); +} + //////////////////////////////////////////////////////////////////// // Function: XFileDataObject::add_int // Access: Public @@ -111,9 +122,7 @@ add_Vector(XFile *x_file, const LVecBase3d &vector) { add_element(node); node->zero_fill(); - (*node)["x"] = vector[0]; - (*node)["y"] = vector[1]; - (*node)["z"] = vector[2]; + node->set(vector); return *node; } @@ -150,10 +159,7 @@ add_IndexedColor(XFile *x_file, int index, const Colorf &color) { node->zero_fill(); (*node)["index"] = index; - (*node)["indexColor"]["red"] = color[0]; - (*node)["indexColor"]["green"] = color[1]; - (*node)["indexColor"]["blue"] = color[2]; - (*node)["indexColor"]["alpha"] = color[3]; + (*node)["indexColor"] = LCAST(double, color); return *node; } @@ -172,8 +178,7 @@ add_Coords2d(XFile *x_file, const LVecBase2d &coords) { add_element(node); node->zero_fill(); - (*node)["u"] = coords[0]; - (*node)["v"] = coords[1]; + node->set(coords); return *node; } @@ -223,7 +228,7 @@ write_data(ostream &out, int indent_level, const char *) const { void XFileDataObject:: set_int_value(int int_value) { xfile_cat.error() - << get_type() << " does not support integer values.\n"; + << get_type_name() << " does not support integer values.\n"; } //////////////////////////////////////////////////////////////////// @@ -235,7 +240,7 @@ set_int_value(int int_value) { void XFileDataObject:: set_double_value(double double_value) { xfile_cat.error() - << get_type() << " does not support floating-point values.\n"; + << get_type_name() << " does not support floating-point values.\n"; } //////////////////////////////////////////////////////////////////// @@ -247,9 +252,32 @@ set_double_value(double double_value) { void XFileDataObject:: set_string_value(const string &string_value) { xfile_cat.error() - << get_type() << " does not support stringeger values.\n"; + << get_type_name() << " does not support string values.\n"; } +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::store_double_array +// Access: Protected +// Description: Stores the indicated array of doubles in the nested +// elements within this object. There must be exactly +// the indicated number of nested values, and they must +// all accept a double. +//////////////////////////////////////////////////////////////////// +void XFileDataObject:: +store_double_array(int num_elements, const double *values) { + if (get_num_elements() != num_elements) { + xfile_cat.error() + << get_type_name() << " does not accept " + << num_elements << " values.\n"; + return; + } + + for (int i = 0; i < num_elements; i++) { + get_element(i)->set_double_value(values[i]); + } +} + + //////////////////////////////////////////////////////////////////// // Function: XFileDataObject::get_int_value // Access: Protected, Virtual @@ -283,6 +311,28 @@ get_string_value() const { return string(); } +//////////////////////////////////////////////////////////////////// +// Function: XFileDataObject::get_double_array +// Access: Protected +// Description: Fills the indicated array of doubles with the values +// from the nested elements within this object. There +// must be exactly the indicated number of nested +// values, and they must all return a double. +//////////////////////////////////////////////////////////////////// +void XFileDataObject:: +get_double_array(int num_elements, double *values) const { + if (get_num_elements() != num_elements) { + xfile_cat.error() + << get_type_name() << " does not contain " + << num_elements << " values.\n"; + return; + } + + for (int i = 0; i < num_elements; i++) { + values[i] = ((XFileDataObject *)this)->get_element(i)->get_double_value(); + } +} + //////////////////////////////////////////////////////////////////// // Function: XFileDataObject::get_num_elements // Access: Protected, Virtual @@ -305,7 +355,7 @@ XFileDataObject *XFileDataObject:: get_element(int n) { xfile_cat.warning() << "Looking for [" << n << "] within data object of type " - << get_type() << ", does not support nested objects.\n"; + << get_type_name() << ", does not support nested objects.\n"; return NULL; } @@ -319,6 +369,6 @@ XFileDataObject *XFileDataObject:: get_element(const string &name) { xfile_cat.warning() << "Looking for [\"" << name << "\"] within data object of type " - << get_type() << ", does not support nested objects.\n"; + << get_type_name() << ", does not support nested objects.\n"; return NULL; } diff --git a/pandatool/src/xfile/xFileDataObject.h b/pandatool/src/xfile/xFileDataObject.h index 6c44c4fe63..c2bdf34b67 100644 --- a/pandatool/src/xfile/xFileDataObject.h +++ b/pandatool/src/xfile/xFileDataObject.h @@ -42,14 +42,31 @@ public: INLINE const XFileDataDef *get_data_def() const; virtual bool is_complex_object() const; + virtual string get_type_name() const; INLINE void operator = (int int_value); INLINE void operator = (double double_value); INLINE void operator = (const string &string_value); + INLINE void operator = (const LVecBase2d &vec); + INLINE void operator = (const LVecBase3d &vec); + INLINE void operator = (const LVecBase4d &vec); + INLINE void operator = (const LMatrix4d &mat); + + INLINE void set(int int_value); + INLINE void set(double double_value); + INLINE void set(const string &string_value); + INLINE void set(const LVecBase2d &vec); + INLINE void set(const LVecBase3d &vec); + INLINE void set(const LVecBase4d &vec); + INLINE void set(const LMatrix4d &mat); INLINE int i() const; INLINE double d() const; INLINE string s() const; + INLINE LVecBase2d vec2() const; + INLINE LVecBase3d vec3() const; + INLINE LVecBase4d vec4() const; + INLINE LMatrix4d mat4() const; INLINE int size() const; INLINE const XFileDataObject &operator [] (int n) const; @@ -85,10 +102,12 @@ protected: virtual void set_int_value(int int_value); virtual void set_double_value(double double_value); virtual void set_string_value(const string &string_value); + void store_double_array(int num_elements, const double *values); virtual int get_int_value() const; virtual double get_double_value() const; virtual string get_string_value() const; + void get_double_array(int num_elements, double *values) const; virtual int get_num_elements() const; virtual XFileDataObject *get_element(int n); diff --git a/pandatool/src/xfile/xFileNode.I b/pandatool/src/xfile/xFileNode.I index 8ae9b5032d..9a5bfc925c 100644 --- a/pandatool/src/xfile/xFileNode.I +++ b/pandatool/src/xfile/xFileNode.I @@ -30,7 +30,8 @@ get_x_file() const { //////////////////////////////////////////////////////////////////// // Function: XFileNode::get_num_children // Access: Public -// Description: +// Description: Returns the list of children of this node. This +// list includes templates as well as data objects. //////////////////////////////////////////////////////////////////// INLINE int XFileNode:: get_num_children() const { @@ -40,10 +41,38 @@ get_num_children() const { //////////////////////////////////////////////////////////////////// // Function: XFileNode::get_child // Access: Public -// Description: +// Description: Returns the nth child of this node. This list +// includes templates as well as data objects. //////////////////////////////////////////////////////////////////// INLINE XFileNode *XFileNode:: get_child(int n) const { nassertr(n >= 0 && n < (int)_children.size(), NULL); return _children[n]; } + +//////////////////////////////////////////////////////////////////// +// Function: XFileNode::get_num_objects +// Access: Public +// Description: Returns the list of child objects of this node. This +// list does not include template definitions; it is +// strictly the list of children that are also data +// objects (instances of templates). +//////////////////////////////////////////////////////////////////// +INLINE int XFileNode:: +get_num_objects() const { + return _objects.size(); +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileNode::get_object +// Access: Public +// Description: Returns the nth child object of this node. This +// list does not include template definitions; it is +// strictly the list of children that are also data +// objects (instances of templates). +//////////////////////////////////////////////////////////////////// +INLINE XFileDataNode *XFileNode:: +get_object(int n) const { + nassertr(n >= 0 && n < (int)_objects.size(), NULL); + return _objects[n]; +} diff --git a/pandatool/src/xfile/xFileNode.cxx b/pandatool/src/xfile/xFileNode.cxx index b0f5a08a4b..37998c253c 100644 --- a/pandatool/src/xfile/xFileNode.cxx +++ b/pandatool/src/xfile/xFileNode.cxx @@ -147,13 +147,72 @@ get_guid() const { return empty; } +//////////////////////////////////////////////////////////////////// +// Function: XFileNode::is_template_def +// Access: Public, Virtual +// Description: Returns true if this node represents the definition +// of some template. This is the template definition, +// not an actual data object that represents an instance +// of the template. If the file strictly uses standard +// templates, the presence of template definitions is +// optional. +// +// If this returns true, the node must be of type +// XFileTemplate. +//////////////////////////////////////////////////////////////////// +bool XFileNode:: +is_template_def() const { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileNode::is_reference +// Access: Public, Virtual +// Description: Returns true if this node represents an indirect +// reference to an object defined previously in the +// file. References are generally transparent, so in +// most cases you never need to call this, unless you +// actually need to differentiate between references and +// instances; you can simply use the reference node as +// if it were itself the object it references. +// +// If this returns true, the node must be of type +// XFileDataNodeReference. +//////////////////////////////////////////////////////////////////// +bool XFileNode:: +is_reference() const { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileNode::is_object +// Access: Public, Virtual +// Description: Returns true if this node represents a data object +// that is the instance of some template, or false +// otherwise. This also returns true for references to +// objects (which are generally treated just like the +// objects themselves). +// +// If this returns true, the node must be of type +// XFileDataNode (it is either an XFileDataNodeTemplate +// or an XFileDataNodeReference). +//////////////////////////////////////////////////////////////////// +bool XFileNode:: +is_object() const { + return false; +} + //////////////////////////////////////////////////////////////////// // Function: XFileNode::is_standard_object // Access: Public, Virtual // Description: Returns true if this node represents an instance of // the standard template with the indicated name, or -// false otherwise. If this returns true, the object -// must be of type XFileDataNodeTemplate. +// false otherwise. This returns also returns true for +// references to standard objects. +// +// If this returns true, the node must be of type +// XFileDataNode (it is either an XFileDataNodeTemplate +// or an XFileDataNodeReference). //////////////////////////////////////////////////////////////////// bool XFileNode:: is_standard_object(const string &template_name) const { @@ -173,6 +232,9 @@ add_child(XFileNode *node) { if (node->has_guid()) { _x_file->_nodes_by_guid[node->get_guid()] = node; } + if (node->is_of_type(XFileDataNode::get_class_type())) { + _objects.push_back(DCAST(XFileDataNode, node)); + } _children.push_back(node); } @@ -185,6 +247,7 @@ add_child(XFileNode *node) { void XFileNode:: clear() { _children.clear(); + _objects.clear(); _children_by_name.clear(); } @@ -495,9 +558,16 @@ make_nice_name(const string &str) { string::const_iterator si; for (si = str.begin(); si != str.end(); ++si) { if (isalnum(*si)) { - result += *si; + result += (*si); } else { - result += "_"; + switch (*si) { + case '-': + result += (*si); + break; + + default: + result += "_"; + } } } diff --git a/pandatool/src/xfile/xFileNode.h b/pandatool/src/xfile/xFileNode.h index 42402e48ef..226fecc218 100644 --- a/pandatool/src/xfile/xFileNode.h +++ b/pandatool/src/xfile/xFileNode.h @@ -35,6 +35,7 @@ class XFileParseDataList; class XFileDataDef; class XFileDataObject; class XFileDataNode; +class XFileDataNodeTemplate; class Filename; //////////////////////////////////////////////////////////////////// @@ -57,9 +58,15 @@ public: int find_child_index(const XFileNode *child) const; XFileNode *find_descendent(const string &name) const; + INLINE int get_num_objects() const; + INLINE XFileDataNode *get_object(int n) const; + virtual bool has_guid() const; virtual const WindowsGuid &get_guid() const; + virtual bool is_template_def() const; + virtual bool is_reference() const; + virtual bool is_object() const; virtual bool is_standard_object(const string &template_name) const; void add_child(XFileNode *node); @@ -103,6 +110,9 @@ protected: typedef pvector< PT(XFileNode) > Children; Children _children; + + typedef pvector Objects; + Objects _objects; typedef pmap ChildrenByName; ChildrenByName _children_by_name; @@ -125,6 +135,8 @@ public: private: static TypeHandle _type_handle; + + friend class XFileDataNodeReference; }; #include "xFileNode.I" diff --git a/pandatool/src/xfile/xFileTemplate.cxx b/pandatool/src/xfile/xFileTemplate.cxx index 20dadc2c0e..bc415f128f 100644 --- a/pandatool/src/xfile/xFileTemplate.cxx +++ b/pandatool/src/xfile/xFileTemplate.cxx @@ -65,6 +65,24 @@ get_guid() const { return _guid; } +//////////////////////////////////////////////////////////////////// +// Function: XFileTemplate::is_template_def +// Access: Public, Virtual +// Description: Returns true if this node represents the definition +// of some template. This is the template definition, +// not an actual data object that represents an instance +// of the template. If the file strictly uses standard +// templates, the presence of template definitions is +// optional. +// +// If this returns true, the node must be of type +// XFileTemplate. +//////////////////////////////////////////////////////////////////// +bool XFileTemplate:: +is_template_def() const { + return true; +} + //////////////////////////////////////////////////////////////////// // Function: XFileTemplate::clear // Access: Public, Virtual diff --git a/pandatool/src/xfile/xFileTemplate.h b/pandatool/src/xfile/xFileTemplate.h index 2210d06198..74dadbe6ff 100644 --- a/pandatool/src/xfile/xFileTemplate.h +++ b/pandatool/src/xfile/xFileTemplate.h @@ -38,6 +38,8 @@ public: virtual bool has_guid() const; virtual const WindowsGuid &get_guid() const; + virtual bool is_template_def() const; + virtual void clear(); virtual void write_text(ostream &out, int indent_level) const; diff --git a/pandatool/src/xfile/xParser.cxx.prebuilt b/pandatool/src/xfile/xParser.cxx.prebuilt index f976c084a1..e903d9c5da 100644 --- a/pandatool/src/xfile/xParser.cxx.prebuilt +++ b/pandatool/src/xfile/xParser.cxx.prebuilt @@ -154,7 +154,7 @@ static const short yyrhs[] = 51, 0, 52, 0, 52, 54, 0, 3, 0, 66, 0, 52, 0, 6, 0, 66, 0, 54, 0, 17, 17, 17, 0, 0, 52, 53, 9, 58, 55, 59, - 10, 0, 60, 0, 59, 60, 0, 9, 65, 10, + 10, 0, 66, 0, 59, 60, 0, 9, 65, 10, 0, 57, 0, 61, 0, 62, 0, 63, 64, 0, 64, 0, 7, 0, 8, 0, 4, 0, 19, 0, 18, 0, 52, 0, 52, 54, 0, 0 @@ -232,81 +232,83 @@ static const short yyr2[] = static const short yydefact[] = { 66, 0, 1, 42, 0, 2, 66, 3, 0, 44, - 0, 43, 0, 49, 45, 4, 66, 66, 47, 0, + 0, 43, 0, 49, 45, 4, 66, 66, 47, 66, 46, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 0, 0, 0, 7, 12, 14, 15, 16, - 66, 66, 8, 61, 59, 60, 0, 63, 62, 54, - 0, 51, 55, 56, 0, 58, 0, 0, 0, 5, - 0, 13, 0, 0, 64, 0, 50, 52, 57, 31, - 0, 0, 33, 32, 0, 0, 11, 38, 40, 10, - 17, 19, 65, 53, 36, 0, 37, 18, 34, 0, - 6, 39, 41, 35, 48, 0, 0 + 66, 66, 8, 0, 51, 0, 0, 0, 5, 0, + 13, 0, 0, 61, 59, 60, 0, 50, 63, 62, + 54, 52, 55, 56, 0, 58, 31, 0, 0, 33, + 32, 0, 0, 11, 38, 40, 10, 17, 19, 64, + 0, 57, 36, 0, 37, 18, 34, 0, 6, 39, + 41, 65, 53, 35, 48, 0, 0 }; static const short yydefgoto[] = { - 1, 5, 17, 33, 34, 75, 35, 36, 37, 38, - 39, 40, 57, 71, 72, 85, 76, 77, 6, 10, - 15, 19, 79, 49, 16, 50, 51, 52, 53, 54, - 55, 65, 11 + 1, 5, 17, 33, 34, 72, 35, 36, 37, 38, + 39, 40, 46, 68, 69, 83, 73, 74, 9, 10, + 15, 19, 76, 7, 16, 43, 61, 62, 63, 64, + 65, 80, 11 }; static const short yypact[] = { - -32768, 3,-32768,-32768, 6,-32768, 6,-32768, 18,-32768, - 23,-32768, 34,-32768,-32768,-32768, 34, 65,-32768, 26, + -32768, 2,-32768,-32768, 12,-32768, 12,-32768, 8,-32768, + 9,-32768, 13,-32768,-32768,-32768, 13, 67,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -32768,-32768, 78, 31, 30, 52,-32768,-32768,-32768,-32768, - 6, 6,-32768,-32768,-32768,-32768, 6,-32768,-32768,-32768, - 7,-32768,-32768,-32768, -11,-32768, 6, 33, 6,-32768, - 2,-32768, 28, 29, 34, 40,-32768,-32768,-32768,-32768, - 19, -1,-32768,-32768, 36, 37, 6,-32768, 34,-32768, - -32768,-32768,-32768,-32768,-32768, 43,-32768,-32768,-32768, 41, - -32768,-32768,-32768,-32768,-32768, 59,-32768 + -32768,-32768, 80, 15, 14, 54,-32768,-32768,-32768,-32768, + 12, 12,-32768, 110,-32768, 12, 16, 12,-32768, 7, + -32768, 11, 17,-32768,-32768,-32768, 12,-32768,-32768,-32768, + -32768,-32768,-32768,-32768, -11,-32768,-32768, 6, -7,-32768, + -32768, 18, 19, 12,-32768, 13,-32768,-32768,-32768, 13, + 22,-32768,-32768, 23,-32768,-32768,-32768, 21,-32768,-32768, + -32768,-32768,-32768,-32768,-32768, 26,-32768 }; static const short yypgoto[] = { - -32768,-32768,-32768,-32768,-32768,-32768,-32768, 25,-32768,-32768, - -32768, 32,-32768,-32768, -10,-32768,-32768, -14, -4, -2, - -15,-32768,-32768, 66,-32768,-32768, 20,-32768,-32768,-32768, - 15,-32768, 4 + -32768,-32768,-32768,-32768,-32768,-32768,-32768, 5,-32768,-32768, + -32768, -4,-32768,-32768, -29,-32768,-32768, -32, -1, -27, + -15,-32768,-32768, 0,-32768,-32768,-32768,-32768,-32768,-32768, + -19,-32768, 4 }; -#define YYLAST 110 +#define YYLAST 129 static const short yytable[] = { - 8, 18, 9, 95, 2, 3, 3, 47, 48, 3, - 3, 43, 70, 41, 44, 45, 46, 66, 87, 74, - 20, 42, 3, 4, 84, 47, 48, 12, 58, 3, - 43, 41, 13, 44, 45, 46, 9, 9, 62, 63, - 14, 59, 64, 60, 47, 48, 70, 80, 81, 82, - 83, 90, 69, 89, 73, 3, 78, 93, 94, 96, - 61, 88, 91, 92, 56, -9, 86, 7, 3, 68, - 67, 0, 78, 21, 22, 23, 24, 25, 26, 27, - 28, 3, 29, 30, 31, 32, 21, 22, 23, 24, - 25, 26, 27, 28, 0, 29, 30, 31, 32, 21, - 22, 23, 24, 25, 26, 27, 28, 0, 29, 30, - 31 + 6, 18, 95, 8, 2, 3, 67, 58, 59, 3, + 3, 82, 85, 51, 52, 3, 41, 12, 13, 14, + 20, 42, 4, 44, 71, 48, 96, 49, 45, 67, + 77, 47, 92, 88, 41, 87, 78, 93, 94, 86, + 50, 89, 6, 60, 66, 81, 70, 0, 75, 0, + 0, 0, 0, 0, 0, 79, 0, 3, 0, 0, + 90, 0, 0, 0, 91, 0, 84, -9, 0, 0, + 3, 0, 75, 0, 0, 21, 22, 23, 24, 25, + 26, 27, 28, 3, 29, 30, 31, 32, 21, 22, + 23, 24, 25, 26, 27, 28, 0, 29, 30, 31, + 32, 21, 22, 23, 24, 25, 26, 27, 28, 0, + 29, 30, 31, 3, 53, 0, 0, 54, 55, 56, + 57, 0, 0, 0, 0, 0, 0, 0, 58, 59 }; static const short yycheck[] = { - 4, 16, 6, 0, 0, 3, 3, 18, 19, 3, - 3, 4, 13, 17, 7, 8, 9, 10, 19, 17, - 16, 17, 3, 20, 5, 18, 19, 9, 32, 3, - 4, 35, 9, 7, 8, 9, 40, 41, 40, 41, - 6, 10, 46, 13, 18, 19, 13, 19, 19, 64, - 10, 14, 56, 17, 58, 3, 60, 14, 17, 0, - 35, 71, 76, 78, 32, 13, 70, 1, 3, 54, - 50, -1, 76, 21, 22, 23, 24, 25, 26, 27, - 28, 3, 30, 31, 32, 33, 21, 22, 23, 24, - 25, 26, 27, 28, -1, 30, 31, 32, 33, 21, - 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, - 32 + 1, 16, 0, 4, 0, 3, 13, 18, 19, 3, + 3, 5, 19, 40, 41, 3, 17, 9, 9, 6, + 16, 17, 20, 19, 17, 10, 0, 13, 32, 13, + 19, 32, 10, 14, 35, 17, 19, 14, 17, 68, + 35, 73, 43, 43, 45, 64, 47, -1, 49, -1, + -1, -1, -1, -1, -1, 56, -1, 3, -1, -1, + 75, -1, -1, -1, 79, -1, 67, 13, -1, -1, + 3, -1, 73, -1, -1, 21, 22, 23, 24, 25, + 26, 27, 28, 3, 30, 31, 32, 33, 21, 22, + 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, + 33, 21, 22, 23, 24, 25, 26, 27, 28, -1, + 30, 31, 32, 3, 4, -1, -1, 7, 8, 9, + 10, -1, -1, -1, -1, -1, -1, -1, 18, 19 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/usr/share/bison/bison.simple" diff --git a/pandatool/src/xfile/xParser.yxx b/pandatool/src/xfile/xParser.yxx index f9b5eb68dc..642379e144 100644 --- a/pandatool/src/xfile/xParser.yxx +++ b/pandatool/src/xfile/xParser.yxx @@ -357,7 +357,7 @@ object: ; data_parts_list: - data_part + empty | data_parts_list data_part ; diff --git a/pandatool/src/xfileegg/Sources.pp b/pandatool/src/xfileegg/Sources.pp index e56b1495ea..01ce01442b 100644 --- a/pandatool/src/xfileegg/Sources.pp +++ b/pandatool/src/xfileegg/Sources.pp @@ -1,10 +1,3 @@ - -// The .x converter takes advantage of the DirectX API's; therefore, -// it can only be built if we have DX available (and therefore it only -// builds on Windows--sorry). -#define BUILD_DIRECTORY $[HAVE_DX] -#define USE_PACKAGES dx - #begin ss_lib_target #define TARGET xfileegg #define LOCAL_LIBS xfile eggbase progbase pandatoolbase @@ -13,22 +6,19 @@ mathutil:c linmath:c putil:c panda:m \ express:c pandaexpress:m \ dtoolconfig dtool pystub \ - - #define WIN_SYS_LIBS \ - d3dxof.lib dxguid.lib d3d8.lib d3dx8.lib dxerr8.lib #define COMBINED_SOURCES $[TARGET]_composite1.cxx #define SOURCES \ xFileAnimationSet.h xFileAnimationSet.I \ xFileFace.h xFileMaker.h xFileMaterial.h \ - xFileMesh.h xFileNormal.h xFileTemplates.h \ + xFileMesh.h xFileNormal.h \ xFileToEggConverter.h xFileVertex.h #define INCLUDED_SOURCES \ xFileAnimationSet.cxx \ xFileFace.cxx xFileMaker.cxx xFileMaterial.cxx \ - xFileMesh.cxx xFileNormal.cxx xFileTemplates.cxx \ + xFileMesh.cxx xFileNormal.cxx \ xFileToEggConverter.cxx xFileVertex.cxx #end ss_lib_target diff --git a/pandatool/src/xfileegg/xFileAnimationSet.cxx b/pandatool/src/xfileegg/xFileAnimationSet.cxx index f0591d0798..c07f9acfc0 100644 --- a/pandatool/src/xfileegg/xFileAnimationSet.cxx +++ b/pandatool/src/xfileegg/xFileAnimationSet.cxx @@ -90,7 +90,6 @@ create_hierarchy(XFileToEggConverter *converter) { // Put some data in the empty tables also. Tables::iterator ti; for (ti = _tables.begin(); ti != _tables.end(); ++ti) { - const string &joint_name = (*ti).first; EggXfmSAnim *anim_table = (*ti).second._table; EggGroup *joint = (*ti).second._joint; if (anim_table->empty() && joint != (EggGroup *)NULL) { diff --git a/pandatool/src/xfileegg/xFileMaker.cxx b/pandatool/src/xfileegg/xFileMaker.cxx index 5d5e6e3f1b..5f180a0801 100644 --- a/pandatool/src/xfileegg/xFileMaker.cxx +++ b/pandatool/src/xfileegg/xFileMaker.cxx @@ -19,7 +19,6 @@ #include "xFileMaker.h" #include "xFileMesh.h" #include "xFileMaterial.h" -#include "xFileTemplates.h" #include "config_xfile.h" #include "notify.h" @@ -81,7 +80,7 @@ add_tree(EggData &egg_data) { // Now collect all the polygons together into polysets. EggPolysetMaker pmaker; - int num_bins = pmaker.make_bins(&egg_data); + pmaker.make_bins(&egg_data); // And now we're ready to traverse the egg hierarchy. if (!recurse_nodes(&egg_data, _x_file)) { @@ -271,58 +270,5 @@ finalize_mesh(XFileNode *x_parent, XFileMesh *mesh) { // Finally, create the Mesh object. mesh->make_x_mesh(x_parent, mesh_index); - /* - if (mesh->has_materials()) { - // Tack on material definitions. - LPDIRECTXFILEDATA xmaterial_list; - mesh->make_material_list_data(raw_data); - if (!create_object(xmaterial_list, TID_D3DRMMeshMaterialList, - "materials" + mesh_index, raw_data)) { - return false; - } - - // Now we need to iterate through the list of Materials - // themselves, and add *these* as children of the material list. - int num_materials = mesh->get_num_materials(); - for (int i = 0; i < num_materials; i++) { - XFileMaterial *material = mesh->get_material(i); - LPDIRECTXFILEDATA xmaterial; - material->make_material_data(raw_data); - if (!create_object(xmaterial, TID_D3DRMMaterial, - "material" + mesh_index + "_" + format_string(i), - raw_data)) { - return false; - } - - // Also, if the Material has a texture map, we must add *this* - // as a child of the material. What a weird system. - if (material->has_texture()) { - LPDIRECTXFILEDATA xtexture; - material->make_texture_data(raw_data); - if (!create_object(xtexture, TID_D3DRMTextureFilename, - "texture" + mesh_index + "_" + format_string(i), - raw_data)) { - return false; - } - - if (!attach_and_release(xtexture, xmaterial)) { - return false; - } - } - - if (!attach_and_release(xmaterial, xmaterial_list)) { - return false; - } - } - - if (!attach_and_release(xmaterial_list, xobj)) { - return false; - } - } - - if (!attach_and_release(xobj, x_parent)) { - return false; - } - */ return true; } diff --git a/pandatool/src/xfileegg/xFileMaterial.cxx b/pandatool/src/xfileegg/xFileMaterial.cxx index b0ac8ce231..444f306ffe 100644 --- a/pandatool/src/xfileegg/xFileMaterial.cxx +++ b/pandatool/src/xfileegg/xFileMaterial.cxx @@ -18,7 +18,7 @@ #include "xFileMaterial.h" #include "xFileToEggConverter.h" - +#include "xFileDataNode.h" #include "eggMaterial.h" #include "eggTexture.h" #include "eggPrimitive.h" @@ -192,63 +192,43 @@ make_x_material(XFileNode *x_meshMaterials, const string &suffix) { _specular_color, _emissive_color); if (has_texture()) { - XFileDataNode *x_texture = - x_material->add_TextureFilename("texture" + suffix, _texture); + x_material->add_TextureFilename("texture" + suffix, _texture); } return x_material; } //////////////////////////////////////////////////////////////////// -// Function: XFileMaterial::read_material_data +// Function: XFileMaterial::fill_material // Access: Public // Description: Fills the structure based on the raw data from the -// Material template. +// X file's Material object. //////////////////////////////////////////////////////////////////// bool XFileMaterial:: -read_material_data(const Datagram &raw_data) { - DatagramIterator di(raw_data); - - _face_color[0] = di.get_float32(); - _face_color[1] = di.get_float32(); - _face_color[2] = di.get_float32(); - _face_color[3] = di.get_float32(); - _power = di.get_float32(); - _specular_color[0] = di.get_float32(); - _specular_color[1] = di.get_float32(); - _specular_color[2] = di.get_float32(); - _emissive_color[0] = di.get_float32(); - _emissive_color[1] = di.get_float32(); - _emissive_color[2] = di.get_float32(); +fill_material(XFileDataNode *obj) { + _face_color = LCAST(float, (*obj)["faceColor"].vec4()); + _power = (*obj)["faceColor"].d(); + _specular_color = LCAST(float, (*obj)["specularColor"].vec3()); + _emissive_color = LCAST(float, (*obj)["emissiveColor"].vec3()); _has_material = true; - if (di.get_remaining_size() != 0) { - nout << "Ignoring " << di.get_remaining_size() - << " trailing MeshMaterial.\n"; + // Walk through the children of the material. If there are any, + // there should be only one, and it should be just a Texture. + int num_objects = obj->get_num_objects(); + for (int i = 0; i < num_objects; i++) { + XFileDataNode *child = obj->get_object(i); + if (child->is_standard_object("TextureFilename")) { + _texture = Filename::from_os_specific((*child)["filename"].s()); + _has_texture = true; + + } else { + if (xfile_cat.is_debug()) { + xfile_cat.debug() + << "Ignoring material object of unknown type: " + << child->get_template_name() << "\n"; + } + } } return true; } - -//////////////////////////////////////////////////////////////////// -// Function: XFileMaterial::read_texture_data -// Access: Public -// Description: Fills the structure based on the raw data from the -// TextureFilename template. -//////////////////////////////////////////////////////////////////// -bool XFileMaterial:: -read_texture_data(const Datagram &raw_data) { - DatagramIterator di(raw_data); - - // The Microsoft convention is to stuff a pointer into a four-byte - // field. Not terribly portable, but that's the interface. - const char *ptr = (const char *)di.get_int32(); - _texture = Filename::from_os_specific(ptr); - _has_texture = true; - - if (di.get_remaining_size() != 0) { - nout << "Ignoring " << di.get_remaining_size() - << " trailing MeshMaterial.\n"; - } - return true; -} diff --git a/pandatool/src/xfileegg/xFileMaterial.h b/pandatool/src/xfileegg/xFileMaterial.h index 3d15297213..2f89463f41 100644 --- a/pandatool/src/xfileegg/xFileMaterial.h +++ b/pandatool/src/xfileegg/xFileMaterial.h @@ -48,12 +48,11 @@ public: bool has_texture() const; XFileDataNode *make_x_material(XFileNode *x_meshMaterials, const string &suffix); - bool read_material_data(const Datagram &raw_data); - bool read_texture_data(const Datagram &raw_data); + bool fill_material(XFileDataNode *obj); private: Colorf _face_color; - float _power; + double _power; RGBColorf _specular_color; RGBColorf _emissive_color; Filename _texture; diff --git a/pandatool/src/xfileegg/xFileMesh.cxx b/pandatool/src/xfileegg/xFileMesh.cxx index a582ce06d6..9aefdf6643 100644 --- a/pandatool/src/xfileegg/xFileMesh.cxx +++ b/pandatool/src/xfileegg/xFileMesh.cxx @@ -310,19 +310,19 @@ create_polygons(XFileToEggConverter *converter) { // Create a temporary EggVertex before adding it to the pool. EggVertex temp_vtx; temp_vtx.set_external_index(vertex_index); - temp_vtx.set_pos(LCAST(double, vertex->_point)); + temp_vtx.set_pos(vertex->_point); if (vertex->_has_color) { temp_vtx.set_color(vertex->_color); } if (vertex->_has_uv) { - TexCoordd uv = LCAST(double, vertex->_uv); + TexCoordd uv = vertex->_uv; // Windows draws the UV's upside-down. uv[1] = 1.0 - uv[1]; temp_vtx.set_uv(uv); } if (normal != (XFileNormal *)NULL && normal->_has_normal) { - temp_vtx.set_normal(LCAST(double, normal->_normal)); + temp_vtx.set_normal(normal->_normal); } // We are given the vertex in local space; we need to transform @@ -342,7 +342,7 @@ create_polygons(XFileToEggConverter *converter) { EggGroup *joint = converter->find_joint(data._joint_name); if (joint != (EggGroup *)NULL) { double weight = (*wmi).second; - LMatrix4d mat = LCAST(double, data._matrix_offset); + LMatrix4d mat = data._matrix_offset; mat *= joint->get_node_to_vertex(); weighted_transform += mat * weight; net_weight += weight; @@ -395,7 +395,7 @@ create_polygons(XFileToEggConverter *converter) { } } } - + if (!has_normals()) { // If we don't have explicit normals, make some up, per the DX // spec. Since the DX spec doesn't mention anything about a @@ -488,7 +488,7 @@ make_x_mesh(XFileNode *x_parent, const string &suffix) { Vertices::const_iterator vi; for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) { XFileVertex *vertex = (*vi); - x_vertices.add_Vector(x_mesh->get_x_file(), LCAST(double, vertex->_point)); + x_vertices.add_Vector(x_mesh->get_x_file(), vertex->_point); } (*x_mesh)["nVertices"] = x_vertices.size(); @@ -546,7 +546,7 @@ make_x_normals(XFileNode *x_mesh, const string &suffix) { Normals::const_iterator ni; for (ni = _normals.begin(); ni != _normals.end(); ++ni) { XFileNormal *normal = (*ni); - x_normals.add_Vector(x_mesh->get_x_file(), LCAST(double, normal->_normal)); + x_normals.add_Vector(x_mesh->get_x_file(), normal->_normal); } (*x_meshNormals)["nNormals"] = x_normals.size(); @@ -610,7 +610,7 @@ make_x_uvs(XFileNode *x_mesh, const string &suffix) { Vertices::const_iterator vi; for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) { XFileVertex *vertex = (*vi); - x_uvs.add_Coords2d(x_mesh->get_x_file(), LCAST(double, vertex->_uv)); + x_uvs.add_Coords2d(x_mesh->get_x_file(), vertex->_uv); } (*x_meshUvs)["nTextureCoords"] = x_uvs.size(); @@ -655,35 +655,33 @@ make_x_material_list(XFileNode *x_mesh, const string &suffix) { } //////////////////////////////////////////////////////////////////// -// Function: XFileMesh::read_mesh_data +// Function: XFileMesh::fill_mesh // Access: Public // Description: Fills the structure based on the raw data from the -// Mesh template. +// X file's Mesh object. //////////////////////////////////////////////////////////////////// bool XFileMesh:: -read_mesh_data(const Datagram &raw_data) { - DatagramIterator di(raw_data); - +fill_mesh(XFileDataNode *obj) { clear(); int i, j; - int num_vertices = di.get_int32(); - for (i = 0; i < num_vertices; i++) { + + const XFileDataObject &vertices = (*obj)["vertices"]; + for (i = 0; i < vertices.size(); i++) { XFileVertex *vertex = new XFileVertex; - vertex->_point[0] = di.get_float32(); - vertex->_point[1] = di.get_float32(); - vertex->_point[2] = di.get_float32(); + vertex->_point = vertices[i].vec3(); add_vertex(vertex); } - int num_faces = di.get_int32(); - for (i = 0; i < num_faces; i++) { + const XFileDataObject &faces = (*obj)["faces"]; + for (i = 0; i < faces.size(); i++) { XFileFace *face = new XFileFace; - num_vertices = di.get_int32(); - for (j = 0; j < num_vertices; j++) { + const XFileDataObject &faceIndices = faces[i]["faceVertexIndices"]; + + for (j = 0; j < faceIndices.size(); j++) { XFileFace::Vertex vertex; - vertex._vertex_index = di.get_int32(); + vertex._vertex_index = faceIndices[j].i(); vertex._normal_index = -1; face->_vertices.push_back(vertex); @@ -691,207 +689,220 @@ read_mesh_data(const Datagram &raw_data) { _faces.push_back(face); } - if (di.get_remaining_size() != 0) { - xfile_cat.warning() - << "Ignoring " << di.get_remaining_size() << " trailing Mesh.\n"; + // Some properties are stored as children of the mesh. + int num_objects = obj->get_num_objects(); + for (int i = 0; i < num_objects; i++) { + if (!fill_mesh_child(obj->get_object(i))) { + return false; + } } return true; } //////////////////////////////////////////////////////////////////// -// Function: XFileMesh::read_normal_data +// Function: XFileMesh::fill_mesh_child +// Access: Public +// Description: Fills the structure based on one of the children of +// the Mesh object. +//////////////////////////////////////////////////////////////////// +bool XFileMesh:: +fill_mesh_child(XFileDataNode *obj) { + if (obj->is_standard_object("MeshNormals")) { + if (!fill_normals(obj)) { + return false; + } + + } else if (obj->is_standard_object("MeshVertexColors")) { + if (!fill_colors(obj)) { + return false; + } + + } else if (obj->is_standard_object("MeshTextureCoords")) { + if (!fill_uvs(obj)) { + return false; + } + + } else if (obj->is_standard_object("MeshMaterialList")) { + if (!fill_material_list(obj)) { + return false; + } + + } else if (obj->is_standard_object("XSkinMeshHeader")) { + // Quietly ignore a skin mesh header. + + } else if (obj->is_standard_object("SkinWeights")) { + if (!fill_skin_weights(obj)) { + return false; + } + + } else { + if (xfile_cat.is_debug()) { + xfile_cat.debug() + << "Ignoring mesh data object of unknown type: " + << obj->get_template_name() << "\n"; + } + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: XFileMesh::fill_normals // Access: Public // Description: Fills the structure based on the raw data from the // MeshNormals template. //////////////////////////////////////////////////////////////////// bool XFileMesh:: -read_normal_data(const Datagram &raw_data) { - DatagramIterator di(raw_data); +fill_normals(XFileDataNode *obj) { + int i, j; - int num_normals = di.get_int32(); - int i; - for (i = 0; i < num_normals; i++) { + const XFileDataObject &normals = (*obj)["normals"]; + for (i = 0; i < normals.size(); i++) { XFileNormal *normal = new XFileNormal; - normal->_normal[0] = di.get_float32(); - normal->_normal[1] = di.get_float32(); - normal->_normal[2] = di.get_float32(); + normal->_normal = normals[i].vec3(); normal->_has_normal = true; add_normal(normal); } - int num_faces = di.get_int32(); - - if (num_faces != _faces.size()) { + const XFileDataObject &faceNormals = (*obj)["faceNormals"]; + if (faceNormals.size() != (int)_faces.size()) { xfile_cat.error() << "Incorrect number of faces in MeshNormals.\n"; return false; } - for (i = 0; i < num_faces; i++) { + for (i = 0; i < faceNormals.size(); i++) { XFileFace *face = _faces[i]; - int num_vertices = di.get_int32(); - if (num_vertices != face->_vertices.size()) { + + const XFileDataObject &faceIndices = faceNormals[i]["faceVertexIndices"]; + + if (faceIndices.size() != (int)face->_vertices.size()) { xfile_cat.error() << "Incorrect number of vertices for face in MeshNormals.\n"; return false; } - for (int j = 0; j < num_vertices; j++) { - face->_vertices[j]._normal_index = di.get_int32(); - } - } - if (di.get_remaining_size() != 0) { - xfile_cat.warning() - << "Ignoring " << di.get_remaining_size() - << " trailing MeshNormals.\n"; + for (j = 0; j < faceIndices.size(); j++) { + face->_vertices[j]._normal_index = faceIndices[j].i(); + } } return true; } //////////////////////////////////////////////////////////////////// -// Function: XFileMesh::read_color_data +// Function: XFileMesh::fill_colors // Access: Public // Description: Fills the structure based on the raw data from the // MeshVertexColors template. //////////////////////////////////////////////////////////////////// bool XFileMesh:: -read_color_data(const Datagram &raw_data) { - DatagramIterator di(raw_data); - - int num_colors = di.get_int32(); - int i; - for (i = 0; i < num_colors; i++) { - unsigned int vertex_index = di.get_int32(); - if (vertex_index < 0 || vertex_index >= _vertices.size()) { +fill_colors(XFileDataNode *obj) { + const XFileDataObject &vertexColors = (*obj)["vertexColors"]; + for (int i = 0; i < vertexColors.size(); i++) { + int vertex_index = vertexColors[i]["index"].i(); + if (vertex_index < 0 || vertex_index >= (int)_vertices.size()) { xfile_cat.error() << "Vertex index out of range in MeshVertexColors.\n"; return false; } - XFileVertex *vertex = _vertices[vertex_index]; - vertex->_color[0] = di.get_float32(); - vertex->_color[1] = di.get_float32(); - vertex->_color[2] = di.get_float32(); - vertex->_color[3] = di.get_float32(); - vertex->_has_color = true; - } - if (di.get_remaining_size() != 0) { - xfile_cat.warning() - << "Ignoring " << di.get_remaining_size() - << " trailing MeshVertexColors.\n"; + XFileVertex *vertex = _vertices[vertex_index]; + vertex->_color = LCAST(float, vertexColors[i]["indexColor"].vec4()); + vertex->_has_color = true; } return true; } //////////////////////////////////////////////////////////////////// -// Function: XFileMesh::read_uv_data +// Function: XFileMesh::fill_uvs // Access: Public // Description: Fills the structure based on the raw data from the // MeshTextureCoords template. //////////////////////////////////////////////////////////////////// bool XFileMesh:: -read_uv_data(const Datagram &raw_data) { - DatagramIterator di(raw_data); - - int num_vertices = di.get_int32(); - if (num_vertices != _vertices.size()) { +fill_uvs(XFileDataNode *obj) { + const XFileDataObject &textureCoords = (*obj)["textureCoords"]; + if (textureCoords.size() != (int)_vertices.size()) { xfile_cat.error() << "Wrong number of vertices in MeshTextureCoords.\n"; return false; } - int i; - for (i = 0; i < num_vertices; i++) { + for (int i = 0; i < textureCoords.size(); i++) { XFileVertex *vertex = _vertices[i]; - vertex->_uv[0] = di.get_float32(); - vertex->_uv[1] = di.get_float32(); + vertex->_uv = textureCoords[i].vec2(); vertex->_has_uv = true; } - if (di.get_remaining_size() != 0) { - xfile_cat.warning() - << "Ignoring " << di.get_remaining_size() - << " trailing MeshTextureCoords.\n"; - } - return true; } //////////////////////////////////////////////////////////////////// -// Function: XFileMesh::read_skin_weights_data +// Function: XFileMesh::fill_skin_weights // Access: Public // Description: Fills the structure based on the raw data from the // SkinWeights template. //////////////////////////////////////////////////////////////////// bool XFileMesh:: -read_skin_weights_data(const Datagram &raw_data) { - DatagramIterator di(raw_data); - +fill_skin_weights(XFileDataNode *obj) { // Create a new SkinWeightsData record for the table. We'll need // this data later when we create the vertices. _skin_weights.push_back(SkinWeightsData()); SkinWeightsData &data = _skin_weights.back(); - // The DX system encodes a pointer to a character string in four - // bytes within the stream. Weird, in a Microsofty sort of way. - data._joint_name = (const char *)di.get_uint32(); + data._joint_name = (*obj)["transformNodeName"].s(); - int num_weights = di.get_int32(); + const XFileDataObject &vertexIndices = (*obj)["vertexIndices"]; + const XFileDataObject &weights = (*obj)["weights"]; - vector_int vindices; - vindices.reserve(num_weights); + if (weights.size() != vertexIndices.size()) { + xfile_cat.error() + << "Inconsistent number of vertices in SkinWeights.\n"; + return false; + } + + // Unpack the weight for each vertex. + for (int i = 0; i < weights.size(); i++) { + int vindex = vertexIndices[i].i(); + double weight = weights[i].d(); - // Unpack the list of vertices first - int i; - for (i = 0; i < num_weights; i++) { - int vindex = di.get_int32(); if (vindex < 0 || vindex > (int)_vertices.size()) { xfile_cat.error() << "Illegal vertex index " << vindex << " in SkinWeights.\n"; return false; } - vindices.push_back(vindex); + data._weight_map[vindex] = weight; } - // Then unpack the weight for each vertex. - for (i = 0; i < num_weights; i++) { - float weight = di.get_float32(); - data._weight_map[vindices[i]] = weight; - } - - // Finally, read the matrix offset. - data._matrix_offset.read_datagram(di); + // Also retrieve the matrix offset. + data._matrix_offset = (*obj)["matrixOffset"]["matrix"].mat4(); return true; } //////////////////////////////////////////////////////////////////// -// Function: XFileMesh::read_material_list_data +// Function: XFileMesh::fill_material_list // Access: Public // Description: Fills the structure based on the raw data from the -// MaterialList template. +// MeshMaterialList template. //////////////////////////////////////////////////////////////////// bool XFileMesh:: -read_material_list_data(const Datagram &raw_data) { - DatagramIterator di(raw_data); - - di.get_int32(); /* num_materials */ - unsigned int num_faces = di.get_int32(); - - if (num_faces > _faces.size()) { +fill_material_list(XFileDataNode *obj) { + const XFileDataObject &faceIndexes = (*obj)["faceIndexes"]; + if (faceIndexes.size() > (int)_faces.size()) { xfile_cat.error() - << "Too many faces in MaterialList.\n"; + << "Too many faces in MeshMaterialList.\n"; return false; } int material_index = -1; - unsigned int i = 0; - while (i < num_faces) { + int i = 0; + while (i < faceIndexes.size()) { XFileFace *face = _faces[i]; - material_index = di.get_int32(); + material_index = faceIndexes[i].i(); face->_material_index = material_index; i++; } @@ -904,10 +915,26 @@ read_material_list_data(const Datagram &raw_data) { i++; } - if (di.get_remaining_size() != 0) { - xfile_cat.warning() - << "Ignoring " << di.get_remaining_size() - << " trailing MeshMaterialList.\n"; + // Now look for children of the MaterialList object. These should + // all be Material objects. + int num_objects = obj->get_num_objects(); + for (int i = 0; i < num_objects; i++) { + XFileDataNode *child = obj->get_object(i); + if (child->is_standard_object("Material")) { + XFileMaterial *material = new XFileMaterial; + if (!material->fill_material(child)) { + delete material; + return false; + } + add_material(material); + + } else { + if (xfile_cat.is_debug()) { + xfile_cat.debug() + << "Ignoring material list object of unknown type: " + << child->get_template_name() << "\n"; + } + } } return true; diff --git a/pandatool/src/xfileegg/xFileMesh.h b/pandatool/src/xfileegg/xFileMesh.h index 88f8330191..87b0e8a016 100644 --- a/pandatool/src/xfileegg/xFileMesh.h +++ b/pandatool/src/xfileegg/xFileMesh.h @@ -27,6 +27,7 @@ #include "coordinateSystem.h" class XFileNode; +class XFileDataNode; class XFileMesh; class XFileVertex; class XFileNormal; @@ -78,12 +79,13 @@ public: XFileDataNode *make_x_uvs(XFileNode *x_mesh, const string &suffix); XFileDataNode *make_x_material_list(XFileNode *x_mesh, const string &suffix); - bool read_mesh_data(const Datagram &raw_data); - bool read_normal_data(const Datagram &raw_data); - bool read_color_data(const Datagram &raw_data); - bool read_uv_data(const Datagram &raw_data); - bool read_skin_weights_data(const Datagram &raw_data); - bool read_material_list_data(const Datagram &raw_data); + bool fill_mesh(XFileDataNode *obj); + bool fill_mesh_child(XFileDataNode *obj); + bool fill_normals(XFileDataNode *obj); + bool fill_colors(XFileDataNode *obj); + bool fill_uvs(XFileDataNode *obj); + bool fill_skin_weights(XFileDataNode *obj); + bool fill_material_list(XFileDataNode *obj); private: typedef pvector Vertices; @@ -104,7 +106,7 @@ private: public: string _joint_name; WeightMap _weight_map; - LMatrix4f _matrix_offset; + LMatrix4d _matrix_offset; }; typedef pvector SkinWeights; SkinWeights _skin_weights; diff --git a/pandatool/src/xfileegg/xFileNormal.cxx b/pandatool/src/xfileegg/xFileNormal.cxx index 5331a4c31f..35a1dca2fc 100644 --- a/pandatool/src/xfileegg/xFileNormal.cxx +++ b/pandatool/src/xfileegg/xFileNormal.cxx @@ -56,7 +56,7 @@ set_from_egg(EggVertex *egg_vertex, EggPrimitive *egg_prim) { norm = norm * egg_prim->get_vertex_to_node(); } - _normal = LCAST(float, norm); + _normal = norm; _has_normal = true; } } diff --git a/pandatool/src/xfileegg/xFileNormal.h b/pandatool/src/xfileegg/xFileNormal.h index 986e420502..1bab7492f1 100644 --- a/pandatool/src/xfileegg/xFileNormal.h +++ b/pandatool/src/xfileegg/xFileNormal.h @@ -38,7 +38,7 @@ public: void set_from_egg(EggVertex *egg_vertex, EggPrimitive *egg_prim); int compare_to(const XFileNormal &other) const; - Normalf _normal; + Normald _normal; bool _has_normal; }; diff --git a/pandatool/src/xfileegg/xFileTemplates.cxx b/pandatool/src/xfileegg/xFileTemplates.cxx deleted file mode 100644 index 7330d82129..0000000000 --- a/pandatool/src/xfileegg/xFileTemplates.cxx +++ /dev/null @@ -1,34 +0,0 @@ -// Filename: xFileTemplates.cxx -// Created by: drose (21Jun01) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved -// -// All use of this software is subject to the terms of the Panda 3d -// Software license. You should have received a copy of this license -// along with this source code; you will also find a current copy of -// the license at http://etc.cmu.edu/panda3d/docs/license/ . -// -// To contact the maintainers of this program write to -// panda3d-general@lists.sourceforge.net . -// -//////////////////////////////////////////////////////////////////// - -#include "xFileTemplates.h" - -// This must be included only in exactly one .cxx file, since -// including defines the structure! -#include - -const int d3drm_xtemplates_length = D3DRM_XTEMPLATE_BYTES; - -// I don't know what the official Windows way to declare this thing -// is. This is my way. What a strange coding environment this is. -#define DECLARE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID name \ - = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } - -DECLARE_GUID(mydef_TID_D3DRMHeader, -0x3d82ab43, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); diff --git a/pandatool/src/xfileegg/xFileTemplates.h b/pandatool/src/xfileegg/xFileTemplates.h deleted file mode 100644 index 2c91d9b2a8..0000000000 --- a/pandatool/src/xfileegg/xFileTemplates.h +++ /dev/null @@ -1,54 +0,0 @@ -// Filename: xFileTemplates.h -// Created by: drose (21Jun01) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved -// -// All use of this software is subject to the terms of the Panda 3d -// Software license. You should have received a copy of this license -// along with this source code; you will also find a current copy of -// the license at http://etc.cmu.edu/panda3d/docs/license/ . -// -// To contact the maintainers of this program write to -// panda3d-general@lists.sourceforge.net . -// -//////////////////////////////////////////////////////////////////// - -#ifndef XFILETEMPLATES_H -#define XFILETEMPLATES_H - -#include "pandatoolbase.h" - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#undef WIN32_LEAN_AND_MEAN - -//////////////////////////////////////////////////////////////////// -// -// This file exists to get an external handle to the table defined in -// the Windows header file rmxftmpl.h. Since the table is actually -// defined in the Windows header file, we can't include that header -// file in multiple .cxx files, or we'll define the table multiple -// times. -// -// Unfortunately, the length of the table is defined within that -// header file with a #define, so there's no way to extern *that*. -// Instead, we define our own variable that references the length. -// -//////////////////////////////////////////////////////////////////// - -extern unsigned char D3DRM_XTEMPLATES[]; -extern const int d3drm_xtemplates_length; - -// For some reason, this definition does not appear in rmxfguid.h. -/* {3D82AB43-62DA-11cf-AB39-0020AF71E433} */ -DEFINE_GUID(mydef_TID_D3DRMHeader, -0x3d82ab43, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); - -#endif - diff --git a/pandatool/src/xfileegg/xFileToEggConverter.cxx b/pandatool/src/xfileegg/xFileToEggConverter.cxx index 09665ab58a..217959741f 100644 --- a/pandatool/src/xfileegg/xFileToEggConverter.cxx +++ b/pandatool/src/xfileegg/xFileToEggConverter.cxx @@ -19,7 +19,6 @@ #include "xFileToEggConverter.h" #include "xFileMesh.h" #include "xFileMaterial.h" -#include "xFileTemplates.h" #include "xFileAnimationSet.h" #include "config_xfile.h" @@ -32,26 +31,6 @@ #include "eggTextureCollection.h" #include "dcast.h" -#define MY_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - EXTERN_C const GUID DECLSPEC_SELECTANY name \ - = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } - -// These are defined in d3dx9mesh.h, which we may not have available -// (so far, Panda is only dependent on dx8 API's). -#ifndef DXFILEOBJ_XSkinMeshHeader -// {3CF169CE-FF7C-44ab-93C0-F78F62D172E2} -MY_DEFINE_GUID(DXFILEOBJ_XSkinMeshHeader, -0x3cf169ce, 0xff7c, 0x44ab, 0x93, 0xc0, 0xf7, 0x8f, 0x62, 0xd1, 0x72, 0xe2); -#endif - -#ifndef DXFILEOBJ_SkinWeights -// {6F0D123B-BAD2-4167-A0D0-80224F25FABB} -MY_DEFINE_GUID(DXFILEOBJ_SkinWeights, -0x6f0d123b, 0xbad2, 0x4167, 0xa0, 0xd0, 0x80, 0x22, 0x4f, 0x25, 0xfa, 0xbb); -#endif - - - //////////////////////////////////////////////////////////////////// // Function: XFileToEggConverter::Constructor // Access: Public @@ -61,8 +40,7 @@ XFileToEggConverter:: XFileToEggConverter() { _make_char = false; _frame_rate = 30.0; - _dx_file = NULL; - _dx_file_enum = NULL; + _x_file = new XFile; _dart_node = NULL; } @@ -76,8 +54,7 @@ XFileToEggConverter(const XFileToEggConverter ©) : SomethingToEggConverter(copy), _make_char(copy._make_char) { - _dx_file = NULL; - _dx_file_enum = NULL; + _x_file = new XFile; _dart_node = NULL; } @@ -138,28 +115,15 @@ get_extension() const { //////////////////////////////////////////////////////////////////// bool XFileToEggConverter:: convert_file(const Filename &filename) { - HRESULT hr; - close(); - hr = DirectXFileCreate(&_dx_file); - if (hr != DXFILE_OK) { - nout << "Unable to create X interface.\n"; + + if (!_x_file->read(filename)) { + nout << "Unable to open X file: " << filename << "\n"; return false; } - // Register our templates. - hr = _dx_file->RegisterTemplates(D3DRM_XTEMPLATES, d3drm_xtemplates_length); - if (hr != DXFILE_OK) { - nout << "Unable to register templates.\n"; - return false; - } - - string os_file = filename.to_os_specific(); - hr = _dx_file->CreateEnumObject - ((void *)os_file.c_str(), DXFILELOAD_FROMFILE, &_dx_file_enum); - if (hr != DXFILE_OK) { - nout << "Unable to open X file: " << os_file << "\n"; - return false; + if (_char_name.empty()) { + _char_name = filename.get_basename_wo_extension(); } if (_egg_data->get_coordinate_system() == CS_default) { @@ -195,14 +159,7 @@ convert_file(const Filename &filename) { //////////////////////////////////////////////////////////////////// void XFileToEggConverter:: close() { - if (_dx_file != NULL) { - if (_dx_file_enum != NULL) { - _dx_file_enum->Release(); - _dx_file_enum = NULL; - } - _dx_file->Release(); - _dx_file = NULL; - } + _x_file->clear(); // Clean up all the other stuff. Meshes::const_iterator mi; @@ -210,11 +167,6 @@ close() { delete (*mi); } _meshes.clear(); - - for (mi = _toplevel_meshes.begin(); mi != _toplevel_meshes.end(); ++mi) { - delete (*mi); - } - _toplevel_meshes.clear(); AnimationSets::const_iterator asi; for (asi = _animation_sets.begin(); asi != _animation_sets.end(); ++asi) { @@ -261,7 +213,7 @@ create_unique_material(const EggMaterial ©) { } //////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::find_joint (one parameter) +// Function: XFileToEggConverter::find_joint // Access: Public // Description: This is called by set_animation_frame, for // the purposes of building the frame data for the @@ -273,13 +225,13 @@ find_joint(const string &joint_name) { Joints::iterator ji; ji = _joints.find(joint_name); if (ji != _joints.end()) { - JointDef &joint_def = (*ji).second; - if (joint_def._node == (EggGroup *)NULL) { + EggGroup *joint = (*ji).second; + if (joint == (EggGroup *)NULL) { // An invalid joint detected earlier. return NULL; } - return joint_def._node; + return joint; } // Joint name is unknown. Issue a warning, then insert NULL into @@ -289,69 +241,11 @@ find_joint(const string &joint_name) { xfile_cat.warning() << "Joint name " << joint_name << " in animation data is undefined.\n"; } - _joints[joint_name]._node = NULL; + _joints[joint_name] = NULL; return NULL; } -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::find_joint (two parameters) -// Access: Public -// Description: This is called by XFileMesh::create_polygons(), for -// the purposes of applying skinning to vertices. It -// searches for the joint matching the indicated name, -// and returns it, possibly creating a new joint if the -// requested matrix_offset demands it. Returns NULL if -// the joint name is unknown. -//////////////////////////////////////////////////////////////////// -EggGroup *XFileToEggConverter:: -find_joint(const string &joint_name, const LMatrix4f &matrix_offset) { - return find_joint(joint_name); - /* - Joints::iterator ji; - ji = _joints.find(joint_name); - if (ji != _joints.end()) { - JointDef &joint_def = (*ji).second; - if (joint_def._node == (EggGroup *)NULL) { - // An invalid joint detected earlier. - return NULL; - } - - OffsetJoints::iterator oji = joint_def._offsets.find(matrix_offset); - if (oji != joint_def._offsets.end()) { - // We've previously created a joint for this matrix, so just - // reuse it. - return (*oji).second; - } - - if (!joint_def._offsets.empty()) { - const LMatrix4f &mat = (*joint_def._offsets.begin()).first; - } - - // We need to create a new joint for this matrix. - EggGroup *new_joint = new EggGroup("synth"); - joint_def._node->add_child(new_joint); - - new_joint->set_group_type(EggGroup::GT_joint); - new_joint->set_transform(LCAST(double, matrix_offset)); - joint_def._offsets[matrix_offset] = new_joint; - - return new_joint; - } - - // Joint name is unknown. Issue a warning, then insert NULL into - // the table so we don't get the same warning again with the next - // polygon. - if (_make_char) { - xfile_cat.warning() - << "Joint name " << joint_name << " in animation data is undefined.\n"; - } - _joints[joint_name]._node = NULL; - - return NULL; - */ -} - //////////////////////////////////////////////////////////////////// // Function: XFileToEggConverter::get_toplevel // Access: Private @@ -361,8 +255,26 @@ find_joint(const string &joint_name, const LMatrix4f &matrix_offset) { //////////////////////////////////////////////////////////////////// bool XFileToEggConverter:: get_toplevel() { - HRESULT hr; - LPDIRECTXFILEDATA obj; + int num_objects = _x_file->get_num_objects(); + int i; + + // First, make a pass through the toplevel objects and see if we + // have frames and/or animation. + _any_frames = false; + _any_animation = false; + for (int i = 0; i < num_objects; i++) { + XFileDataNode *child = _x_file->get_object(i); + if (child->is_standard_object("Frame")) { + _any_frames = true; + } else if (child->is_standard_object("AnimationSet")) { + _any_animation = true; + } + } + + // If we have animation, assume we want to convert it as a character. + if (_any_animation) { + _make_char = true; + } EggGroupNode *egg_parent = _egg_data; @@ -375,20 +287,11 @@ get_toplevel() { egg_parent = _dart_node; } - _any_frames = false; - - hr = _dx_file_enum->GetNextDataObject(&obj); - while (hr == DXFILE_OK) { - if (!convert_toplevel_object(obj, egg_parent)) { + // Now go back through and convert the objects. + for (i = 0; i < num_objects; i++) { + if (!convert_toplevel_object(_x_file->get_object(i), egg_parent)) { return false; } - hr = _dx_file_enum->GetNextDataObject(&obj); - } - - if (hr != DXFILEERR_NOMOREOBJECTS) { - xfile_cat.error() - << "Error extracting top-level objects.\n"; - return false; } return true; @@ -401,55 +304,41 @@ get_toplevel() { // any Frames, to the appropriate egg structures. //////////////////////////////////////////////////////////////////// bool XFileToEggConverter:: -convert_toplevel_object(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) { - HRESULT hr; - - // Determine what type of data object we have. - const GUID *type; - hr = obj->GetType(&type); - if (hr != DXFILE_OK) { - xfile_cat.error() - << "Unable to get type of template\n"; - return false; - } - - if (*type == mydef_TID_D3DRMHeader) { +convert_toplevel_object(XFileDataNode *obj, EggGroupNode *egg_parent) { + if (obj->is_standard_object("Header")) { // Quietly ignore headers. - } else if (*type == TID_D3DRMMaterial) { + } else if (obj->is_standard_object("Material")) { // Quietly ignore toplevel materials. These will presumably be // referenced below. - } else if (*type == TID_D3DRMFrame) { - _any_frames = true; + } else if (obj->is_standard_object("Frame")) { if (!convert_frame(obj, egg_parent)) { return false; } - } else if (*type == TID_D3DRMFrameTransformMatrix) { - if (!convert_transform(obj, egg_parent)) { - return false; - } - - } else if (*type == TID_D3DRMAnimationSet) { + } else if (obj->is_standard_object("AnimationSet")) { if (!convert_animation_set(obj)) { return false; } - } else if (*type == TID_D3DRMMesh) { - // Assume a Mesh at the toplevel is just present to define a - // reference that will be included below. Convert it into the - // _toplevel_meshes set, where it will be ignored unless there are - // no frames at all in the file. - if (!convert_mesh(obj, egg_parent, true)) { - return false; + } else if (obj->is_standard_object("Mesh")) { + // If there are any Frames at all in the file, then assume a Mesh + // at the toplevel is just present to define a reference that will + // be included below--so we ignore it here. On the other hand, if + // the file has no Frames, then a Mesh at the toplevel must be + // actual geometry, so convert it now. + if (!_any_frames) { + if (!convert_mesh(obj, egg_parent)) { + return false; + } } } else { if (xfile_cat.is_debug()) { xfile_cat.debug() << "Ignoring toplevel object of unknown type: " - << get_object_name(obj) << "\n"; + << obj->get_template_name() << "\n"; } } @@ -463,79 +352,30 @@ convert_toplevel_object(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) { // structures. //////////////////////////////////////////////////////////////////// bool XFileToEggConverter:: -convert_object(LPDIRECTXFILEOBJECT obj, EggGroupNode *egg_parent) { - HRESULT hr; - LPDIRECTXFILEDATA data_obj; - LPDIRECTXFILEDATAREFERENCE ref_obj; - - // See if the object is a data object. - hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj); - if (hr == DD_OK) { - // It is. - return convert_data_object(data_obj, egg_parent); - } - - // Or maybe it's a reference to a previous object. - hr = obj->QueryInterface(IID_IDirectXFileDataReference, (void **)&ref_obj); - if (hr == DD_OK) { - // It is. - if (ref_obj->Resolve(&data_obj) == DXFILE_OK) { - return convert_data_object(data_obj, egg_parent); - } - } - - // It isn't. - if (xfile_cat.is_debug()) { - xfile_cat.debug() - << "Ignoring object of unknown type: " - << get_object_name(obj) << "\n"; - } - return true; -} - - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_data_object -// Access: Private -// Description: Converts the indicated object to the appropriate egg -// structures. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_data_object(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) { - HRESULT hr; - - // Determine what type of data object we have. - const GUID *type; - hr = obj->GetType(&type); - if (hr != DXFILE_OK) { - xfile_cat.error() - << "Unable to get type of template\n"; - return false; - } - - if (*type == mydef_TID_D3DRMHeader) { +convert_object(XFileDataNode *obj, EggGroupNode *egg_parent) { + if (obj->is_standard_object("Header")) { // Quietly ignore headers. - } else if (*type == TID_D3DRMFrame) { + } else if (obj->is_standard_object("Frame")) { if (!convert_frame(obj, egg_parent)) { return false; } - } else if (*type == TID_D3DRMFrameTransformMatrix) { + } else if (obj->is_standard_object("FrameTransformMatrix")) { if (!convert_transform(obj, egg_parent)) { return false; } - } else if (*type == TID_D3DRMMesh) { - if (!convert_mesh(obj, egg_parent, false)) { + } else if (obj->is_standard_object("Mesh")) { + if (!convert_mesh(obj, egg_parent)) { return false; } } else { if (xfile_cat.is_debug()) { xfile_cat.debug() - << "Ignoring data object of unknown type: " - << get_object_name(obj) << "\n"; + << "Ignoring object of unknown type: " + << obj->get_template_name() << "\n"; } } @@ -549,10 +389,8 @@ convert_data_object(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) { // structures. //////////////////////////////////////////////////////////////////// bool XFileToEggConverter:: -convert_frame(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) { - HRESULT hr; - - string name = get_object_name(obj); +convert_frame(XFileDataNode *obj, EggGroupNode *egg_parent) { + string name = obj->get_name(); EggGroup *group = new EggGroup(name); egg_parent->add_child(group); @@ -563,9 +401,7 @@ convert_frame(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) { group->set_name("unnamed"); } else { - JointDef joint_def; - joint_def._node = group; - bool inserted = _joints.insert(Joints::value_type(name, joint_def)).second; + bool inserted = _joints.insert(Joints::value_type(name, group)).second; if (!inserted) { xfile_cat.warning() << "Nonunique Frame name " << name @@ -575,20 +411,11 @@ convert_frame(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) { } // Now walk through the children of the frame. - LPDIRECTXFILEOBJECT child_obj; - - hr = obj->GetNextObject(&child_obj); - while (hr == DXFILE_OK) { - if (!convert_object(child_obj, group)) { + int num_objects = obj->get_num_objects(); + for (int i = 0; i < num_objects; i++) { + if (!convert_object(obj->get_object(i), group)) { return false; } - hr = obj->GetNextObject(&child_obj); - } - - if (hr != DXFILEERR_NOMOREOBJECTS) { - xfile_cat.error() - << "Error extracting children of frame " << name << ".\n"; - return false; } return true; @@ -604,23 +431,16 @@ convert_frame(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) { // frame. //////////////////////////////////////////////////////////////////// bool XFileToEggConverter:: -convert_transform(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) { - Datagram raw_data; - if (!get_data(obj, raw_data)) { - return false; - } - - DatagramIterator di(raw_data); - LMatrix4f mat; - mat.read_datagram(di); +convert_transform(XFileDataNode *obj, EggGroupNode *egg_parent) { + LMatrix4d mat = (*obj)["frameMatrix"]["matrix"].mat4(); if (egg_parent->is_of_type(EggGroup::get_class_type())) { EggGroup *egg_group = DCAST(EggGroup, egg_parent); - egg_group->set_transform(LCAST(double, mat)); + egg_group->set_transform(mat); } else { xfile_cat.error() - << "Transform " << get_object_name(obj) + << "Transform " << obj->get_name() << " encountered without frame!\n"; } @@ -635,30 +455,17 @@ convert_transform(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) { // be applied to the model within this file. //////////////////////////////////////////////////////////////////// bool XFileToEggConverter:: -convert_animation_set(LPDIRECTXFILEDATA obj) { - HRESULT hr; - +convert_animation_set(XFileDataNode *obj) { XFileAnimationSet *animation_set = new XFileAnimationSet(); - animation_set->set_name(get_object_name(obj)); + animation_set->set_name(obj->get_name()); // Now walk through the children of the set; each one animates a // different joint. - LPDIRECTXFILEOBJECT child_obj; - - hr = obj->GetNextObject(&child_obj); - while (hr == DXFILE_OK) { - if (!convert_animation_set_object(child_obj, *animation_set)) { + int num_objects = obj->get_num_objects(); + for (int i = 0; i < num_objects; i++) { + if (!convert_animation_set_object(obj->get_object(i), *animation_set)) { return false; } - hr = obj->GetNextObject(&child_obj); - } - - if (hr != DXFILEERR_NOMOREOBJECTS) { - xfile_cat.error() - << "Error extracting children of AnimationSet " - << get_object_name(obj) << ".\n"; - delete animation_set; - return false; } _animation_sets.push_back(animation_set); @@ -673,65 +480,18 @@ convert_animation_set(LPDIRECTXFILEDATA obj) { // AnimationSet. //////////////////////////////////////////////////////////////////// bool XFileToEggConverter:: -convert_animation_set_object(LPDIRECTXFILEOBJECT obj, +convert_animation_set_object(XFileDataNode *obj, XFileAnimationSet &animation_set) { - HRESULT hr; - LPDIRECTXFILEDATA data_obj; - LPDIRECTXFILEDATAREFERENCE ref_obj; - - // See if the object is a data object. - hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj); - if (hr == DD_OK) { - // It is. - return convert_animation_set_data_object(data_obj, animation_set); - } - - // Or maybe it's a reference to a previous object. - hr = obj->QueryInterface(IID_IDirectXFileDataReference, (void **)&ref_obj); - if (hr == DD_OK) { - // It is. - if (ref_obj->Resolve(&data_obj) == DXFILE_OK) { - return convert_animation_set_data_object(data_obj, animation_set); - } - } - - // It isn't. - if (xfile_cat.is_debug()) { - xfile_cat.debug() - << "Ignoring animation set object of unknown type: " - << get_object_name(obj) << "\n"; - } - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_animation_set_data_object -// Access: Private -// Description: Converts the indicated data object, a child of a -// AnimationSet. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_animation_set_data_object(LPDIRECTXFILEDATA obj, XFileAnimationSet &animation_set) { - HRESULT hr; - - // Determine what type of data object we have. - const GUID *type; - hr = obj->GetType(&type); - if (hr != DXFILE_OK) { - xfile_cat.error() - << "Unable to get type of template\n"; - return false; - } - - if (*type == TID_D3DRMAnimation) { + if (obj->is_standard_object("Animation")) { if (!convert_animation(obj, animation_set)) { return false; } + } else { if (xfile_cat.is_debug()) { xfile_cat.debug() - << "Ignoring animation set data object of unknown type: " - << get_object_name(obj) << "\n"; + << "Ignoring animation set object of unknown type: " + << obj->get_template_name() << "\n"; } } @@ -744,13 +504,10 @@ convert_animation_set_data_object(LPDIRECTXFILEDATA obj, XFileAnimationSet &anim // Description: Converts the indicated Animation template object. //////////////////////////////////////////////////////////////////// bool XFileToEggConverter:: -convert_animation(LPDIRECTXFILEDATA obj, XFileAnimationSet &animation_set) { - HRESULT hr; - +convert_animation(XFileDataNode *obj, XFileAnimationSet &animation_set) { // Within an Animation template, we expect to find a reference to a // frame, possibly an AnimationOptions object, and one or more // AnimationKey objects. - LPDIRECTXFILEOBJECT child_obj; // First, walk through the list of children, to find the one that is // the frame reference. We need to know this up front so we know @@ -758,41 +515,19 @@ convert_animation(LPDIRECTXFILEDATA obj, XFileAnimationSet &animation_set) { string frame_name; bool got_frame_name = false; - pvector children; - - hr = obj->GetNextObject(&child_obj); - while (hr == DXFILE_OK) { - LPDIRECTXFILEDATAREFERENCE ref_obj; - if (child_obj->QueryInterface(IID_IDirectXFileDataReference, (void **)&ref_obj) == DD_OK) { - // Here's a reference! - LPDIRECTXFILEDATA data_obj; - if (ref_obj->Resolve(&data_obj) == DXFILE_OK) { - const GUID *type; - if (data_obj->GetType(&type) == DXFILE_OK) { - if (*type == TID_D3DRMFrame) { - // Ok, this one is a reference to a frame. Save the name. - frame_name = get_object_name(data_obj); - got_frame_name = true; - } - } - } - } else { - children.push_back(child_obj); + int num_objects = obj->get_num_objects(); + int i; + for (i = 0; i < num_objects; i++) { + XFileDataNode *child = obj->get_object(i); + if (child->is_reference() && child->is_standard_object("Frame")) { + frame_name = child->get_name(); + got_frame_name = true; } - - hr = obj->GetNextObject(&child_obj); - } - - if (hr != DXFILEERR_NOMOREOBJECTS) { - xfile_cat.error() - << "Error extracting children of Animation " - << get_object_name(obj) << ".\n"; - return false; } if (!got_frame_name) { xfile_cat.error() - << "Animation " << get_object_name(obj) + << "Animation " << obj->get_name() << " includes no reference to a frame.\n"; return false; } @@ -800,9 +535,8 @@ convert_animation(LPDIRECTXFILEDATA obj, XFileAnimationSet &animation_set) { FrameData &table = animation_set.create_frame_data(frame_name); // Now go back again and get the actual data. - pvector::iterator ci; - for (ci = children.begin(); ci != children.end(); ++ci) { - if (!convert_animation_object((*ci), frame_name, table)) { + for (i = 0; i < num_objects; i++) { + if (!convert_animation_object(obj->get_object(i), frame_name, table)) { return false; } } @@ -817,61 +551,15 @@ convert_animation(LPDIRECTXFILEDATA obj, XFileAnimationSet &animation_set) { // Animation. //////////////////////////////////////////////////////////////////// bool XFileToEggConverter:: -convert_animation_object(LPDIRECTXFILEOBJECT obj, const string &joint_name, +convert_animation_object(XFileDataNode *obj, const string &joint_name, XFileToEggConverter::FrameData &table) { - HRESULT hr; - LPDIRECTXFILEDATA data_obj; - LPDIRECTXFILEDATAREFERENCE ref_obj; - - // See if the object is a data object. - hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj); - if (hr == DD_OK) { - // It is. - return convert_animation_data_object(data_obj, joint_name, table); - } - - // Or maybe it's a reference to a previous object. - hr = obj->QueryInterface(IID_IDirectXFileDataReference, (void **)&ref_obj); - if (hr == DD_OK) { - // It is. - if (ref_obj->Resolve(&data_obj) == DXFILE_OK) { - return convert_animation_data_object(data_obj, joint_name, table); - } - } - - // It isn't. - if (xfile_cat.is_debug()) { - xfile_cat.debug() - << "Ignoring animation set object of unknown type: " - << get_object_name(obj) << "\n"; - } - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_animation_data_object -// Access: Private -// Description: Converts the indicated data object, a child of a -// Animation. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_animation_data_object(LPDIRECTXFILEDATA obj, const string &joint_name, - XFileToEggConverter::FrameData &table) { - HRESULT hr; - - // Determine what type of data object we have. - const GUID *type; - hr = obj->GetType(&type); - if (hr != DXFILE_OK) { - xfile_cat.error() - << "Unable to get type of template\n"; - return false; - } - - if (*type == TID_D3DRMAnimationOptions) { + if (obj->is_standard_object("AnimationOptions")) { // Quietly ignore AnimationOptions. - } else if (*type == TID_D3DRMAnimationKey) { + } else if (obj->is_standard_object("Frame")) { + // Quietly ignore frames, since we already got the frame name. + + } else if (obj->is_standard_object("AnimationKey")) { if (!convert_animation_key(obj, joint_name, table)) { return false; } @@ -879,8 +567,8 @@ convert_animation_data_object(LPDIRECTXFILEDATA obj, const string &joint_name, } else { if (xfile_cat.is_debug()) { xfile_cat.debug() - << "Ignoring animation set data object of unknown type: " - << get_object_name(obj) << "\n"; + << "Ignoring animation object of unknown type: " + << obj->get_template_name() << "\n"; } } @@ -893,35 +581,21 @@ convert_animation_data_object(LPDIRECTXFILEDATA obj, const string &joint_name, // Description: Converts the indicated AnimationKey template object. //////////////////////////////////////////////////////////////////// bool XFileToEggConverter:: -convert_animation_key(LPDIRECTXFILEDATA obj, const string &joint_name, +convert_animation_key(XFileDataNode *obj, const string &joint_name, XFileToEggConverter::FrameData &table) { - Datagram raw_data; - if (!get_data(obj, raw_data)) { - return false; - } + int key_type = (*obj)["keyType"].i(); + + const XFileDataObject &keys = (*obj)["keys"]; - DatagramIterator di(raw_data); - int key_type = di.get_uint32(); - int nkeys = di.get_uint32(); - - for (int i = 0; i < nkeys; i++) { + for (int i = 0; i < keys.size(); i++) { // We ignore the time value. It seems to be of questionable value // anyway, being of all sorts of crazy scales; and Panda doesn't // support timestamped keyframes anyway. Assume the x file was // generated with one frame per frame of animation, and translate // accordingly. - /*int time =*/ di.get_uint32(); - int nvalues = di.get_uint32(); - pvector values; - values.reserve(nvalues); - for (int j = 0; j < nvalues; j++) { - float value = di.get_float32(); - values.push_back(value); - } - - if (!set_animation_frame(joint_name, table, i, key_type, - &values[0], nvalues)) { + const XFileDataObject &values = keys[i]["tfkeys"]["values"]; + if (!set_animation_frame(joint_name, table, i, key_type, values)) { return false; } } @@ -937,7 +611,7 @@ convert_animation_key(LPDIRECTXFILEDATA obj, const string &joint_name, bool XFileToEggConverter:: set_animation_frame(const string &joint_name, XFileToEggConverter::FrameData &table, int frame, - int key_type, const float *values, int nvalues) { + int key_type, const XFileDataObject &values) { if ((int)table._entries.size() <= frame) { nassertr((int)table._entries.size() == frame, false); table._entries.push_back(XFileAnimationSet::FrameEntry()); @@ -951,36 +625,36 @@ set_animation_frame(const string &joint_name, // Key type 0: rotation. // This appears to be a quaternion. Hope we get the coordinate // system right. - if (nvalues != 4) { + if (values.size() != 4) { xfile_cat.error() << "Incorrect number of values in animation table: " - << nvalues << " for rotation data.\n"; + << values.size() << " for rotation data.\n"; return false; } - frame_entry._rot.set(-values[0], values[1], values[2], values[3]); + frame_entry._rot.invert_from(LQuaterniond(values.vec4())); table._flags |= XFileAnimationSet::FDF_rot; break; case 1: - if (nvalues != 3) { + if (values.size() != 3) { xfile_cat.error() << "Incorrect number of values in animation table: " - << nvalues << " for scale data.\n"; + << values.size() << " for scale data.\n"; return false; } - frame_entry._scale.set(values[0], values[1], values[2]); + frame_entry._scale = values.vec3(); table._flags |= XFileAnimationSet::FDF_scale; break; case 2: // Key type 2: position - if (nvalues != 3) { + if (values.size() != 3) { xfile_cat.error() << "Incorrect number of values in animation table: " - << nvalues << " for position data.\n"; + << values.size() << " for position data.\n"; return false; } - frame_entry._trans.set(values[0], values[1], values[2]); + frame_entry._trans = values.vec3(); table._flags |= XFileAnimationSet::FDF_trans; break; @@ -992,16 +666,13 @@ set_animation_frame(const string &joint_name, case 4: // Key type 4: full matrix - if (nvalues != 16) { + if (values.size() != 16) { xfile_cat.error() << "Incorrect number of values in animation table: " - << nvalues << " for matrix data.\n"; + << values.size() << " for matrix data.\n"; return false; } - frame_entry._mat.set(values[0], values[1], values[2], values[3], - values[4], values[5], values[6], values[7], - values[8], values[9], values[10], values[11], - values[12], values[13], values[14], values[15]); + frame_entry._mat = values.mat4(); table._flags |= XFileAnimationSet::FDF_mat; break; @@ -1021,470 +692,17 @@ set_animation_frame(const string &joint_name, // structures. //////////////////////////////////////////////////////////////////// bool XFileToEggConverter:: -convert_mesh(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent, - bool is_toplevel) { - HRESULT hr; - - Datagram raw_data; - if (!get_data(obj, raw_data)) { - return false; - } - +convert_mesh(XFileDataNode *obj, EggGroupNode *egg_parent) { XFileMesh *mesh = new XFileMesh(_egg_data->get_coordinate_system()); - mesh->set_name(get_object_name(obj)); + mesh->set_name(obj->get_name()); mesh->set_egg_parent(egg_parent); - if (!mesh->read_mesh_data(raw_data)) { + if (!mesh->fill_mesh(obj)) { delete mesh; return false; } - // Now process all the child objects of the mesh. - LPDIRECTXFILEOBJECT child_obj; - - hr = obj->GetNextObject(&child_obj); - while (hr == DXFILE_OK) { - if (!convert_mesh_object(child_obj, *mesh)) { - return false; - } - hr = obj->GetNextObject(&child_obj); - } - - if (hr != DXFILEERR_NOMOREOBJECTS) { - xfile_cat.error() - << "Error extracting children of mesh " << get_object_name(obj) - << ".\n"; - delete mesh; - return false; - } - - if (is_toplevel) { - _toplevel_meshes.push_back(mesh); - } else { - _meshes.push_back(mesh); - } - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_mesh_object -// Access: Private -// Description: Converts the indicated object, a child of a Mesh, to -// the appropriate egg structures. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_mesh_object(LPDIRECTXFILEOBJECT obj, XFileMesh &mesh) { - HRESULT hr; - LPDIRECTXFILEDATA data_obj; - LPDIRECTXFILEDATAREFERENCE ref_obj; - - // See if the object is a data object. - hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj); - if (hr == DD_OK) { - // It is. - return convert_mesh_data_object(data_obj, mesh); - } - - // Or maybe it's a reference to a previous object. - hr = obj->QueryInterface(IID_IDirectXFileDataReference, (void **)&ref_obj); - if (hr == DD_OK) { - // It is. - if (ref_obj->Resolve(&data_obj) == DXFILE_OK) { - return convert_mesh_data_object(data_obj, mesh); - } - } - - // It isn't. - if (xfile_cat.is_debug()) { - xfile_cat.debug() - << "Ignoring mesh object of unknown type: " - << get_object_name(obj) << "\n"; - } - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_mesh_data_object -// Access: Private -// Description: Converts the indicated data object, a child of a -// Mesh, to the appropriate egg structures. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_mesh_data_object(LPDIRECTXFILEDATA obj, XFileMesh &mesh) { - HRESULT hr; - - // Determine what type of data object we have. - const GUID *type; - hr = obj->GetType(&type); - if (hr != DXFILE_OK) { - xfile_cat.error() - << "Unable to get type of template\n"; - return false; - } - - if (*type == TID_D3DRMMeshNormals) { - if (!convert_mesh_normals(obj, mesh)) { - return false; - } - - } else if (*type == TID_D3DRMMeshVertexColors) { - if (!convert_mesh_colors(obj, mesh)) { - return false; - } - - } else if (*type == TID_D3DRMMeshTextureCoords) { - if (!convert_mesh_uvs(obj, mesh)) { - return false; - } - - } else if (*type == TID_D3DRMMeshMaterialList) { - if (!convert_mesh_material_list(obj, mesh)) { - return false; - } - - } else if (*type == DXFILEOBJ_XSkinMeshHeader) { - // Quietly ignore a skin mesh header. - - } else if (*type == DXFILEOBJ_SkinWeights) { - if (!convert_skin_weights(obj, mesh)) { - return false; - } - - } else { - if (xfile_cat.is_debug()) { - xfile_cat.debug() - << "Ignoring mesh data object of unknown type: " - << get_object_name(obj) << "\n"; - } - } - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_mesh_normals -// Access: Private -// Description: Converts the indicated MeshNormals template -// object. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_mesh_normals(LPDIRECTXFILEDATA obj, XFileMesh &mesh) { - Datagram raw_data; - if (!get_data(obj, raw_data)) { - return false; - } - - if (!mesh.read_normal_data(raw_data)) { - return false; - } - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_mesh_colors -// Access: Private -// Description: Converts the indicated MeshVertexColors template -// object. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_mesh_colors(LPDIRECTXFILEDATA obj, XFileMesh &mesh) { - Datagram raw_data; - if (!get_data(obj, raw_data)) { - return false; - } - - if (!mesh.read_color_data(raw_data)) { - return false; - } - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_mesh_uvs -// Access: Private -// Description: Converts the indicated MeshTextureCoords template -// object. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_mesh_uvs(LPDIRECTXFILEDATA obj, XFileMesh &mesh) { - Datagram raw_data; - if (!get_data(obj, raw_data)) { - return false; - } - - if (!mesh.read_uv_data(raw_data)) { - return false; - } - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_skin_weights -// Access: Private -// Description: Converts the indicated SkinWeights template -// object. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_skin_weights(LPDIRECTXFILEDATA obj, XFileMesh &mesh) { - Datagram raw_data; - if (!get_data(obj, raw_data)) { - return false; - } - - if (!mesh.read_skin_weights_data(raw_data)) { - return false; - } - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_mesh_material_list -// Access: Private -// Description: Converts the indicated MeshMaterialList template -// object. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_mesh_material_list(LPDIRECTXFILEDATA obj, XFileMesh &mesh) { - HRESULT hr; - - Datagram raw_data; - if (!get_data(obj, raw_data)) { - return false; - } - - if (!mesh.read_material_list_data(raw_data)) { - return false; - } - - // Now we need to process the children of the material list. These - // will be the materials. - LPDIRECTXFILEOBJECT child_obj; - - hr = obj->GetNextObject(&child_obj); - while (hr == DXFILE_OK) { - if (!convert_material_list_object(child_obj, mesh)) { - return false; - } - hr = obj->GetNextObject(&child_obj); - } - - if (hr != DXFILEERR_NOMOREOBJECTS) { - xfile_cat.error() - << "Error extracting children of MeshMaterialList " - << get_object_name(obj) << ".\n"; - return false; - } - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_material_list_object -// Access: Private -// Description: Converts the indicated object, a child of a -// MeshMaterialList. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_material_list_object(LPDIRECTXFILEOBJECT obj, XFileMesh &mesh) { - HRESULT hr; - LPDIRECTXFILEDATA data_obj; - LPDIRECTXFILEDATAREFERENCE ref_obj; - - // See if the object is a data object. - hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj); - if (hr == DD_OK) { - // It is. - return convert_material_list_data_object(data_obj, mesh); - } - - // Or maybe it's a reference to a previous object. - hr = obj->QueryInterface(IID_IDirectXFileDataReference, (void **)&ref_obj); - if (hr == DD_OK) { - // It is. - if (ref_obj->Resolve(&data_obj) == DXFILE_OK) { - return convert_material_list_data_object(data_obj, mesh); - } - } - - // It isn't. - if (xfile_cat.is_debug()) { - xfile_cat.debug() - << "Ignoring material list object of unknown type: " - << get_object_name(obj) << "\n"; - } - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_material_list_data_object -// Access: Private -// Description: Converts the indicated data object, a child of a -// MeshMaterialList. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_material_list_data_object(LPDIRECTXFILEDATA obj, XFileMesh &mesh) { - HRESULT hr; - - // Determine what type of data object we have. - const GUID *type; - hr = obj->GetType(&type); - if (hr != DXFILE_OK) { - xfile_cat.error() - << "Unable to get type of template\n"; - return false; - } - - if (*type == TID_D3DRMMaterial) { - if (!convert_material(obj, mesh)) { - return false; - } - } else { - if (xfile_cat.is_debug()) { - xfile_cat.debug() - << "Ignoring material list data object of unknown type: " - << get_object_name(obj) << "\n"; - } - } - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_material -// Access: Private -// Description: Converts the indicated Material template object. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_material(LPDIRECTXFILEDATA obj, XFileMesh &mesh) { - HRESULT hr; - - Datagram raw_data; - if (!get_data(obj, raw_data)) { - return false; - } - - XFileMaterial *material = new XFileMaterial; - - if (!material->read_material_data(raw_data)) { - delete material; - return false; - } - - mesh.add_material(material); - - // Now we need to process the children of the material. There - // should only be one, and it will be a texture. - LPDIRECTXFILEOBJECT child_obj; - - hr = obj->GetNextObject(&child_obj); - while (hr == DXFILE_OK) { - if (!convert_material_object(child_obj, *material)) { - return false; - } - hr = obj->GetNextObject(&child_obj); - } - - if (hr != DXFILEERR_NOMOREOBJECTS) { - xfile_cat.error() - << "Error extracting children of Material " - << get_object_name(obj) << ".\n"; - return false; - } - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_material_object -// Access: Private -// Description: Converts the indicated object, a child of a -// Material. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_material_object(LPDIRECTXFILEOBJECT obj, XFileMaterial &material) { - HRESULT hr; - LPDIRECTXFILEDATA data_obj; - LPDIRECTXFILEDATAREFERENCE ref_obj; - - // See if the object is a data object. - hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj); - if (hr == DD_OK) { - // It is. - return convert_material_data_object(data_obj, material); - } - - // Or maybe it's a reference to a previous object. - hr = obj->QueryInterface(IID_IDirectXFileDataReference, (void **)&ref_obj); - if (hr == DD_OK) { - // It is. - if (ref_obj->Resolve(&data_obj) == DXFILE_OK) { - return convert_material_data_object(data_obj, material); - } - } - - // It isn't. - if (xfile_cat.is_debug()) { - xfile_cat.debug() - << "Ignoring material object of unknown type: " - << get_object_name(obj) << "\n"; - } - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_material_data_object -// Access: Private -// Description: Converts the indicated data object, a child of a -// Material. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_material_data_object(LPDIRECTXFILEDATA obj, XFileMaterial &material) { - HRESULT hr; - - // Determine what type of data object we have. - const GUID *type; - hr = obj->GetType(&type); - if (hr != DXFILE_OK) { - xfile_cat.error() - << "Unable to get type of template\n"; - return false; - } - - if (*type == TID_D3DRMTextureFilename) { - if (!convert_texture(obj, material)) { - return false; - } - } else { - if (xfile_cat.is_debug()) { - xfile_cat.debug() - << "Ignoring material data object of unknown type: " - << get_object_name(obj) << "\n"; - } - } - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::convert_texture -// Access: Private -// Description: Converts the indicated TextureFilename template object. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -convert_texture(LPDIRECTXFILEDATA obj, XFileMaterial &material) { - Datagram raw_data; - if (!get_data(obj, raw_data)) { - return false; - } - - if (!material.read_texture_data(raw_data)) { - return false; - } + _meshes.push_back(mesh); return true; } @@ -1508,16 +726,6 @@ create_polygons() { } _meshes.clear(); - for (mi = _toplevel_meshes.begin(); mi != _toplevel_meshes.end(); ++mi) { - if (!_any_frames) { - if (!(*mi)->create_polygons(this)) { - okflag = false; - } - } - delete (*mi); - } - _toplevel_meshes.clear(); - return okflag; } @@ -1531,11 +739,6 @@ bool XFileToEggConverter:: create_hierarchy() { bool okflag = true; - if (!_make_char && !_animation_sets.empty()) { - xfile_cat.warning() - << "Ignoring animation data without -a.\n"; - } - AnimationSets::const_iterator asi; for (asi = _animation_sets.begin(); asi != _animation_sets.end(); ++asi) { if (_make_char) { @@ -1549,57 +752,3 @@ create_hierarchy() { return okflag; } - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::get_object_name -// Access: Private -// Description: Returns the name of the indicated object. -//////////////////////////////////////////////////////////////////// -string XFileToEggConverter:: -get_object_name(LPDIRECTXFILEOBJECT obj) { - HRESULT hr; - - DWORD length = 0; - obj->GetName(NULL, &length); - - if (length == 0) { - return string(); - } - - char *buffer = new char[length]; - hr = obj->GetName(buffer, &length); - - string result; - if (hr != DXFILE_OK) { - xfile_cat.error() - << "Unable to get object name.\n"; - } else { - result = buffer; - } - - delete[] buffer; - return result; -} - -//////////////////////////////////////////////////////////////////// -// Function: XFileToEggConverter::get_data -// Access: Private -// Description: Extracts out the raw data for the indicated object. -//////////////////////////////////////////////////////////////////// -bool XFileToEggConverter:: -get_data(LPDIRECTXFILEDATA obj, Datagram &raw_data) { - HRESULT hr; - DWORD length; - void *data; - hr = obj->GetData(NULL, &length, &data); - if (hr != DXFILE_OK) { - xfile_cat.error() - << "Unable to get data for " << get_object_name(obj) << "\n"; - return false; - } - - raw_data.clear(); - raw_data.append_data(data, length); - - return true; -} diff --git a/pandatool/src/xfileegg/xFileToEggConverter.h b/pandatool/src/xfileegg/xFileToEggConverter.h index b84f3a1f14..5723cb1959 100644 --- a/pandatool/src/xfileegg/xFileToEggConverter.h +++ b/pandatool/src/xfileegg/xFileToEggConverter.h @@ -21,19 +21,14 @@ #include "pandatoolbase.h" #include "xFileAnimationSet.h" +#include "xFile.h" #include "somethingToEggConverter.h" #include "eggTextureCollection.h" #include "eggMaterialCollection.h" #include "pvector.h" #include "pmap.h" #include "luse.h" - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#undef WIN32_LEAN_AND_MEAN +#include "pointerTo.h" class Datagram; class XFileMesh; @@ -42,6 +37,7 @@ class EggGroup; class EggGroupNode; class EggTexture; class EggMaterial; +class XFileDataObject; //////////////////////////////////////////////////////////////////// // Class : XFileToEggConverter @@ -66,8 +62,6 @@ public: EggTexture *create_unique_texture(const EggTexture ©); EggMaterial *create_unique_material(const EggMaterial ©); EggGroup *find_joint(const string &joint_name); - EggGroup *find_joint(const string &joint_name, - const LMatrix4f &matrix_offset); public: bool _make_char; @@ -78,77 +72,39 @@ private: typedef XFileAnimationSet::FrameData FrameData; bool get_toplevel(); - bool convert_toplevel_object(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent); - bool convert_object(LPDIRECTXFILEOBJECT obj, EggGroupNode *egg_parent); - bool convert_data_object(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent); - bool convert_frame(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent); - bool convert_transform(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent); - bool convert_animation_set(LPDIRECTXFILEDATA obj); - bool convert_animation_set_object(LPDIRECTXFILEOBJECT obj, + bool convert_toplevel_object(XFileDataNode *obj, EggGroupNode *egg_parent); + bool convert_object(XFileDataNode *obj, EggGroupNode *egg_parent); + bool convert_frame(XFileDataNode *obj, EggGroupNode *egg_parent); + bool convert_transform(XFileDataNode *obj, EggGroupNode *egg_parent); + bool convert_animation_set(XFileDataNode *obj); + bool convert_animation_set_object(XFileDataNode *obj, XFileAnimationSet &animation_set); - bool convert_animation_set_data_object(LPDIRECTXFILEDATA obj, - XFileAnimationSet &animation_set); - bool convert_animation(LPDIRECTXFILEDATA obj, + bool convert_animation(XFileDataNode *obj, XFileAnimationSet &animation_set); - bool convert_animation_object(LPDIRECTXFILEOBJECT obj, + bool convert_animation_object(XFileDataNode *obj, const string &joint_name, FrameData &table); - bool convert_animation_data_object(LPDIRECTXFILEDATA obj, - const string &joint_name, - FrameData &table); - bool convert_animation_key(LPDIRECTXFILEDATA obj, const string &joint_name, + bool convert_animation_key(XFileDataNode *obj, const string &joint_name, FrameData &table); bool set_animation_frame(const string &joint_name, FrameData &table, int frame, int key_type, - const float *values, int nvalues); - bool convert_mesh(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent, - bool is_toplevel); - - bool convert_mesh_object(LPDIRECTXFILEOBJECT obj, XFileMesh &mesh); - bool convert_mesh_data_object(LPDIRECTXFILEDATA obj, XFileMesh &mesh); - bool convert_mesh_normals(LPDIRECTXFILEDATA obj, XFileMesh &mesh); - bool convert_mesh_colors(LPDIRECTXFILEDATA obj, XFileMesh &mesh); - bool convert_mesh_uvs(LPDIRECTXFILEDATA obj, XFileMesh &mesh); - bool convert_skin_weights(LPDIRECTXFILEDATA obj, XFileMesh &mesh); - bool convert_mesh_material_list(LPDIRECTXFILEDATA obj, XFileMesh &mesh); - bool convert_material_list_object(LPDIRECTXFILEOBJECT obj, XFileMesh &mesh); - bool convert_material_list_data_object(LPDIRECTXFILEDATA obj, XFileMesh &mesh); - bool convert_material(LPDIRECTXFILEDATA obj, XFileMesh &mesh); - bool convert_material_object(LPDIRECTXFILEOBJECT obj, XFileMaterial &material); - bool convert_material_data_object(LPDIRECTXFILEDATA obj, XFileMaterial &material); - bool convert_texture(LPDIRECTXFILEDATA obj, XFileMaterial &material); + const XFileDataObject &values); + bool convert_mesh(XFileDataNode *obj, EggGroupNode *egg_parent); bool create_polygons(); bool create_hierarchy(); - string get_object_name(LPDIRECTXFILEOBJECT obj); - bool get_data(LPDIRECTXFILEDATA obj, Datagram &raw_data); - - LPDIRECTXFILE _dx_file; - LPDIRECTXFILEENUMOBJECT _dx_file_enum; + PT(XFile) _x_file; bool _any_frames; + bool _any_animation; typedef pvector Meshes; Meshes _meshes; - Meshes _toplevel_meshes; typedef pvector AnimationSets; AnimationSets _animation_sets; - - typedef pmap OffsetJoints; - - // A joint definition consists of the pointer to the EggGroup that - // represents the actual joint, plus a table of synthetic joints - // that were created for each animation set's offset matrix (we need - // to create a different joint to apply each unique offset matrix in - // an animation set). - class JointDef { - public: - EggGroup *_node; - OffsetJoints _offsets; - }; - typedef pmap Joints; + typedef pmap Joints; Joints _joints; EggGroup *_dart_node; diff --git a/pandatool/src/xfileegg/xFileVertex.cxx b/pandatool/src/xfileegg/xFileVertex.cxx index 4d4de93d32..c2a8c79f92 100644 --- a/pandatool/src/xfileegg/xFileVertex.cxx +++ b/pandatool/src/xfileegg/xFileVertex.cxx @@ -32,7 +32,7 @@ XFileVertex() { _has_uv = false; _point.set(0.0, 0.0, 0.0); _uv.set(0.0, 0.0); - _color.set(1.0, 1.0, 1.0, 1.0); + _color.set(1.0f, 1.0f, 1.0f, 1.0f); } //////////////////////////////////////////////////////////////////// @@ -53,7 +53,7 @@ set_from_egg(EggVertex *egg_vertex, EggPrimitive *egg_prim) { pos = pos * egg_prim->get_vertex_to_node(); } - _point = LCAST(float, pos); + _point = pos; if (egg_vertex->has_uv()) { TexCoordd uv = egg_vertex->get_uv(); diff --git a/pandatool/src/xfileegg/xFileVertex.h b/pandatool/src/xfileegg/xFileVertex.h index 6853ead0dd..9a8e691ec5 100644 --- a/pandatool/src/xfileegg/xFileVertex.h +++ b/pandatool/src/xfileegg/xFileVertex.h @@ -36,8 +36,8 @@ public: void set_from_egg(EggVertex *egg_vertex, EggPrimitive *egg_poly); int compare_to(const XFileVertex &other) const; - Vertexf _point; - TexCoordf _uv; + Vertexd _point; + TexCoordd _uv; Colorf _color; bool _has_color; bool _has_uv; diff --git a/pandatool/src/xfileegg/xfileegg_composite1.cxx b/pandatool/src/xfileegg/xfileegg_composite1.cxx index cbb82ac6a5..d87e0f5b75 100644 --- a/pandatool/src/xfileegg/xfileegg_composite1.cxx +++ b/pandatool/src/xfileegg/xfileegg_composite1.cxx @@ -5,7 +5,6 @@ #include "xFileMaterial.cxx" #include "xFileMesh.cxx" #include "xFileNormal.cxx" -#include "xFileTemplates.cxx" #include "xFileToEggConverter.cxx" #include "xFileVertex.cxx" diff --git a/pandatool/src/xfileprogs/Sources.pp b/pandatool/src/xfileprogs/Sources.pp index cd719b66bb..b6c3035c57 100644 --- a/pandatool/src/xfileprogs/Sources.pp +++ b/pandatool/src/xfileprogs/Sources.pp @@ -1,10 +1,3 @@ - -// The .x converter takes advantage of the DirectX API's; therefore, -// it can only be built if we have DX available (and therefore it only -// builds on Windows--sorry). -#define BUILD_DIRECTORY $[HAVE_DX] -#define USE_PACKAGES dx - #begin bin_target #define TARGET egg2x #define LOCAL_LIBS xfileegg xfile eggbase progbase pandatoolbase @@ -14,9 +7,6 @@ express:c pandaexpress:m \ dtoolconfig dtool pystub \ - #define WIN_SYS_LIBS \ - d3dxof.lib dxguid.lib d3d8.lib d3dx8.lib dxerr8.lib - #define SOURCES \ eggToX.cxx eggToX.h @@ -31,10 +21,21 @@ express:c pandaexpress:m \ dtoolconfig dtool pystub \ - #define WIN_SYS_LIBS \ - d3dxof.lib dxguid.lib d3d8.lib d3dx8.lib dxerr8.lib - #define SOURCES \ xFileToEgg.cxx xFileToEgg.h #end bin_target + +#begin bin_target + #define TARGET x-trans + #define LOCAL_LIBS \ + progbase xfile + #define OTHER_LIBS \ + linmath:c panda:m \ + express:c pandaexpress:m \ + dtoolutil:c dtoolbase:c dconfig:c dtoolconfig:m dtool:m pystub + + #define SOURCES \ + xFileTrans.cxx xFileTrans.h + +#end bin_target diff --git a/pandatool/src/xfile/xFileTrans.cxx b/pandatool/src/xfileprogs/xFileTrans.cxx similarity index 97% rename from pandatool/src/xfile/xFileTrans.cxx rename to pandatool/src/xfileprogs/xFileTrans.cxx index ebb745bd15..e589092cbd 100644 --- a/pandatool/src/xfile/xFileTrans.cxx +++ b/pandatool/src/xfileprogs/xFileTrans.cxx @@ -26,7 +26,7 @@ //////////////////////////////////////////////////////////////////// XFileTrans:: XFileTrans() : - WithOutputFile(true, true, false) + WithOutputFile(true, false, true) { // Indicate the extension name we expect the user to supply for // output files. @@ -38,7 +38,6 @@ XFileTrans() : "debugging the X file parser that is part of the Pandatool library."); clear_runlines(); - add_runline("[opts] input.x > output.x"); add_runline("[opts] input.x output.x"); add_runline("[opts] -o output.x input.x"); diff --git a/pandatool/src/xfile/xFileTrans.h b/pandatool/src/xfileprogs/xFileTrans.h similarity index 100% rename from pandatool/src/xfile/xFileTrans.h rename to pandatool/src/xfileprogs/xFileTrans.h