egg2x now uses native parser
This commit is contained in:
parent
b9b7ddec00
commit
bcbe9bb30c
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue