Browse Source

x2egg now uses native parser

David Rose 21 years ago
parent
commit
fc74bc81f0
41 changed files with 931 additions and 1452 deletions
  1. 4 1
      pandatool/src/progbase/withOutputFile.cxx
  2. 0 5
      pandatool/src/ptloader/Sources.pp
  3. 0 5
      pandatool/src/ptloader/config_ptloader.cxx
  4. 0 14
      pandatool/src/xfile/Sources.pp
  5. 5 6
      pandatool/src/xfile/xFileDataDef.cxx
  6. 12 0
      pandatool/src/xfile/xFileDataNode.I
  7. 47 0
      pandatool/src/xfile/xFileDataNode.cxx
  8. 5 0
      pandatool/src/xfile/xFileDataNode.h
  9. 32 4
      pandatool/src/xfile/xFileDataNodeReference.cxx
  10. 3 2
      pandatool/src/xfile/xFileDataNodeReference.h
  11. 0 18
      pandatool/src/xfile/xFileDataNodeTemplate.cxx
  12. 0 2
      pandatool/src/xfile/xFileDataNodeTemplate.h
  13. 200 2
      pandatool/src/xfile/xFileDataObject.I
  14. 64 14
      pandatool/src/xfile/xFileDataObject.cxx
  15. 19 0
      pandatool/src/xfile/xFileDataObject.h
  16. 31 2
      pandatool/src/xfile/xFileNode.I
  17. 74 4
      pandatool/src/xfile/xFileNode.cxx
  18. 12 0
      pandatool/src/xfile/xFileNode.h
  19. 18 0
      pandatool/src/xfile/xFileTemplate.cxx
  20. 2 0
      pandatool/src/xfile/xFileTemplate.h
  21. 52 50
      pandatool/src/xfile/xParser.cxx.prebuilt
  22. 1 1
      pandatool/src/xfile/xParser.yxx
  23. 2 12
      pandatool/src/xfileegg/Sources.pp
  24. 0 1
      pandatool/src/xfileegg/xFileAnimationSet.cxx
  25. 1 55
      pandatool/src/xfileegg/xFileMaker.cxx
  26. 25 45
      pandatool/src/xfileegg/xFileMaterial.cxx
  27. 2 3
      pandatool/src/xfileegg/xFileMaterial.h
  28. 151 124
      pandatool/src/xfileegg/xFileMesh.cxx
  29. 9 7
      pandatool/src/xfileegg/xFileMesh.h
  30. 1 1
      pandatool/src/xfileegg/xFileNormal.cxx
  31. 1 1
      pandatool/src/xfileegg/xFileNormal.h
  32. 0 34
      pandatool/src/xfileegg/xFileTemplates.cxx
  33. 0 54
      pandatool/src/xfileegg/xFileTemplates.h
  34. 122 904
      pandatool/src/xfileegg/xFileToEggConverter.cxx
  35. 17 61
      pandatool/src/xfileegg/xFileToEggConverter.h
  36. 2 2
      pandatool/src/xfileegg/xFileVertex.cxx
  37. 2 2
      pandatool/src/xfileegg/xFileVertex.h
  38. 0 1
      pandatool/src/xfileegg/xfileegg_composite1.cxx
  39. 14 13
      pandatool/src/xfileprogs/Sources.pp
  40. 1 2
      pandatool/src/xfileprogs/xFileTrans.cxx
  41. 0 0
      pandatool/src/xfileprogs/xFileTrans.h

+ 4 - 1
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 {

+ 0 - 5
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

+ 0 - 5
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

+ 0 - 14
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

+ 5 - 6
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);
     }

+ 12 - 0
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();
+}
+

+ 47 - 0
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();
+}

+ 5 - 0
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;

+ 32 - 4
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]);
 }

+ 3 - 2
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;

+ 0 - 18
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

+ 0 - 2
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;

+ 200 - 2
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

+ 64 - 14
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;
 }

+ 19 - 0
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);

+ 31 - 2
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];
+}

+ 74 - 4
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 += "_";
+      }
     }
   }
 

