egg2x now uses native parser

This commit is contained in:
David Rose 2004-10-13 01:03:44 +00:00
parent b9b7ddec00
commit bcbe9bb30c
26 changed files with 1051 additions and 630 deletions

View File

@ -244,6 +244,30 @@ find_template(const WindowsGuid &guid) const {
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: XFile::find_standard_template
// Access: Public, Static
// Description: Returns the standard template associated with the
// indicated name, if any, or NULL if none.
////////////////////////////////////////////////////////////////////
XFileTemplate *XFile::
find_standard_template(const string &name) {
const XFile *standard_templates = get_standard_templates();
return standard_templates->find_template(name);
}
////////////////////////////////////////////////////////////////////
// Function: XFile::find_standard_template
// Access: Public, Static
// Description: Returns the template associated with the indicated
// GUID, if any, or NULL if none.
////////////////////////////////////////////////////////////////////
XFileTemplate *XFile::
find_standard_template(const WindowsGuid &guid) {
const XFile *standard_templates = get_standard_templates();
return standard_templates->find_template(guid);
}
////////////////////////////////////////////////////////////////////
// Function: XFile::find_data_object
// Access: Public

View File

@ -21,6 +21,7 @@
#include "pandatoolbase.h"
#include "xFileNode.h"
#include "xFileDataNode.h"
#include "windowsGuid.h"
#include "filename.h"
#include "pmap.h"
@ -51,6 +52,9 @@ public:
XFileTemplate *find_template(const string &name) const;
XFileTemplate *find_template(const WindowsGuid &guid) const;
static XFileTemplate *find_standard_template(const string &name);
static XFileTemplate *find_standard_template(const WindowsGuid &guid);
XFileDataNodeTemplate *find_data_object(const string &name) const;
XFileDataNodeTemplate *find_data_object(const WindowsGuid &guid) const;

View File

@ -208,6 +208,51 @@ repack_data(XFileDataObject *object,
prev_data, index, sub_index);
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::fill_zero_data
// Access: Public, Virtual
// Description: This is similar to repack_data(), except it is used
// to fill the initial values for a newly-created
// template object to zero.
////////////////////////////////////////////////////////////////////
bool XFileDataDef::
fill_zero_data(XFileDataObject *object) const {
PT(XFileDataObject) data_value;
// What kind of data element are we expecting?
switch (_type) {
case T_word:
case T_dword:
case T_char:
case T_uchar:
case T_sword:
case T_sdword:
data_value = zero_fill_value(0, &XFileDataDef::zero_fill_integer_value);
break;
case T_float:
case T_double:
data_value = zero_fill_value(0, &XFileDataDef::zero_fill_double_value);
break;
case T_string:
case T_cstring:
case T_unicode:
data_value = zero_fill_value(0, &XFileDataDef::zero_fill_string_value);
break;
case T_template:
data_value = zero_fill_value(0, &XFileDataDef::zero_fill_template_value);
break;
}
if (data_value != (XFileDataObject *)NULL) {
object->add_element(data_value);
}
return XFileNode::fill_zero_data(object);
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::unpack_integer_value
@ -368,6 +413,92 @@ unpack_value(const XFileParseDataList &parse_data_list, int array_index,
unpack_value(parse_data_list, array_index + 1,
prev_data, index, sub_index,
unpack_method);
if (array_element == (XFileDataObject *)NULL) {
return NULL;
}
data_value->add_element(array_element);
}
}
return data_value;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::zero_fill_integer_value
// Access: Private
// Description: Returns a newly-allocated zero integer value.
////////////////////////////////////////////////////////////////////
PT(XFileDataObject) XFileDataDef::
zero_fill_integer_value() const {
return new XFileDataObjectInteger(this, 0);
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::zero_fill_double_value
// Access: Private
// Description: Returns a newly-allocated zero floating-point value.
////////////////////////////////////////////////////////////////////
PT(XFileDataObject) XFileDataDef::
zero_fill_double_value() const {
return new XFileDataObjectDouble(this, 0.0);
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::zero_fill_string_value
// Access: Private
// Description: Returns a newly-allocated empty string value.
////////////////////////////////////////////////////////////////////
PT(XFileDataObject) XFileDataDef::
zero_fill_string_value() const {
return new XFileDataObjectString(this, "");
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::zero_fill_template_value
// Access: Private
// Description: Returns a newly-allocated zero-filled nested template
// value.
////////////////////////////////////////////////////////////////////
PT(XFileDataObject) XFileDataDef::
zero_fill_template_value() const {
PT(XFileDataObject) data_value =
new XFileDataNodeTemplate(get_x_file(), get_name(), _template);
if (!_template->fill_zero_data(data_value)) {
return NULL;
}
return data_value;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::zero_fill_value
// Access: Private
// Description: Creates a zero-valued element for the next sequential
// value, of the type returned by the zero_fill_method.
// If the value is a fixed-size array type, zero-fills
// all the elements of the array.
////////////////////////////////////////////////////////////////////
PT(XFileDataObject) XFileDataDef::
zero_fill_value(int array_index,
XFileDataDef::ZeroFillMethod zero_fill_method) const {
PT(XFileDataObject) data_value;
if (array_index == (int)_array_def.size()) {
data_value = (this->*zero_fill_method)();
} else {
data_value = new XFileDataObjectArray(this);
int array_size = 0;
if (_array_def[array_index].is_fixed_size()) {
array_size = _array_def[array_index].get_fixed_size();
}
for (int i = 0; i < array_size; i++) {
PT(XFileDataObject) array_element =
zero_fill_value(array_index + 1, zero_fill_method);
if (array_element == (XFileDataObject *)NULL) {
return NULL;
}
data_value->add_element(array_element);
}
}

View File

@ -73,11 +73,15 @@ public:
PrevData &prev_data,
size_t &index, size_t &sub_index) const;
virtual bool fill_zero_data(XFileDataObject *object) const;
private:
typedef PT(XFileDataObject)
(XFileDataDef::*UnpackMethod)(const XFileParseDataList &parse_data_list,
const PrevData &prev_data,
size_t &index, size_t &sub_index) const;
typedef PT(XFileDataObject)
(XFileDataDef::*ZeroFillMethod)() const;
PT(XFileDataObject)
unpack_integer_value(const XFileParseDataList &parse_data_list,
@ -101,6 +105,13 @@ private:
const PrevData &prev_data,
size_t &index, size_t &sub_index,
UnpackMethod unpack_method) const;
PT(XFileDataObject) zero_fill_integer_value() const;
PT(XFileDataObject) zero_fill_double_value() const;
PT(XFileDataObject) zero_fill_string_value() const;
PT(XFileDataObject) zero_fill_template_value() const;
PT(XFileDataObject)
zero_fill_value(int array_index, ZeroFillMethod zero_fill_method) const;
private:
Type _type;

View File

@ -20,6 +20,7 @@
#include "indent.h"
#include "xFileParseData.h"
#include "xLexerDefs.h"
#include "config_xfile.h"
TypeHandle XFileDataNodeTemplate::_type_handle;
@ -35,6 +36,17 @@ XFileDataNodeTemplate(XFile *x_file, const string &name,
{
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataNodeTemplate::zero_fill
// Access: Public
// Description: Fills the data node with zero-valued elements
// appropriate to the template.
////////////////////////////////////////////////////////////////////
void XFileDataNodeTemplate::
zero_fill() {
_template->fill_zero_data(this);
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataNodeTemplate::is_complex_object
// Access: Public, Virtual
@ -155,9 +167,9 @@ write_text(ostream &out, int indent_level) const {
}
out << " {\n";
int num_elements = get_num_elements();
for (int i = 0; i < num_elements; i++) {
get_element(i)->write_data(out, indent_level + 2, ";");
NestedElements::const_iterator ni;
for (ni = _nested_elements.begin(); ni != _nested_elements.end(); ++ni) {
(*ni)->write_data(out, indent_level + 2, ";");
}
XFileNode::write_text(out, indent_level + 2);
@ -233,8 +245,8 @@ get_num_elements() const {
// Description: Returns the nth nested data element within the
// object.
////////////////////////////////////////////////////////////////////
const XFileDataObject *XFileDataNodeTemplate::
get_element(int n) const {
XFileDataObject *XFileDataNodeTemplate::
get_element(int n) {
nassertr(n >= 0 && n < (int)_nested_elements.size(), NULL);
return _nested_elements[n];
}
@ -245,11 +257,14 @@ get_element(int n) const {
// Description: Returns the nested data element within the
// object that has the indicated name.
////////////////////////////////////////////////////////////////////
const XFileDataObject *XFileDataNodeTemplate::
get_element(const string &name) const {
XFileDataObject *XFileDataNodeTemplate::
get_element(const string &name) {
int child_index = _template->find_child_index(name);
if (child_index >= 0) {
return get_element(child_index);
}
xfile_cat.warning()
<< "\"" << name << "\" not a member of " << _template->get_name()
<< "\n";
return NULL;
}

View File

@ -39,6 +39,7 @@ class XFileDataNodeTemplate : public XFileDataNode {
public:
XFileDataNodeTemplate(XFile *x_file, const string &name,
XFileTemplate *xtemplate);
void zero_fill();
virtual bool is_complex_object() const;
@ -55,8 +56,8 @@ public:
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:
XFileParseDataList _parse_data_list;

View File

@ -39,18 +39,55 @@ get_data_def() const {
return _data_def;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::operator = (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::
operator = (int int_value) {
set_int_value(int_value);
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::operator = (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::
operator = (double double_value) {
set_double_value(double_value);
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::operator = (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::
operator = (const string &string_value) {
set_string_value(string_value);
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::i
// Access: Public
// Description: Unambiguously returns the object's representation as
// an integer, or 0 if the object has no integer
// representation. See also the typecast operators, and
// get_data_def() to determine what kind of
// representation this object has.
// representation. See also get_data_def() to determine
// what kind of representation this object has.
////////////////////////////////////////////////////////////////////
INLINE int XFileDataObject::
i() const {
return as_integer_value();
return get_int_value();
}
////////////////////////////////////////////////////////////////////
@ -58,13 +95,12 @@ i() const {
// Access: Public
// Description: Unambiguously returns the object's representation as
// a double, or 0.0 if the object has no double
// representation. See also the typecast operators, and
// get_data_def() to determine what kind of
// representation this object has.
// representation. See also get_data_def() to determine
// what kind of representation this object has.
////////////////////////////////////////////////////////////////////
INLINE double XFileDataObject::
d() const {
return as_double_value();
return get_double_value();
}
////////////////////////////////////////////////////////////////////
@ -72,47 +108,12 @@ d() const {
// Access: Public
// Description: Unambiguously returns the object's representation as
// a string, or empty string if the object has no string
// representation. See also the typecast operators, and
// get_data_def() to determine what kind of
// representation this object has.
// representation. See also get_data_def() to determine
// what kind of representation this object has.
////////////////////////////////////////////////////////////////////
INLINE string XFileDataObject::
s() const {
return as_string_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::int typecast operator
// Access: Public
// Description: Returns the object's representation as an integer, or
// 0 if the object has no integer representation.
////////////////////////////////////////////////////////////////////
INLINE XFileDataObject::
operator int () const {
return as_integer_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::double typecast operator
// Access: Public
// Description: Returns the object's representation as a double, or
// 0.0 if the object has no integer representation.
////////////////////////////////////////////////////////////////////
INLINE XFileDataObject::
operator double () const {
return as_double_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::string typecast operator
// Access: Public
// Description: Returns the object's representation as a string, or
// empty string if the object has no string
// representation.
////////////////////////////////////////////////////////////////////
INLINE XFileDataObject::
operator string () const {
return as_string_value();
return get_string_value();
}
////////////////////////////////////////////////////////////////////
@ -135,7 +136,7 @@ size() const {
////////////////////////////////////////////////////////////////////
INLINE const XFileDataObject &XFileDataObject::
operator [] (int n) const {
const XFileDataObject *element = get_element(n);
const XFileDataObject *element = ((XFileDataObject *)this)->get_element(n);
nassertr(element != (XFileDataObject *)NULL, *this);
return *element;
}
@ -149,7 +150,35 @@ operator [] (int n) const {
////////////////////////////////////////////////////////////////////
INLINE const XFileDataObject &XFileDataObject::
operator [] (const string &name) const {
const XFileDataObject *element = get_element(name);
const XFileDataObject *element = ((XFileDataObject *)this)->get_element(name);
nassertr(element != (XFileDataObject *)NULL, *this);
return *element;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::operator [] (int)
// Access: Public
// Description: Returns the nth nested object within this object.
// Call get_num_children() to determine the number of
// nested objects.
////////////////////////////////////////////////////////////////////
INLINE XFileDataObject &XFileDataObject::
operator [] (int n) {
XFileDataObject *element = get_element(n);
nassertr(element != (XFileDataObject *)NULL, *this);
return *element;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::operator [] (string)
// Access: Public
// Description: Returns the named nested object within this object.
// It is an error if the named object does not exist.
// Call find_child() instead if there is any doubt.
////////////////////////////////////////////////////////////////////
INLINE XFileDataObject &XFileDataObject::
operator [] (const string &name) {
XFileDataObject *element = get_element(name);
nassertr(element != (XFileDataObject *)NULL, *this);
return *element;
}

View File

@ -17,6 +17,13 @@
////////////////////////////////////////////////////////////////////
#include "xFileDataObject.h"
#include "xFileTemplate.h"
#include "xFile.h"
#include "xFileDataNodeTemplate.h"
#include "xFileDataObjectInteger.h"
#include "xFileDataObjectDouble.h"
#include "xFileDataObjectString.h"
#include "config_xfile.h"
#include "indent.h"
TypeHandle XFileDataObject::_type_handle;
@ -42,6 +49,135 @@ is_complex_object() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::add_int
// Access: Public
// Description: Appends a new integer value to the data object, if it
// makes sense to do so. Normally, this is valid only
// for a DataObjectArray, or in certain special cases for
// a DataNodeTemplate.
////////////////////////////////////////////////////////////////////
XFileDataObject &XFileDataObject::
add_int(int int_value) {
XFileDataObject *object =
new XFileDataObjectInteger(get_data_def(), int_value);
add_element(object);
return *object;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::add_double
// Access: Public
// Description: Appends a new floating-point value to the data
// object, if it makes sense to do so. Normally, this
// is valid only for a DataObjectArray, or in certain
// special cases for a DataNodeTemplate.
////////////////////////////////////////////////////////////////////
XFileDataObject &XFileDataObject::
add_double(double double_value) {
XFileDataObject *object =
new XFileDataObjectDouble(get_data_def(), double_value);
add_element(object);
return *object;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::add_string
// Access: Public
// Description: Appends a new string value to the data object, if it
// makes sense to do so. Normally, this is valid only
// for a DataObjectArray, or in certain special cases for
// a DataNodeTemplate.
////////////////////////////////////////////////////////////////////
XFileDataObject &XFileDataObject::
add_string(const string &string_value) {
XFileDataObject *object =
new XFileDataObjectString(get_data_def(), string_value);
add_element(object);
return *object;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::add_Vector
// Access: Public
// Description: Appends a new Vector instance.
////////////////////////////////////////////////////////////////////
XFileDataObject &XFileDataObject::
add_Vector(XFile *x_file, const LVecBase3d &vector) {
XFileTemplate *xtemplate = XFile::find_standard_template("Vector");
nassertr(xtemplate != (XFileTemplate *)NULL, *this);
XFileDataNodeTemplate *node =
new XFileDataNodeTemplate(x_file, "", xtemplate);
add_element(node);
node->zero_fill();
(*node)["x"] = vector[0];
(*node)["y"] = vector[1];
(*node)["z"] = vector[2];
return *node;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::add_MeshFace
// Access: Public
// Description: Appends a new MeshFace instance.
////////////////////////////////////////////////////////////////////
XFileDataObject &XFileDataObject::
add_MeshFace(XFile *x_file) {
XFileTemplate *xtemplate = XFile::find_standard_template("MeshFace");
nassertr(xtemplate != (XFileTemplate *)NULL, *this);
XFileDataNodeTemplate *node =
new XFileDataNodeTemplate(x_file, "", xtemplate);
add_element(node);
node->zero_fill();
return *node;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::add_IndexedColor
// Access: Public
// Description: Appends a new IndexedColor instance.
////////////////////////////////////////////////////////////////////
XFileDataObject &XFileDataObject::
add_IndexedColor(XFile *x_file, int index, const Colorf &color) {
XFileTemplate *xtemplate = XFile::find_standard_template("IndexedColor");
nassertr(xtemplate != (XFileTemplate *)NULL, *this);
XFileDataNodeTemplate *node =
new XFileDataNodeTemplate(x_file, "", xtemplate);
add_element(node);
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];
return *node;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::add_Coords2d
// Access: Public
// Description: Appends a new Coords2d instance.
////////////////////////////////////////////////////////////////////
XFileDataObject &XFileDataObject::
add_Coords2d(XFile *x_file, const LVecBase2d &coords) {
XFileTemplate *xtemplate = XFile::find_standard_template("Coords2d");
nassertr(xtemplate != (XFileTemplate *)NULL, *this);
XFileDataNodeTemplate *node =
new XFileDataNodeTemplate(x_file, "", xtemplate);
add_element(node);
node->zero_fill();
(*node)["u"] = coords[0];
(*node)["v"] = coords[1];
return *node;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::add_element
// Access: Public, Virtual
@ -79,35 +215,71 @@ write_data(ostream &out, int indent_level, const char *) const {
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::as_integer_value
// Function: XFileDataObject::set_int_value
// Access: Protected, Virtual
// Description: Sets the object's value as an integer, if this is
// legal.
////////////////////////////////////////////////////////////////////
void XFileDataObject::
set_int_value(int int_value) {
xfile_cat.error()
<< get_type() << " does not support integer values.\n";
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::set_double_value
// Access: Protected, Virtual
// Description: Sets the object's value as a floating-point number,
// if this is legal.
////////////////////////////////////////////////////////////////////
void XFileDataObject::
set_double_value(double double_value) {
xfile_cat.error()
<< get_type() << " does not support floating-point values.\n";
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::set_string_value
// Access: Protected, Virtual
// Description: Sets the object's value as a string, if this is
// legal.
////////////////////////////////////////////////////////////////////
void XFileDataObject::
set_string_value(const string &string_value) {
xfile_cat.error()
<< get_type() << " does not support stringeger values.\n";
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::get_int_value
// Access: Protected, Virtual
// Description: Returns the object's representation as an integer, if
// it has one.
////////////////////////////////////////////////////////////////////
int XFileDataObject::
as_integer_value() const {
get_int_value() const {
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::as_double_value
// Function: XFileDataObject::get_double_value
// Access: Protected, Virtual
// Description: Returns the object's representation as a double, if
// it has one.
////////////////////////////////////////////////////////////////////
double XFileDataObject::
as_double_value() const {
get_double_value() const {
return 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::as_string_value
// Function: XFileDataObject::get_string_value
// Access: Protected, Virtual
// Description: Returns the object's representation as a string, if
// it has one.
////////////////////////////////////////////////////////////////////
string XFileDataObject::
as_string_value() const {
get_string_value() const {
return string();
}
@ -129,8 +301,11 @@ get_num_elements() const {
// Description: Returns the nth nested data element within the
// object.
////////////////////////////////////////////////////////////////////
const XFileDataObject *XFileDataObject::
get_element(int n) const {
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";
return NULL;
}
@ -140,7 +315,10 @@ get_element(int n) const {
// Description: Returns the nested data element within the
// object that has the indicated name.
////////////////////////////////////////////////////////////////////
const XFileDataObject *XFileDataObject::
get_element(const string &name) const {
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";
return NULL;
}

View File

@ -23,7 +23,9 @@
#include "referenceCount.h"
#include "pointerTo.h"
#include "dcast.h"
#include "luse.h"
class XFile;
class XFileDataDef;
////////////////////////////////////////////////////////////////////
@ -41,17 +43,38 @@ public:
virtual bool is_complex_object() const;
INLINE void operator = (int int_value);
INLINE void operator = (double double_value);
INLINE void operator = (const string &string_value);
INLINE int i() const;
INLINE double d() const;
INLINE string s() const;
INLINE operator int () const;
INLINE operator double () const;
INLINE operator string () const;
INLINE int size() const;
INLINE const XFileDataObject &operator [] (int n) const;
INLINE const XFileDataObject &operator [] (const string &name) const;
INLINE XFileDataObject &operator [] (int n);
INLINE XFileDataObject &operator [] (const string &name);
// The following methods can be used to add elements of a specific
// type to a complex object, e.g. an array or a template object.
XFileDataObject &add_int(int int_value);
XFileDataObject &add_double(double double_value);
XFileDataObject &add_string(const string &string_value);
// The following methods can be used to add elements of a specific
// type, based on one of the standard templates.
XFileDataObject &add_Vector(XFile *x_file, const LVecBase3d &vector);
XFileDataObject &add_MeshFace(XFile *x_file);
XFileDataObject &add_IndexedColor(XFile *x_file, int index,
const Colorf &color);
XFileDataObject &add_Coords2d(XFile *x_file, const LVecBase2d &coords);
public:
virtual bool add_element(XFileDataObject *element);
virtual void output_data(ostream &out) const;
@ -59,13 +82,17 @@ public:
const char *separator) const;
protected:
virtual int as_integer_value() const;
virtual double as_double_value() const;
virtual string as_string_value() const;
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);
virtual int get_int_value() const;
virtual double get_double_value() const;
virtual string get_string_value() const;
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);
const XFileDataDef *_data_def;

View File

@ -116,8 +116,8 @@ get_num_elements() const {
// Description: Returns the nth nested data element within the
// object.
////////////////////////////////////////////////////////////////////
const XFileDataObject *XFileDataObjectArray::
get_element(int n) const {
XFileDataObject *XFileDataObjectArray::
get_element(int n) {
nassertr(n >= 0 && n < (int)_nested_elements.size(), NULL);
return _nested_elements[n];
}

View File

@ -39,7 +39,7 @@ public:
protected:
virtual int get_num_elements() const;
virtual const XFileDataObject *get_element(int n) const;
virtual XFileDataObject *get_element(int n);
private:
typedef pvector< PT(XFileDataObject) > NestedElements;

View File

@ -42,7 +42,7 @@ XFileDataObjectDouble(const XFileDataDef *data_def, double value) :
////////////////////////////////////////////////////////////////////
void XFileDataObjectDouble::
output_data(ostream &out) const {
out << as_string_value();
out << get_string_value();
}
////////////////////////////////////////////////////////////////////
@ -54,39 +54,61 @@ output_data(ostream &out) const {
void XFileDataObjectDouble::
write_data(ostream &out, int indent_level, const char *separator) const {
indent(out, indent_level)
<< as_string_value() << separator << "\n";
<< get_string_value() << separator << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectDouble::as_integer_value
// Function: XFileDataObjectDouble::set_int_value
// Access: Protected, Virtual
// Description: Sets the object's value as an integer, if this is
// legal.
////////////////////////////////////////////////////////////////////
void XFileDataObjectDouble::
set_int_value(int int_value) {
_value = (double)int_value;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectDouble::set_double_value
// Access: Protected, Virtual
// Description: Sets the object's value as a floating-point number,
// if this is legal.
////////////////////////////////////////////////////////////////////
void XFileDataObjectDouble::
set_double_value(double double_value) {
_value = double_value;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectDouble::get_int_value
// Access: Protected, Virtual
// Description: Returns the object's representation as an integer, if
// it has one.
////////////////////////////////////////////////////////////////////
int XFileDataObjectDouble::
as_integer_value() const {
get_int_value() const {
return (int)_value;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectDouble::as_double_value
// Function: XFileDataObjectDouble::get_double_value
// Access: Protected, Virtual
// Description: Returns the object's representation as a double, if
// it has one.
////////////////////////////////////////////////////////////////////
double XFileDataObjectDouble::
as_double_value() const {
get_double_value() const {
return _value;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectDouble::as_string_value
// Function: XFileDataObjectDouble::get_string_value
// Access: Protected, Virtual
// Description: Returns the object's representation as a string, if
// it has one.
////////////////////////////////////////////////////////////////////
string XFileDataObjectDouble::
as_string_value() const {
get_string_value() const {
// It's important to format with a decimal point, even if the value
// is integral, since the DirectX .x reader differentiates betweens
// doubles and integers on parsing.

View File

@ -37,9 +37,12 @@ public:
const char *separator) const;
protected:
virtual int as_integer_value() const;
virtual double as_double_value() const;
virtual string as_string_value() const;
virtual void set_int_value(int int_value);
virtual void set_double_value(double double_value);
virtual int get_int_value() const;
virtual double get_double_value() const;
virtual string get_string_value() const;
private:
double _value;

View File

@ -58,34 +58,45 @@ write_data(ostream &out, int indent_level, const char *separator) const {
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectInteger::as_integer_value
// Function: XFileDataObjectInt::set_int_value
// Access: Protected, Virtual
// Description: Sets the object's value as an integer, if this is
// legal.
////////////////////////////////////////////////////////////////////
void XFileDataObjectInteger::
set_int_value(int int_value) {
_value = int_value;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectInteger::get_int_value
// Access: Protected, Virtual
// Description: Returns the object's representation as an integer, if
// it has one.
////////////////////////////////////////////////////////////////////
int XFileDataObjectInteger::
as_integer_value() const {
get_int_value() const {
return _value;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectInteger::as_double_value
// Function: XFileDataObjectInteger::get_double_value
// Access: Protected, Virtual
// Description: Returns the object's representation as a double, if
// it has one.
////////////////////////////////////////////////////////////////////
double XFileDataObjectInteger::
as_double_value() const {
get_double_value() const {
return _value;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectInteger::as_string_value
// Function: XFileDataObjectInteger::get_string_value
// Access: Protected, Virtual
// Description: Returns the object's representation as a string, if
// it has one.
////////////////////////////////////////////////////////////////////
string XFileDataObjectInteger::
as_string_value() const {
get_string_value() const {
return format_string(_value);
}

View File

@ -37,9 +37,11 @@ public:
const char *separator) const;
protected:
virtual int as_integer_value() const;
virtual double as_double_value() const;
virtual string as_string_value() const;
virtual void set_int_value(int int_value);
virtual int get_int_value() const;
virtual double get_double_value() const;
virtual string get_string_value() const;
private:
int _value;

View File

@ -59,13 +59,24 @@ write_data(ostream &out, int indent_level, const char *separator) const {
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectString::as_string_value
// Function: XFileDataObjectString::set_string_value
// Access: Protected, Virtual
// Description: Sets the object's value as a string, if this is
// legal.
////////////////////////////////////////////////////////////////////
void XFileDataObjectString::
set_string_value(const string &string_value) {
_value = string_value;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectString::get_string_value
// Access: Protected, Virtual
// Description: Returns the object's representation as a string, if
// it has one.
////////////////////////////////////////////////////////////////////
string XFileDataObjectString::
as_string_value() const {
get_string_value() const {
return _value;
}
@ -95,6 +106,7 @@ enquote_string(ostream &out) const {
break;
case '"':
case '\\':
out << '\\' << (*si);
break;

View File

@ -37,7 +37,8 @@ public:
const char *separator) const;
protected:
virtual string as_string_value() const;
virtual void set_string_value(const string &string_value);
virtual string get_string_value() const;
private:
void enquote_string(ostream &out) const;

View File

@ -21,6 +21,9 @@
#include "xFile.h"
#include "xLexerDefs.h"
#include "xFileParseData.h"
#include "xFile.h"
#include "xFileDataNodeTemplate.h"
#include "filename.h"
TypeHandle XFileNode::_type_handle;
@ -31,7 +34,7 @@ TypeHandle XFileNode::_type_handle;
////////////////////////////////////////////////////////////////////
XFileNode::
XFileNode(XFile *x_file, const string &name) :
Namable(name),
Namable(make_nice_name(name)),
_x_file(x_file)
{
}
@ -202,3 +205,249 @@ repack_data(XFileDataObject *object,
return true;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::fill_zero_data
// Access: Public, Virtual
// Description: This is similar to repack_data(), except it is used
// to fill the initial values for a newly-created
// template object to zero.
////////////////////////////////////////////////////////////////////
bool XFileNode::
fill_zero_data(XFileDataObject *object) const {
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
if (!(*ci)->fill_zero_data(object)) {
return false;
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::add_Mesh
// Access: Public
// Description: Creates a new Mesh instance, as a child of this node.
////////////////////////////////////////////////////////////////////
XFileDataNode *XFileNode::
add_Mesh(const string &name) {
XFileTemplate *xtemplate = XFile::find_standard_template("Mesh");
nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
XFileDataNodeTemplate *node =
new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
add_child(node);
node->zero_fill();
return node;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::add_MeshNormals
// Access: Public
// Description: Creates a new MeshNormals instance, as a child of
// this node.
////////////////////////////////////////////////////////////////////
XFileDataNode *XFileNode::
add_MeshNormals(const string &name) {
XFileTemplate *xtemplate = XFile::find_standard_template("MeshNormals");
nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
XFileDataNodeTemplate *node =
new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
add_child(node);
node->zero_fill();
return node;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::add_MeshVertexColors
// Access: Public
// Description: Creates a new MeshVertexColors instance, as a child of
// this node.
////////////////////////////////////////////////////////////////////
XFileDataNode *XFileNode::
add_MeshVertexColors(const string &name) {
XFileTemplate *xtemplate = XFile::find_standard_template("MeshVertexColors");
nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
XFileDataNodeTemplate *node =
new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
add_child(node);
node->zero_fill();
return node;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::add_MeshTextureCoords
// Access: Public
// Description: Creates a new MeshTextureCoords instance, as a child of
// this node.
////////////////////////////////////////////////////////////////////
XFileDataNode *XFileNode::
add_MeshTextureCoords(const string &name) {
XFileTemplate *xtemplate = XFile::find_standard_template("MeshTextureCoords");
nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
XFileDataNodeTemplate *node =
new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
add_child(node);
node->zero_fill();
return node;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::add_MeshMaterialList
// Access: Public
// Description: Creates a new MeshMaterialList instance, as a child of
// this node.
////////////////////////////////////////////////////////////////////
XFileDataNode *XFileNode::
add_MeshMaterialList(const string &name) {
XFileTemplate *xtemplate = XFile::find_standard_template("MeshMaterialList");
nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
XFileDataNodeTemplate *node =
new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
add_child(node);
node->zero_fill();
return node;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::add_Material
// Access: Public
// Description: Creates a new Material instance, as a child of
// this node.
////////////////////////////////////////////////////////////////////
XFileDataNode *XFileNode::
add_Material(const string &name, const Colorf &face_color,
double power, const RGBColorf &specular_color,
const RGBColorf &emissive_color) {
XFileTemplate *xtemplate = XFile::find_standard_template("Material");
nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
XFileDataNodeTemplate *node =
new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
add_child(node);
node->zero_fill();
(*node)["faceColor"]["red"] = face_color[0];
(*node)["faceColor"]["green"] = face_color[1];
(*node)["faceColor"]["blue"] = face_color[2];
(*node)["faceColor"]["alpha"] = face_color[3];
(*node)["power"] = power;
(*node)["specularColor"]["red"] = specular_color[0];
(*node)["specularColor"]["green"] = specular_color[1];
(*node)["specularColor"]["blue"] = specular_color[2];
(*node)["emissiveColor"]["red"] = emissive_color[0];
(*node)["emissiveColor"]["green"] = emissive_color[1];
(*node)["emissiveColor"]["blue"] = emissive_color[2];
return node;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::add_TextureFilename
// Access: Public
// Description: Creates a new TextureFilename instance, as a child of
// this node.
////////////////////////////////////////////////////////////////////
XFileDataNode *XFileNode::
add_TextureFilename(const string &name, const Filename &filename) {
XFileTemplate *xtemplate = XFile::find_standard_template("TextureFilename");
nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
XFileDataNodeTemplate *node =
new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
add_child(node);
node->zero_fill();
(*node)["filename"] = filename.to_os_specific();
return node;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::add_Frame
// Access: Public
// Description: Creates a new Frame instance, as a child of this
// node.
////////////////////////////////////////////////////////////////////
XFileDataNode *XFileNode::
add_Frame(const string &name) {
XFileTemplate *xtemplate = XFile::find_standard_template("Frame");
nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
XFileDataNodeTemplate *node =
new XFileDataNodeTemplate(get_x_file(), name, xtemplate);
add_child(node);
node->zero_fill();
return node;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::add_FrameTransformMatrix
// Access: Public
// Description: Creates a new FrameTransformMatrix instance, as a
// child of this node.
////////////////////////////////////////////////////////////////////
XFileDataNode *XFileNode::
add_FrameTransformMatrix(const LMatrix4d &mat) {
XFileTemplate *xtemplate =
XFile::find_standard_template("FrameTransformMatrix");
nassertr(xtemplate != (XFileTemplate *)NULL, NULL);
XFileDataNodeTemplate *node =
new XFileDataNodeTemplate(get_x_file(), "", xtemplate);
add_child(node);
node->zero_fill();
XFileDataObject &xmat = (*node)["frameMatrix"]["matrix"];
xmat[0] = mat(0, 0);
xmat[1] = mat(0, 1);
xmat[2] = mat(0, 2);
xmat[3] = mat(0, 3);
xmat[4] = mat(1, 0);
xmat[5] = mat(1, 1);
xmat[6] = mat(1, 2);
xmat[7] = mat(1, 3);
xmat[8] = mat(2, 0);
xmat[9] = mat(2, 1);
xmat[10] = mat(2, 2);
xmat[11] = mat(2, 3);
xmat[12] = mat(3, 0);
xmat[13] = mat(3, 1);
xmat[14] = mat(3, 2);
xmat[15] = mat(3, 3);
return node;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::make_nice_name
// Access: Protected, Static
// Description: Transforms the indicated egg name to a name that is
// acceptable for a node in the X File format.
////////////////////////////////////////////////////////////////////
string XFileNode::
make_nice_name(const string &str) {
string result;
string::const_iterator si;
for (si = str.begin(); si != str.end(); ++si) {
if (isalnum(*si)) {
result += *si;
} else {
result += "_";
}
}
if (!str.empty() && isdigit(str[0])) {
// If the name begins with a digit, we must make it begin with
// something else, like for instance an underscore.
result = '_' + result;
}
return result;
}

View File

@ -27,12 +27,15 @@
#include "notify.h"
#include "pvector.h"
#include "pmap.h"
#include "luse.h"
class XFile;
class WindowsGuid;
class XFileParseDataList;
class XFileDataDef;
class XFileDataObject;
class XFileDataNode;
class Filename;
////////////////////////////////////////////////////////////////////
// Class : XFileNode
@ -68,6 +71,34 @@ public:
PrevData &prev_data,
size_t &index, size_t &sub_index) const;
virtual bool fill_zero_data(XFileDataObject *object) const;
// The following methods can be used to create instances of the
// standard template objects. These definitions match those defined
// in standardTemplates.x in this directory (and compiled into the
// executable).
/*
PT(XFileNode) make_Header(int major, int minor, int flags);
PT(XFileNode) make_Vector(const LVecBase3d &vector);
PT(XFileNode) make_MeshFace(int num_vertex_indices, const int *vertex_indices);
*/
XFileDataNode *add_Mesh(const string &name);
XFileDataNode *add_MeshNormals(const string &name);
XFileDataNode *add_MeshVertexColors(const string &name);
XFileDataNode *add_MeshTextureCoords(const string &name);
XFileDataNode *add_MeshMaterialList(const string &name);
XFileDataNode *add_Material(const string &name, const Colorf &face_color,
double power, const RGBColorf &specular_color,
const RGBColorf &emissive_color);
XFileDataNode *add_TextureFilename(const string &name,
const Filename &filename);
XFileDataNode *add_Frame(const string &name);
XFileDataNode *add_FrameTransformMatrix(const LMatrix4d &mat);
protected:
static string make_nice_name(const string &str);
protected:
XFile *_x_file;

View File

@ -43,9 +43,8 @@
////////////////////////////////////////////////////////////////////
XFileMaker::
XFileMaker() {
_dx_file = NULL;
_dx_file_save = NULL;
_mesh_index = 0;
_x_file = new XFile;
}
////////////////////////////////////////////////////////////////////
@ -55,152 +54,24 @@ XFileMaker() {
////////////////////////////////////////////////////////////////////
XFileMaker::
~XFileMaker() {
close();
}
////////////////////////////////////////////////////////////////////
// Function: XFileMaker::open
// Function: XFileMaker::write
// Access: Public
// Description: Opens the indicated filename for writing, and writes
// the .x header information; returns true on success,
// false otherwise.
// Description: Writes the .x file data to the indicated filename;
// returns true on success, false otherwise.
////////////////////////////////////////////////////////////////////
bool XFileMaker::
open(const Filename &filename) {
HRESULT hr;
close();
hr = DirectXFileCreate(&_dx_file);
if (hr != DXFILE_OK) {
nout << "Unable to create X interface.\n";
return false;
}
// Register our templates.
hr = _dx_file->RegisterTemplates(D3DRM_XTEMPLATES, d3drm_xtemplates_length);
if (hr != DXFILE_OK) {
nout << "Unable to register templates.\n";
return false;
}
string os_file = filename.to_os_specific();
hr = _dx_file->CreateSaveObject(os_file.c_str(), DXFILEFORMAT_TEXT,
&_dx_file_save);
if (hr != DXFILE_OK) {
nout << "Unable to open X file: " << os_file << "\n";
return false;
}
// Save the templates we will use.
static const GUID *temps[] = {
&mydef_TID_D3DRMHeader,
&TID_D3DRMCoords2d,
&TID_D3DRMVector,
&TID_D3DRMColorRGBA,
&TID_D3DRMColorRGB,
&TID_D3DRMIndexedColor,
&TID_D3DRMTextureFilename,
&TID_D3DRMMatrix4x4,
&TID_D3DRMMaterial,
&TID_D3DRMMeshFace,
&TID_D3DRMMesh,
&TID_D3DRMMeshNormals,
&TID_D3DRMMeshTextureCoords,
&TID_D3DRMMeshMaterialList,
&TID_D3DRMFrameTransformMatrix,
&TID_D3DRMFrame,
/*
This is the complete list I extracted out of the Windows header
files.
&TID_D3DRMInfo,
&TID_D3DRMMesh,
&TID_D3DRMVector,
&TID_D3DRMMeshFace,
&TID_D3DRMMaterial,
&TID_D3DRMMaterialArray,
&TID_D3DRMFrame,
&TID_D3DRMFrameTransformMatrix,
&TID_D3DRMMeshMaterialList,
&TID_D3DRMMeshTextureCoords,
&TID_D3DRMMeshNormals,
&TID_D3DRMCoords2d,
&TID_D3DRMMatrix4x4,
&TID_D3DRMAnimation,
&TID_D3DRMAnimationSet,
&TID_D3DRMAnimationKey,
&TID_D3DRMFloatKeys,
&TID_D3DRMMaterialAmbientColor,
&TID_D3DRMMaterialDiffuseColor,
&TID_D3DRMMaterialSpecularColor,
&TID_D3DRMMaterialEmissiveColor,
&TID_D3DRMMaterialPower,
&TID_D3DRMColorRGBA,
&TID_D3DRMColorRGB,
&TID_D3DRMGuid,
&TID_D3DRMTextureFilename,
&TID_D3DRMTextureReference,
&TID_D3DRMIndexedColor,
&TID_D3DRMMeshVertexColors,
&TID_D3DRMMaterialWrap,
&TID_D3DRMBoolean,
&TID_D3DRMMeshFaceWraps,
&TID_D3DRMBoolean2d,
&TID_D3DRMTimedFloatKeys,
&TID_D3DRMAnimationOptions,
&TID_D3DRMFramePosition,
&TID_D3DRMFrameVelocity,
&TID_D3DRMFrameRotation,
&TID_D3DRMLight,
&TID_D3DRMCamera,
&TID_D3DRMAppData,
&TID_D3DRMLightUmbra,
&TID_D3DRMLightRange,
&TID_D3DRMLightPenumbra,
&TID_D3DRMLightAttenuation,
&TID_D3DRMInlineData,
&TID_D3DRMUrl,
&TID_D3DRMProgressiveMesh,
&TID_D3DRMExternalVisual,
&TID_D3DRMStringProperty,
&TID_D3DRMPropertyBag,
&TID_D3DRMRightHanded,
*/
};
static const int num_temps = sizeof(temps) / sizeof(temps[0]);
hr = _dx_file_save->SaveTemplates(num_temps, temps);
if (hr != DXFILE_OK) {
nout << "Unable to save templates.\n";
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMaker::close
// Access: Public
// Description: Finalizes and closes the file previously opened via
// open().
////////////////////////////////////////////////////////////////////
void XFileMaker::
close() {
if (_dx_file != NULL) {
if (_dx_file_save != NULL) {
_dx_file_save->Release();
_dx_file_save = NULL;
}
_dx_file->Release();
_dx_file = NULL;
}
write(const Filename &filename) {
return _x_file->write(filename);
}
////////////////////////////////////////////////////////////////////
// Function: XFileMaker::add_tree
// Access: Public
// Description: Adds the egg tree rooted at the indicated node to the
// DX structure. This may be somewhat destructive of
// X structure. This may be somewhat destructive of
// the egg tree. Returns true on success, false on
// failure.
////////////////////////////////////////////////////////////////////
@ -213,16 +84,19 @@ add_tree(EggData &egg_data) {
int num_bins = pmaker.make_bins(&egg_data);
// And now we're ready to traverse the egg hierarchy.
if (!recurse_nodes(&egg_data, NULL)) {
if (!recurse_nodes(&egg_data, _x_file)) {
return false;
}
// Make sure we finalize any meshes in the root.
if (!finalize_mesh(NULL)) {
return false;
// Create X structures for all of the meshes we built up.
Meshes::iterator mi;
for (mi = _meshes.begin(); mi != _meshes.end(); ++mi) {
if (!finalize_mesh((*mi).first, (*mi).second)) {
return false;
}
}
_meshes.clear();
nassertr(_meshes.empty(), false);
return true;
}
@ -233,37 +107,29 @@ add_tree(EggData &egg_data) {
// it is supported.
////////////////////////////////////////////////////////////////////
bool XFileMaker::
add_node(EggNode *egg_node, LPDIRECTXFILEDATA dx_parent) {
add_node(EggNode *egg_node, XFileNode *x_parent) {
if (egg_node->is_of_type(EggBin::get_class_type())) {
return add_bin(DCAST(EggBin, egg_node), dx_parent);
return add_bin(DCAST(EggBin, egg_node), x_parent);
} else if (egg_node->is_of_type(EggGroup::get_class_type())) {
return add_group(DCAST(EggGroup, egg_node), dx_parent);
return add_group(DCAST(EggGroup, egg_node), x_parent);
} else if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
// A grouping node of some kind.
EggGroupNode *egg_group = DCAST(EggGroupNode, egg_node);
LPDIRECTXFILEDATA obj;
if (xfile_one_mesh) {
// Don't create any additional frames representing the egg
// hierarchy.
if (!recurse_nodes(egg_group, dx_parent)) {
if (!recurse_nodes(egg_group, x_parent)) {
return false;
}
} else {
// Create a frame for each EggGroup.
if (!create_frame(obj, egg_group->get_name())) {
return false;
}
if (!recurse_nodes(egg_group, obj)) {
obj->Release();
return false;
}
if (!attach_and_release(obj, dx_parent)) {
// Create a Frame for each EggGroup.
XFileDataNode *x_frame = x_parent->add_Frame(egg_group->get_name());
if (!recurse_nodes(egg_group, x_frame)) {
return false;
}
}
@ -281,32 +147,24 @@ add_node(EggNode *egg_node, LPDIRECTXFILEDATA dx_parent) {
// Description: Adds a frame for the indicated group node.
////////////////////////////////////////////////////////////////////
bool XFileMaker::
add_group(EggGroup *egg_group, LPDIRECTXFILEDATA dx_parent) {
add_group(EggGroup *egg_group, XFileNode *x_parent) {
if (xfile_one_mesh) {
// Don't create any additional frames representing the egg
// hierarchy.
if (!recurse_nodes(egg_group, dx_parent)) {
if (!recurse_nodes(egg_group, x_parent)) {
return false;
}
} else {
// Create a frame for each EggGroup.
LPDIRECTXFILEDATA obj;
if (!create_frame(obj, egg_group->get_name())) {
return false;
}
XFileDataNode *x_frame = x_parent->add_Frame(egg_group->get_name());
// Set the transform on the frame, if we have one.
if (egg_group->has_transform()) {
add_frame_transform(obj, LCAST(float, egg_group->get_transform()));
x_frame->add_FrameTransformMatrix(egg_group->get_transform());
}
if (!recurse_nodes(egg_group, obj)) {
obj->Release();
return false;
}
if (!attach_and_release(obj, dx_parent)) {
if (!recurse_nodes(egg_group, x_frame)) {
return false;
}
}
@ -321,10 +179,10 @@ add_group(EggGroup *egg_group, LPDIRECTXFILEDATA dx_parent) {
// the indicated bin node.
////////////////////////////////////////////////////////////////////
bool XFileMaker::
add_bin(EggBin *egg_bin, LPDIRECTXFILEDATA dx_parent) {
add_bin(EggBin *egg_bin, XFileNode *x_parent) {
switch (egg_bin->get_bin_number()) {
case EggPolysetMaker::BN_polyset:
return add_polyset(egg_bin, dx_parent);
return add_polyset(egg_bin, x_parent);
}
xfile_cat.error()
@ -339,11 +197,11 @@ add_bin(EggBin *egg_bin, LPDIRECTXFILEDATA dx_parent) {
// polygons within the indicated bin.
////////////////////////////////////////////////////////////////////
bool XFileMaker::
add_polyset(EggBin *egg_bin, LPDIRECTXFILEDATA dx_parent) {
add_polyset(EggBin *egg_bin, XFileNode *x_parent) {
// Make sure that all our polygons are reasonable.
egg_bin->remove_invalid_primitives();
XFileMesh *mesh = get_mesh(dx_parent);
XFileMesh *mesh = get_mesh(x_parent);
EggGroupNode::iterator ci;
for (ci = egg_bin->begin(); ci != egg_bin->end(); ++ci) {
@ -364,11 +222,11 @@ add_polyset(EggBin *egg_bin, LPDIRECTXFILEDATA dx_parent) {
// the indicated DX object.
////////////////////////////////////////////////////////////////////
bool XFileMaker::
recurse_nodes(EggGroupNode *egg_node, LPDIRECTXFILEDATA dx_parent) {
recurse_nodes(EggGroupNode *egg_node, XFileNode *x_parent) {
EggGroupNode::iterator ci;
for (ci = egg_node->begin(); ci != egg_node->end(); ++ci) {
EggNode *node = (*ci);
if (!add_node(node, dx_parent)) {
EggNode *child = (*ci);
if (!add_node(child, x_parent)) {
return false;
}
}
@ -376,152 +234,24 @@ recurse_nodes(EggGroupNode *egg_node, LPDIRECTXFILEDATA dx_parent) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMaker::create_object
// Access: Private
// Description: Creates a DX data object.
////////////////////////////////////////////////////////////////////
bool XFileMaker::
create_object(LPDIRECTXFILEDATA &obj, REFGUID template_id,
const string &name, const Datagram &dg) {
HRESULT hr;
string nice_name = make_nice_name(name);
int data_size = dg.get_length();
void *data_pointer = (void *)dg.get_data();
if (data_size == 0) {
data_pointer = (void *)NULL;
}
hr = _dx_file_save->CreateDataObject
(template_id, nice_name.c_str(), NULL,
data_size, data_pointer, &obj);
if (hr != DXFILE_OK) {
nout << "Unable to create data object for " << name << "\n";
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMaker::create_frame
// Access: Private
// Description: Creates a "frame" object with the indicated name.
////////////////////////////////////////////////////////////////////
bool XFileMaker::
create_frame(LPDIRECTXFILEDATA &obj, const string &name) {
return create_object(obj, TID_D3DRMFrame, name, Datagram());
}
////////////////////////////////////////////////////////////////////
// Function: XFileMaker::add_frame_transform
// Access: Private
// Description: Adds a transformation matrix to the indicated frame.
////////////////////////////////////////////////////////////////////
bool XFileMaker::
add_frame_transform(LPDIRECTXFILEDATA obj, const LMatrix4f &mat) {
Datagram raw_data;
mat.write_datagram(raw_data);
LPDIRECTXFILEDATA xtransform;
if (!create_object(xtransform, TID_D3DRMFrameTransformMatrix,
"transform", raw_data)) {
return false;
}
if (!attach_and_release(xtransform, obj)) {
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMaker::attach_and_release
// Access: Private
// Description: Assigns the indicated X data object to the indicated
// parent, and releases the pointer.
////////////////////////////////////////////////////////////////////
bool XFileMaker::
attach_and_release(LPDIRECTXFILEDATA obj, LPDIRECTXFILEDATA dx_parent) {
HRESULT hr;
// First, make sure we don't have an outstanding mesh for this
// object.
if (!finalize_mesh(obj)) {
return false;
}
if (dx_parent == NULL) {
// No parent; it's a toplevel object.
hr = _dx_file_save->SaveData(obj);
if (hr != DXFILE_OK) {
nout << "Unable to save data object\n";
obj->Release();
return false;
}
} else {
// Got a parent; it's a child of the indicated object.
hr = dx_parent->AddDataObject(obj);
if (hr != DXFILE_OK) {
nout << "Unable to save data object\n";
obj->Release();
return false;
}
}
obj->Release();
return true;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMaker::make_nice_name
// Access: Private, Static
// Description: Transforms the indicated egg name to a name that is
// acceptable to the DirectX format.
////////////////////////////////////////////////////////////////////
string XFileMaker::
make_nice_name(const string &str) {
string result;
string::const_iterator si;
for (si = str.begin(); si != str.end(); ++si) {
if (isalnum(*si)) {
result += *si;
} else {
result += "_";
}
}
if (!str.empty() && isdigit(str[0])) {
// If the name begins with a digit, we must make it begin with
// something else, like for instance an underscore.
result = '_' + result;
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMaker::get_mesh
// Access: Private
// Description: Returns a suitable XFileMesh object for creating
// meshes within the indicated dx_parent object.
// meshes within the indicated x_parent object.
////////////////////////////////////////////////////////////////////
XFileMesh *XFileMaker::
get_mesh(LPDIRECTXFILEDATA dx_parent) {
Meshes::iterator mi = _meshes.find(dx_parent);
get_mesh(XFileNode *x_parent) {
Meshes::iterator mi = _meshes.find(x_parent);
if (mi != _meshes.end()) {
// We've already started working on this dx_parent before; use the
// We've already started working on this x_parent before; use the
// same mesh object.
return (*mi).second;
}
// We haven't seen this dx_parent before; create a new mesh object.
// We haven't seen this x_parent before; create a new mesh object.
XFileMesh *mesh = new XFileMesh;
_meshes.insert(Meshes::value_type(dx_parent, mesh));
_meshes.insert(Meshes::value_type(x_parent, mesh));
return mesh;
}
@ -529,72 +259,19 @@ get_mesh(LPDIRECTXFILEDATA dx_parent) {
////////////////////////////////////////////////////////////////////
// Function: XFileMaker::finalize_mesh
// Access: Private
// Description: Creates the actual DX mesh object corresponding to
// the indicated dx_parent object.
// Description: Creates the actual X structures corresponding to
// the indicated XFileMesh object.
////////////////////////////////////////////////////////////////////
bool XFileMaker::
finalize_mesh(LPDIRECTXFILEDATA dx_parent) {
Meshes::iterator mi = _meshes.find(dx_parent);
if (mi == _meshes.end()) {
// We haven't got a mesh for this object; do nothing.
return true;
}
XFileMesh *mesh = (*mi).second;
_meshes.erase(mi);
finalize_mesh(XFileNode *x_parent, XFileMesh *mesh) {
// Get a unique number for each mesh.
_mesh_index++;
string mesh_index = format_string(_mesh_index);
// Finally, create the Mesh object.
Datagram raw_data;
mesh->make_mesh_data(raw_data);
LPDIRECTXFILEDATA xobj;
if (!create_object(xobj, TID_D3DRMMesh, "mesh" + mesh_index, raw_data)) {
return false;
}
if (mesh->has_normals()) {
// Tack on normals.
LPDIRECTXFILEDATA xnormals;
mesh->make_normal_data(raw_data);
if (!create_object(xnormals, TID_D3DRMMeshNormals, "norms" + mesh_index,
raw_data)) {
return false;
}
if (!attach_and_release(xnormals, xobj)) {
return false;
}
}
if (mesh->has_colors()) {
// Tack on colors.
LPDIRECTXFILEDATA xcolors;
mesh->make_color_data(raw_data);
if (!create_object(xcolors, TID_D3DRMMeshVertexColors,
"colors" + mesh_index, raw_data)) {
return false;
}
if (!attach_and_release(xcolors, xobj)) {
return false;
}
}
if (mesh->has_uvs()) {
// Tack on texture coordinates.
LPDIRECTXFILEDATA xuvs;
mesh->make_uv_data(raw_data);
if (!create_object(xuvs, TID_D3DRMMeshTextureCoords,
"uvs" + mesh_index, raw_data)) {
return false;
}
if (!attach_and_release(xuvs, xobj)) {
return false;
}
}
mesh->make_x_mesh(x_parent, mesh_index);
/*
if (mesh->has_materials()) {
// Tack on material definitions.
LPDIRECTXFILEDATA xmaterial_list;
@ -643,8 +320,9 @@ finalize_mesh(LPDIRECTXFILEDATA dx_parent) {
}
}
if (!attach_and_release(xobj, dx_parent)) {
if (!attach_and_release(xobj, x_parent)) {
return false;
}
*/
return true;
}

View File

@ -24,13 +24,7 @@
#include "filename.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 "xFile.h"
class EggNode;
class EggGroupNode;
@ -51,37 +45,26 @@ public:
XFileMaker();
~XFileMaker();
bool open(const Filename &filename);
void close();
bool write(const Filename &filename);
bool add_tree(EggData &egg_data);
private:
bool add_node(EggNode *egg_node, LPDIRECTXFILEDATA dx_parent);
bool add_group(EggGroup *egg_group, LPDIRECTXFILEDATA dx_parent);
bool add_bin(EggBin *egg_bin, LPDIRECTXFILEDATA dx_parent);
bool add_polyset(EggBin *egg_bin, LPDIRECTXFILEDATA dx_parent);
bool add_node(EggNode *egg_node, XFileNode *x_parent);
bool add_group(EggGroup *egg_group, XFileNode *x_parent);
bool add_bin(EggBin *egg_bin, XFileNode *x_parent);
bool add_polyset(EggBin *egg_bin, XFileNode *x_parent);
bool recurse_nodes(EggGroupNode *egg_node, LPDIRECTXFILEDATA dx_parent);
bool recurse_nodes(EggGroupNode *egg_node, XFileNode *x_parent);
bool create_object(LPDIRECTXFILEDATA &obj, REFGUID template_id,
const string &name, const Datagram &dg);
bool create_frame(LPDIRECTXFILEDATA &obj, const string &name);
bool add_frame_transform(LPDIRECTXFILEDATA obj, const LMatrix4f &mat);
XFileMesh *get_mesh(XFileNode *x_parent);
bool finalize_mesh(XFileNode *x_parent, XFileMesh *mesh);
bool attach_and_release(LPDIRECTXFILEDATA obj, LPDIRECTXFILEDATA dx_parent);
static string make_nice_name(const string &str);
XFileMesh *get_mesh(LPDIRECTXFILEDATA dx_parent);
bool finalize_mesh(LPDIRECTXFILEDATA dx_parent);
LPDIRECTXFILE _dx_file;
LPDIRECTXFILESAVEOBJECT _dx_file_save;
PT(XFile) _x_file;
int _mesh_index;
typedef pmap<LPDIRECTXFILEDATA, XFileMesh *> Meshes;
typedef pmap<XFileNode *, XFileMesh *> Meshes;
Meshes _meshes;
};

View File

@ -180,63 +180,23 @@ has_texture() const {
}
////////////////////////////////////////////////////////////////////
// Function: XFileMaterial::make_material_data
// Function: XFileMaterial::make_x_material
// Access: Public
// Description: Fills the datagram with the raw data for the DX
// Material template.
// Description: Creates a Material object for the material list.
////////////////////////////////////////////////////////////////////
void XFileMaterial::
make_material_data(Datagram &raw_data) {
raw_data.clear();
raw_data.add_float32(_face_color[0]);
raw_data.add_float32(_face_color[1]);
raw_data.add_float32(_face_color[2]);
raw_data.add_float32(_face_color[3]);
raw_data.add_float32(_power);
raw_data.add_float32(_specular_color[0]);
raw_data.add_float32(_specular_color[1]);
raw_data.add_float32(_specular_color[2]);
raw_data.add_float32(_emissive_color[0]);
raw_data.add_float32(_emissive_color[1]);
raw_data.add_float32(_emissive_color[2]);
}
XFileDataNode *XFileMaterial::
make_x_material(XFileNode *x_meshMaterials, const string &suffix) {
XFileDataNode *x_material =
x_meshMaterials->add_Material("material" + suffix,
_face_color, _power,
_specular_color, _emissive_color);
////////////////////////////////////////////////////////////////////
// Function: XFileMaterial::make_texture_data
// Access: Public
// Description: Fills the datagram with the raw data for the DX
// TextureFilename template.
////////////////////////////////////////////////////////////////////
void XFileMaterial::
make_texture_data(Datagram &raw_data) {
raw_data.clear();
// Convert the filename to an appropriate form for the X file.
string os_filename = _texture.to_os_specific();
// Now we have to double up the backslashes.
string filename;
for (string::const_iterator pi = os_filename.begin();
pi != os_filename.end();
++pi) {
if ((*pi) == '\\') {
filename += '\\';
filename += '\\';
} else {
filename += (*pi);
}
if (has_texture()) {
XFileDataNode *x_texture =
x_material->add_TextureFilename("texture" + suffix, _texture);
}
// Get a char * pointer to the texture filename, to pass into the
// Microsoft DX file interface. Unfortunately, we can't delete this
// again, since it needs to live longer than the life of the
// XFileMaterial object itself, so this becomes a memory leak
// (unless the DX file interface frees it, but the documentation is
// far from clear). Too bad.
char *filename_str = strdup(filename.c_str());
// The Microsoft convention is to stuff a pointer into a four-byte
// field. Not terribly portable, but that's the interface.
raw_data.add_int32((int)filename_str);
return x_material;
}
////////////////////////////////////////////////////////////////////

View File

@ -26,6 +26,8 @@
class EggPrimitive;
class Datagram;
class XFileToEggConverter;
class XFileNode;
class XFileDataNode;
////////////////////////////////////////////////////////////////////
// Class : XFileMaterial
@ -45,9 +47,7 @@ public:
bool has_material() const;
bool has_texture() const;
void make_material_data(Datagram &raw_data);
void make_texture_data(Datagram &raw_data);
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);

View File

@ -21,8 +21,9 @@
#include "xFileVertex.h"
#include "xFileNormal.h"
#include "xFileMaterial.h"
#include "xFileDataNode.h"
#include "config_xfile.h"
#include "string_utils.h"
#include "eggVertexPool.h"
#include "eggVertex.h"
#include "eggPolygon.h"
@ -473,136 +474,184 @@ get_material(int n) const {
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::make_mesh_data
// Function: XFileMesh::make_x_mesh
// Access: Public
// Description: Fills the datagram with the raw data for the DX
// Mesh template.
// Description: Creates an X structure corresponding to the mesh.
////////////////////////////////////////////////////////////////////
void XFileMesh::
make_mesh_data(Datagram &raw_data) {
raw_data.clear();
raw_data.add_int32(_vertices.size());
XFileDataNode *XFileMesh::
make_x_mesh(XFileNode *x_parent, const string &suffix) {
XFileDataNode *x_mesh = x_parent->add_Mesh("mesh" + suffix);
// First, fill in the table of vertices.
XFileDataObject &x_vertices = (*x_mesh)["vertices"];
Vertices::const_iterator vi;
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
XFileVertex *vertex = (*vi);
const Vertexf &point = vertex->_point;
raw_data.add_float32(point[0]);
raw_data.add_float32(point[1]);
raw_data.add_float32(point[2]);
x_vertices.add_Vector(x_mesh->get_x_file(), LCAST(double, vertex->_point));
}
(*x_mesh)["nVertices"] = x_vertices.size();
raw_data.add_int32(_faces.size());
// Then, create the list of faces that index into the above vertices.
XFileDataObject &x_faces = (*x_mesh)["faces"];
Faces::const_iterator fi;
for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
XFileFace *face = (*fi);
raw_data.add_int32(face->_vertices.size());
XFileDataObject &x_mesh_face = x_faces.add_MeshFace(x_mesh->get_x_file());
XFileDataObject &x_faceVertexIndices = x_mesh_face["faceVertexIndices"];
XFileFace::Vertices::const_iterator fvi;
for (fvi = face->_vertices.begin();
fvi != face->_vertices.end();
++fvi) {
raw_data.add_int32((*fvi)._vertex_index);
x_faceVertexIndices.add_int((*fvi)._vertex_index);
}
x_mesh_face["nFaceVertexIndices"] = x_faceVertexIndices.size();
}
(*x_mesh)["nFaces"] = x_faces.size();
// Now, add in any supplemental data.
if (has_normals()) {
// Tack on normals.
make_x_normals(x_mesh, suffix);
}
if (has_colors()) {
// Tack on colors.
make_x_colors(x_mesh, suffix);
}
if (has_uvs()) {
// Tack on uvs.
make_x_uvs(x_mesh, suffix);
}
if (has_materials()) {
// Tack on materials.
make_x_material_list(x_mesh, suffix);
}
return x_mesh;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::make_normal_data
// Function: XFileMesh::make_x_normals
// Access: Public
// Description: Fills the datagram with the raw data for the DX
// MeshNormals template.
// Description: Creates a MeshNormals table for the mesh.
////////////////////////////////////////////////////////////////////
void XFileMesh::
make_normal_data(Datagram &raw_data) {
raw_data.clear();
raw_data.add_int32(_normals.size());
XFileDataNode *XFileMesh::
make_x_normals(XFileNode *x_mesh, const string &suffix) {
XFileDataNode *x_meshNormals = x_mesh->add_MeshNormals("norms" + suffix);
XFileDataObject &x_normals = (*x_meshNormals)["normals"];
Normals::const_iterator ni;
for (ni = _normals.begin(); ni != _normals.end(); ++ni) {
XFileNormal *normal = (*ni);
const Normalf &norm = normal->_normal;
raw_data.add_float32(norm[0]);
raw_data.add_float32(norm[1]);
raw_data.add_float32(norm[2]);
x_normals.add_Vector(x_mesh->get_x_file(), LCAST(double, normal->_normal));
}
(*x_meshNormals)["nNormals"] = x_normals.size();
raw_data.add_int32(_faces.size());
// Then, create the list of faces that index into the above normals.
XFileDataObject &x_faces = (*x_meshNormals)["faceNormals"];
Faces::const_iterator fi;
for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
XFileFace *face = (*fi);
raw_data.add_int32(face->_vertices.size());
XFileDataObject &x_normals_face = x_faces.add_MeshFace(x_mesh->get_x_file());
XFileDataObject &x_faceVertexIndices = x_normals_face["faceVertexIndices"];
XFileFace::Vertices::const_iterator fvi;
for (fvi = face->_vertices.begin();
fvi != face->_vertices.end();
++fvi) {
raw_data.add_int32((*fvi)._normal_index);
x_faceVertexIndices.add_int((*fvi)._normal_index);
}
x_normals_face["nFaceVertexIndices"] = x_faceVertexIndices.size();
}
(*x_meshNormals)["nFaceNormals"] = x_faces.size();
return x_meshNormals;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::make_color_data
// Function: XFileMesh::make_x_colors
// Access: Public
// Description: Fills the datagram with the raw data for the DX
// MeshVertexColors template.
// Description: Creates a MeshVertexColors table for the mesh.
////////////////////////////////////////////////////////////////////
void XFileMesh::
make_color_data(Datagram &raw_data) {
raw_data.clear();
raw_data.add_int32(_vertices.size());
XFileDataNode *XFileMesh::
make_x_colors(XFileNode *x_mesh, const string &suffix) {
XFileDataNode *x_meshColors = x_mesh->add_MeshVertexColors("colors" + suffix);
XFileDataObject &x_colors = (*x_meshColors)["vertexColors"];
Vertices::const_iterator vi;
int i = 0;
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
XFileVertex *vertex = (*vi);
const Colorf &color = vertex->_color;
raw_data.add_int32(i);
raw_data.add_float32(color[0]);
raw_data.add_float32(color[1]);
raw_data.add_float32(color[2]);
raw_data.add_float32(color[3]);
x_colors.add_IndexedColor(x_mesh->get_x_file(), i, color);
i++;
}
(*x_meshColors)["nVertexColors"] = x_colors.size();
return x_meshColors;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::make_uv_data
// Function: XFileMesh::make_x_uvs
// Access: Public
// Description: Fills the datagram with the raw data for the DX
// MeshTextureCoords template.
// Description: Creates a MeshTextureCoords table for the mesh.
////////////////////////////////////////////////////////////////////
void XFileMesh::
make_uv_data(Datagram &raw_data) {
raw_data.clear();
raw_data.add_int32(_vertices.size());
XFileDataNode *XFileMesh::
make_x_uvs(XFileNode *x_mesh, const string &suffix) {
XFileDataNode *x_meshUvs = x_mesh->add_MeshTextureCoords("uvs" + suffix);
XFileDataObject &x_uvs = (*x_meshUvs)["textureCoords"];
Vertices::const_iterator vi;
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
XFileVertex *vertex = (*vi);
const TexCoordf &uv = vertex->_uv;
raw_data.add_float32(uv[0]);
raw_data.add_float32(uv[1]);
x_uvs.add_Coords2d(x_mesh->get_x_file(), LCAST(double, vertex->_uv));
}
(*x_meshUvs)["nTextureCoords"] = x_uvs.size();
return x_meshUvs;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::make_material_list_data
// Function: XFileMesh::make_x_material_list
// Access: Public
// Description: Fills the datagram with the raw data for the DX
// MeshMaterialList template.
// Description: Creates a MeshMaterialList table for the mesh.
////////////////////////////////////////////////////////////////////
void XFileMesh::
make_material_list_data(Datagram &raw_data) {
raw_data.clear();
raw_data.add_int32(_materials.size());
raw_data.add_int32(_faces.size());
XFileDataNode *XFileMesh::
make_x_material_list(XFileNode *x_mesh, const string &suffix) {
XFileDataNode *x_meshMaterials =
x_mesh->add_MeshMaterialList("materials" + suffix);
// First, build up the list of faces the reference the materials.
XFileDataObject &x_indexes = (*x_meshMaterials)["faceIndexes"];
Faces::const_iterator fi;
for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
XFileFace *face = (*fi);
raw_data.add_int32(face->_material_index);
x_indexes.add_int(face->_material_index);
}
(*x_meshMaterials)["nFaceIndexes"] = x_indexes.size();
// Now, build up the list of materials themselves. Each material is
// a child of the MeshMaterialList node, rather than an element of
// an array.
for (size_t i = 0; i < _materials.size(); i++) {
XFileMaterial *material = _materials[i];
material->make_x_material(x_meshMaterials,
suffix + "_" + format_string(i));
}
(*x_meshMaterials)["nMaterials"] = (int)_materials.size();
return x_meshMaterials;
}
////////////////////////////////////////////////////////////////////

View File

@ -26,12 +26,14 @@
#include "namable.h"
#include "coordinateSystem.h"
class XFileNode;
class XFileMesh;
class XFileVertex;
class XFileNormal;
class XFileMaterial;
class XFileFace;
class XFileToEggConverter;
class XFileDataNode;
class EggGroupNode;
class EggVertex;
class EggPolygon;
@ -70,11 +72,11 @@ public:
int get_num_materials() const;
XFileMaterial *get_material(int n) const;
void make_mesh_data(Datagram &raw_data);
void make_normal_data(Datagram &raw_data);
void make_color_data(Datagram &raw_data);
void make_uv_data(Datagram &raw_data);
void make_material_list_data(Datagram &raw_data);
XFileDataNode *make_x_mesh(XFileNode *x_parent, const string &suffix);
XFileDataNode *make_x_normals(XFileNode *x_mesh, const string &suffix);
XFileDataNode *make_x_colors(XFileNode *x_mesh, const string &suffix);
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);

View File

@ -60,11 +60,6 @@ EggToX() : EggToSomething("DirectX", ".x", true, false) {
////////////////////////////////////////////////////////////////////
void EggToX::
run() {
if (!_x.open(get_output_filename())) {
nout << "Unable to open " << get_output_filename() << " for output.\n";
exit(1);
}
if (!do_reader_options()) {
exit(1);
}
@ -74,7 +69,10 @@ run() {
exit(1);
}
_x.close();
if (!_x.write(get_output_filename())) {
nout << "Unable to write " << get_output_filename() << ".\n";
exit(1);
}
}