x2egg now uses native parser

This commit is contained in:
David Rose 2004-10-13 21:39:35 +00:00
parent 209c02fc6e
commit fc74bc81f0
41 changed files with 933 additions and 1523 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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;

View File

@ -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]);
}

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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];
}

View File

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

View File

@ -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"

View File

@ -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

View File

@ -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;

View File

@ -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"

View File

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

View File

@ -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

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;
};

View File

@ -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 <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);

View File

@ -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 <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 Load Diff

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -5,7 +5,6 @@
#include "xFileMaterial.cxx"
#include "xFileMesh.cxx"
#include "xFileNormal.cxx"
#include "xFileTemplates.cxx"
#include "xFileToEggConverter.cxx"
#include "xFileVertex.cxx"

View File

@ -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

View File

@ -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");