+ 12 - 0
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<XFileDataNode *> Objects;
+  Objects _objects;
 
   typedef pmap<string, int> ChildrenByName;
   ChildrenByName _children_by_name;
@@ -125,6 +135,8 @@ public:
 
 private:
   static TypeHandle _type_handle;
+
+  friend class XFileDataNodeReference;
 };
 
 #include "xFileNode.I"

+ 18 - 0
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

+ 2 - 0
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;
 

+ 52 - 50
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"

+ 1 - 1
pandatool/src/xfile/xParser.yxx

@@ -357,7 +357,7 @@ object:
 	;
 
 data_parts_list:
-        data_part
+        empty
         | data_parts_list data_part
         ;
 

+ 2 - 12
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

+ 0 - 1
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) {

+ 1 - 55
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;
 }

+ 25 - 45
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;
-}

+ 2 - 3
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;

+ 151 - 124
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->_color = LCAST(float, vertexColors[i]["indexColor"].vec4());
     vertex->_has_color = true;
   }
 
-  if (di.get_remaining_size() != 0) {
-    xfile_cat.warning()
-      << "Ignoring " << di.get_remaining_size()
-      << " trailing MeshVertexColors.\n";
-  }
-
   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();
+
+  const XFileDataObject &vertexIndices = (*obj)["vertexIndices"];
+  const XFileDataObject &weights = (*obj)["weights"];
 
-  int num_weights = di.get_int32();
+  if (weights.size() != vertexIndices.size()) {
+    xfile_cat.error()
+      << "Inconsistent number of vertices in SkinWeights.\n";
+    return false;
+  }
 
-  vector_int vindices;
-  vindices.reserve(num_weights);
+  // 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);
-  }
-
-  // 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;
+    data._weight_map[vindex] = 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;

+ 9 - 7
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<XFileVertex *> Vertices;
@@ -104,7 +106,7 @@ private:
   public:
     string _joint_name;
     WeightMap _weight_map;
-    LMatrix4f _matrix_offset;
+    LMatrix4d _matrix_offset;
   };
   typedef pvector<SkinWeightsData> SkinWeights;
   SkinWeights _skin_weights;

+ 1 - 1
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;
   }
 }

+ 1 - 1
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;
 };
 

+ 0 - 34
pandatool/src/xfileegg/xFileTemplates.cxx

@@ -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
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#include "xFileTemplates.h"
-
-// This must be included only in exactly one .cxx file, since
-// including defines the structure!
-#include <rmxftmpl.h>
-
-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);

+ 0 - 54
pandatool/src/xfileegg/xFileTemplates.h

@@ -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
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#ifndef XFILETEMPLATES_H
-#define XFILETEMPLATES_H
-
-#include "pandatoolbase.h"
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <d3dx.h>
-#include <dxfile.h>
-#include <rmxfguid.h>
-#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
-

File diff suppressed because it is too large
+ 122 - 904
pandatool/src/xfileegg/xFileToEggConverter.cxx


+ 17 - 61
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 <windows.h>
-#include <d3dx.h>
-#include <dxfile.h>
-#include <rmxfguid.h>
-#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 &copy);
   EggMaterial *create_unique_material(const EggMaterial &copy);
   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<XFileMesh *> Meshes;
   Meshes _meshes;
-  Meshes _toplevel_meshes;
 
   typedef pvector<XFileAnimationSet *> AnimationSets;
   AnimationSets _animation_sets;
-
-  typedef pmap<LMatrix4f, EggGroup *> 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<string, JointDef> Joints;
+  typedef pmap<string, EggGroup *> Joints;
   Joints _joints;
 
   EggGroup *_dart_node;

+ 2 - 2
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();

+ 2 - 2
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;

+ 0 - 1
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"
 

+ 14 - 13
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

+ 1 - 2
pandatool/src/xfile/xFileTrans.cxx → 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");
 

+ 0 - 0
pandatool/src/xfile/xFileTrans.h → pandatool/src/xfileprogs/xFileTrans.h


Some files were not shown because too many files changed in this diff