*** empty log message ***
This commit is contained in:
parent
a98fd52495
commit
3bd11c3cda
|
|
@ -15,13 +15,46 @@
|
|||
|
||||
#define SOURCES \
|
||||
xFileFace.cxx xFileFace.h \
|
||||
xFileMaker.cxx xFileMaker.h \
|
||||
xFileMaterial.cxx xFileMaterial.h \
|
||||
xFileMesh.cxx xFileMesh.h \
|
||||
xFileNormal.cxx xFileNormal.h \
|
||||
xFileVertex.cxx xFileVertex.h
|
||||
|
||||
#define SOURCES \
|
||||
$[SOURCES] \
|
||||
xFileMaker.cxx xFileMaker.h
|
||||
|
||||
#define SOURCES \
|
||||
$[SOURCES] \
|
||||
eggToX.cxx eggToX.h
|
||||
|
||||
#end bin_target
|
||||
|
||||
#begin bin_target
|
||||
#define TARGET x2egg
|
||||
#define LOCAL_LIBS converter eggbase progbase pandatoolbase
|
||||
#define OTHER_LIBS \
|
||||
egg:c pandaegg:m \
|
||||
mathutil:c linmath:c putil:c panda:m \
|
||||
express:c pandaexpress:m \
|
||||
dtoolconfig dtool pystub \
|
||||
|
||||
#define WIN_SYS_LIBS \
|
||||
d3dxof.lib
|
||||
|
||||
#define SOURCES \
|
||||
xFileFace.cxx xFileFace.h \
|
||||
xFileMaterial.cxx xFileMaterial.h \
|
||||
xFileMesh.cxx xFileMesh.h \
|
||||
xFileNormal.cxx xFileNormal.h \
|
||||
xFileVertex.cxx xFileVertex.h
|
||||
|
||||
#define SOURCES \
|
||||
$[SOURCES] \
|
||||
xFileToEggConverter.cxx xFileToEggConverter.h
|
||||
|
||||
#define SOURCES \
|
||||
$[SOURCES] \
|
||||
xFileToEgg.cxx xFileToEgg.h
|
||||
|
||||
#end bin_target
|
||||
|
|
|
|||
|
|
@ -26,7 +26,17 @@
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileFace::
|
||||
XFileFace(XFileMesh *mesh, EggPolygon *egg_poly) {
|
||||
XFileFace() {
|
||||
_material_index = -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileFace::set_from_egg
|
||||
// Access: Public
|
||||
// Description: Sets the structure up from the indicated egg data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileFace::
|
||||
set_from_egg(XFileMesh *mesh, EggPolygon *egg_poly) {
|
||||
// Walk through the polygon's vertices in reverse order, to change
|
||||
// from Egg's counter-clockwise convention to DX's clockwise.
|
||||
EggPolygon::reverse_iterator vi;
|
||||
|
|
@ -37,4 +47,6 @@ XFileFace(XFileMesh *mesh, EggPolygon *egg_poly) {
|
|||
v._normal_index = mesh->add_normal(egg_vertex, egg_poly);
|
||||
_vertices.push_back(v);
|
||||
}
|
||||
|
||||
_material_index = mesh->add_material(egg_poly);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ class EggPolygon;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class XFileFace {
|
||||
public:
|
||||
XFileFace(XFileMesh *mesh, EggPolygon *egg_poly);
|
||||
XFileFace();
|
||||
void set_from_egg(XFileMesh *mesh, EggPolygon *egg_poly);
|
||||
|
||||
class Vertex {
|
||||
public:
|
||||
|
|
@ -40,6 +41,8 @@ public:
|
|||
};
|
||||
typedef pvector<Vertex> Vertices;
|
||||
Vertices _vertices;
|
||||
|
||||
int _material_index;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include "xFileMaker.h"
|
||||
#include "xFileMesh.h"
|
||||
#include "xFileMaterial.h"
|
||||
|
||||
#include "notify.h"
|
||||
#include "eggGroupNode.h"
|
||||
#include "eggGroup.h"
|
||||
|
|
@ -305,6 +307,54 @@ add_polyset(EggBin *egg_bin, LPDIRECTXFILEDATA dx_parent) {
|
|||
}
|
||||
}
|
||||
|
||||
if (mesh.has_materials()) {
|
||||
// Tack on material definitions.
|
||||
LPDIRECTXFILEDATA xmaterial_list;
|
||||
mesh.make_material_list_data(raw_data);
|
||||
if (!create_object(xmaterial_list, TID_D3DRMMeshMaterialList,
|
||||
"materials" + mesh_index, raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we need to iterate through the list of Materials
|
||||
// themselves, and add *these* as children of the material list.
|
||||
int num_materials = mesh.get_num_materials();
|
||||
for (int i = 0; i < num_materials; i++) {
|
||||
XFileMaterial *material = mesh.get_material(i);
|
||||
LPDIRECTXFILEDATA xmaterial;
|
||||
material->make_material_data(raw_data);
|
||||
if (!create_object(xmaterial, TID_D3DRMMaterial,
|
||||
"material" + mesh_index + "_" + format_string(i),
|
||||
raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Also, if the Material has a texture map, we must add *this*
|
||||
// as a child of the material. What a weird system.
|
||||
if (material->has_texture()) {
|
||||
LPDIRECTXFILEDATA xtexture;
|
||||
material->make_texture_data(raw_data);
|
||||
if (!create_object(xtexture, TID_D3DRMTextureFilename,
|
||||
"texture" + mesh_index + "_" + format_string(i),
|
||||
raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!attach_and_release(xtexture, xmaterial)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!attach_and_release(xmaterial, xmaterial_list)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!attach_and_release(xmaterial_list, xobj)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!attach_and_release(xobj, dx_parent)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,284 @@
|
|||
// Filename: xFileMaterial.cxx
|
||||
// Created by: drose (19Jun01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "xFileMaterial.h"
|
||||
|
||||
#include "eggMaterial.h"
|
||||
#include "eggTexture.h"
|
||||
#include "eggMaterialCollection.h"
|
||||
#include "eggTextureCollection.h"
|
||||
#include "eggPrimitive.h"
|
||||
#include "datagram.h"
|
||||
|
||||
#include <string.h> // for strcmp, strdup
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMaterial::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileMaterial::
|
||||
XFileMaterial() {
|
||||
_face_color.set(1.0, 1.0, 1.0, 1.0);
|
||||
_specular_color.set(0.0, 0.0, 0.0);
|
||||
_emissive_color.set(0.0, 0.0, 0.0);
|
||||
_power = 64.0;
|
||||
|
||||
_has_material = false;
|
||||
_has_texture = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMaterial::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileMaterial::
|
||||
~XFileMaterial() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMaterial::set_from_egg
|
||||
// Access: Public
|
||||
// Description: Sets the structure up from the indicated egg data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileMaterial::
|
||||
set_from_egg(EggPrimitive *egg_prim) {
|
||||
// First, determine the face color.
|
||||
if (egg_prim->has_color()) {
|
||||
_face_color = egg_prim->get_color();
|
||||
_has_material = true;
|
||||
}
|
||||
|
||||
// Do we have an actual EggMaterial, to control lighting effects?
|
||||
if (egg_prim->has_material()) {
|
||||
_has_material = true;
|
||||
EggMaterial *egg_mat = egg_prim->get_material();
|
||||
if (egg_mat->has_diff()) {
|
||||
_face_color = egg_mat->get_diff();
|
||||
}
|
||||
if (egg_mat->has_spec()) {
|
||||
const Colorf &spec = egg_mat->get_spec();
|
||||
_specular_color.set(spec[0], spec[1], spec[2]);
|
||||
}
|
||||
if (egg_mat->has_emit()) {
|
||||
const Colorf &emit = egg_mat->get_emit();
|
||||
_emissive_color.set(emit[0], emit[1], emit[2]);
|
||||
}
|
||||
if (egg_mat->has_shininess()) {
|
||||
_power = egg_mat->get_shininess();
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, if we also have a texture, record that.
|
||||
if (egg_prim->has_texture()) {
|
||||
_has_material = true;
|
||||
_has_texture = true;
|
||||
EggTexture *egg_tex = egg_prim->get_texture();
|
||||
_texture = egg_tex->get_filename();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMaterial::apply_to_egg
|
||||
// Access: Public
|
||||
// Description: Applies the properties in the material to the
|
||||
// indicated egg primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileMaterial::
|
||||
apply_to_egg(EggPrimitive *egg_prim,
|
||||
EggTextureCollection &textures,
|
||||
EggMaterialCollection &materials) {
|
||||
// Is there a texture?
|
||||
if (_has_texture) {
|
||||
EggTexture temp("", _texture);
|
||||
EggTexture *egg_tex =
|
||||
textures.create_unique_texture(temp, ~EggTexture::E_tref_name);
|
||||
egg_prim->set_texture(egg_tex);
|
||||
}
|
||||
|
||||
// Are there any fancy lighting effects?
|
||||
bool got_spec = (_specular_color != RGBColorf::zero());
|
||||
bool got_emit = (_emissive_color != RGBColorf::zero());
|
||||
if (got_spec || got_emit) {
|
||||
EggMaterial temp("");
|
||||
temp.set_diff(_face_color);
|
||||
if (got_spec) {
|
||||
temp.set_shininess(_power);
|
||||
temp.set_spec(Colorf(_specular_color[0], _specular_color[1],
|
||||
_specular_color[2], 1.0));
|
||||
}
|
||||
if (got_emit) {
|
||||
temp.set_emit(Colorf(_emissive_color[0], _emissive_color[1],
|
||||
_emissive_color[2], 1.0));
|
||||
}
|
||||
EggMaterial *egg_mat =
|
||||
materials.create_unique_material(temp, ~EggMaterial::E_mref_name);
|
||||
egg_prim->set_material(egg_mat);
|
||||
}
|
||||
|
||||
// Also apply the face color.
|
||||
egg_prim->set_color(_face_color);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMaterial::compare_to
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int XFileMaterial::
|
||||
compare_to(const XFileMaterial &other) const {
|
||||
int ct;
|
||||
ct = _face_color.compare_to(other._face_color);
|
||||
if (ct == 0) {
|
||||
ct = (_power == other._power) ? 0 : ((_power < other._power) ? -1 : 1);
|
||||
}
|
||||
if (ct == 0) {
|
||||
ct = _specular_color.compare_to(other._specular_color);
|
||||
}
|
||||
if (ct == 0) {
|
||||
ct = _emissive_color.compare_to(other._emissive_color);
|
||||
}
|
||||
if (ct == 0) {
|
||||
ct = strcmp(_texture.c_str(), other._texture.c_str());
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMaterial::has_material
|
||||
// Access: Public
|
||||
// Description: Returns true if this material represents something
|
||||
// meaningful, or false if the default material is
|
||||
// sufficient.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileMaterial::
|
||||
has_material() const {
|
||||
return _has_material;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMaterial::has_texture
|
||||
// Access: Public
|
||||
// Description: Returns true if this material includes a texture map,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileMaterial::
|
||||
has_texture() const {
|
||||
return _has_texture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMaterial::make_material_data
|
||||
// Access: Public
|
||||
// Description: Fills the datagram with the raw data for the DX
|
||||
// Material template.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
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]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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();
|
||||
|
||||
// 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.
|
||||
string filename = _texture.to_os_specific();
|
||||
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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMaterial::read_material_data
|
||||
// Access: Public
|
||||
// Description: Fills the structure based on the raw data from the
|
||||
// Material template.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileMaterial::
|
||||
read_material_data(const Datagram &raw_data) {
|
||||
DatagramIterator di(raw_data);
|
||||
|
||||
_face_color[0] = di.get_float32();
|
||||
_face_color[1] = di.get_float32();
|
||||
_face_color[2] = di.get_float32();
|
||||
_face_color[3] = di.get_float32();
|
||||
_power = di.get_float32();
|
||||
_specular_color[0] = di.get_float32();
|
||||
_specular_color[1] = di.get_float32();
|
||||
_specular_color[2] = di.get_float32();
|
||||
_emissive_color[0] = di.get_float32();
|
||||
_emissive_color[1] = di.get_float32();
|
||||
_emissive_color[2] = di.get_float32();
|
||||
_has_material = true;
|
||||
|
||||
if (di.get_remaining_size() != 0) {
|
||||
cerr << "Ignoring " << di.get_remaining_size()
|
||||
<< " trailing MeshMaterial.\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMaterial::read_texture_data
|
||||
// Access: Public
|
||||
// Description: Fills the structure based on the raw data from the
|
||||
// TextureFilename template.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileMaterial::
|
||||
read_texture_data(const Datagram &raw_data) {
|
||||
DatagramIterator di(raw_data);
|
||||
|
||||
// The Microsoft convention is to stuff a pointer into a four-byte
|
||||
// field. Not terribly portable, but that's the interface.
|
||||
const char *ptr = (const char *)di.get_int32();
|
||||
_texture = ptr;
|
||||
_has_texture = true;
|
||||
|
||||
if (di.get_remaining_size() != 0) {
|
||||
cerr << "Ignoring " << di.get_remaining_size()
|
||||
<< " trailing MeshMaterial.\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
// Filename: xFileMaterial.h
|
||||
// Created by: drose (19Jun01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef XFILEMATERIAL_H
|
||||
#define XFILEMATERIAL_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "luse.h"
|
||||
#include "filename.h"
|
||||
|
||||
class EggPrimitive;
|
||||
class EggTextureCollection;
|
||||
class EggMaterialCollection;
|
||||
class Datagram;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileMaterial
|
||||
// Description : This represents an X file "material", which consists
|
||||
// of a color, lighting, and/or texture specification.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileMaterial {
|
||||
public:
|
||||
XFileMaterial();
|
||||
~XFileMaterial();
|
||||
|
||||
void set_from_egg(EggPrimitive *egg_prim);
|
||||
void apply_to_egg(EggPrimitive *egg_prim,
|
||||
EggTextureCollection &textures,
|
||||
EggMaterialCollection &materials);
|
||||
|
||||
int compare_to(const XFileMaterial &other) const;
|
||||
|
||||
bool has_material() const;
|
||||
bool has_texture() const;
|
||||
|
||||
void make_material_data(Datagram &raw_data);
|
||||
void make_texture_data(Datagram &raw_data);
|
||||
|
||||
bool read_material_data(const Datagram &raw_data);
|
||||
bool read_texture_data(const Datagram &raw_data);
|
||||
|
||||
private:
|
||||
Colorf _face_color;
|
||||
float _power;
|
||||
RGBColorf _specular_color;
|
||||
RGBColorf _emissive_color;
|
||||
Filename _texture;
|
||||
|
||||
bool _has_material;
|
||||
bool _has_texture;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -20,6 +20,12 @@
|
|||
#include "xFileFace.h"
|
||||
#include "xFileVertex.h"
|
||||
#include "xFileNormal.h"
|
||||
#include "xFileMaterial.h"
|
||||
|
||||
#include "eggVertexPool.h"
|
||||
#include "eggVertex.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "eggGroupNode.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::Constructor
|
||||
|
|
@ -31,6 +37,7 @@ XFileMesh() {
|
|||
_has_normals = false;
|
||||
_has_colors = false;
|
||||
_has_uvs = false;
|
||||
_has_materials = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -40,6 +47,16 @@ XFileMesh() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
XFileMesh::
|
||||
~XFileMesh() {
|
||||
clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::clear
|
||||
// Access: Public
|
||||
// Description: Empties all data from the mesh.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileMesh::
|
||||
clear() {
|
||||
Vertices::iterator vi;
|
||||
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
|
||||
XFileVertex *vertex = (*vi);
|
||||
|
|
@ -50,6 +67,25 @@ XFileMesh::
|
|||
XFileNormal *normal = (*ni);
|
||||
delete normal;
|
||||
}
|
||||
Materials::iterator mi;
|
||||
for (mi = _materials.begin(); mi != _materials.end(); ++mi) {
|
||||
XFileMaterial *material = (*mi);
|
||||
delete material;
|
||||
}
|
||||
Faces::iterator fi;
|
||||
for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
|
||||
XFileFace *face = (*fi);
|
||||
delete face;
|
||||
}
|
||||
|
||||
_vertices.clear();
|
||||
_normals.clear();
|
||||
_materials.clear();
|
||||
_faces.clear();
|
||||
|
||||
_unique_vertices.clear();
|
||||
_unique_normals.clear();
|
||||
_unique_materials.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -59,7 +95,8 @@ XFileMesh::
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void XFileMesh::
|
||||
add_polygon(EggPolygon *egg_poly) {
|
||||
XFileFace *face = new XFileFace(this, egg_poly);
|
||||
XFileFace *face = new XFileFace;
|
||||
face->set_from_egg(this, egg_poly);
|
||||
_faces.push_back(face);
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +110,8 @@ add_polygon(EggPolygon *egg_poly) {
|
|||
int XFileMesh::
|
||||
add_vertex(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
|
||||
int next_index = _vertices.size();
|
||||
XFileVertex *vertex = new XFileVertex(egg_vertex, egg_prim);
|
||||
XFileVertex *vertex = new XFileVertex;
|
||||
vertex->set_from_egg(egg_vertex, egg_prim);
|
||||
if (vertex->_has_color) {
|
||||
_has_colors = true;
|
||||
}
|
||||
|
|
@ -107,7 +145,8 @@ add_vertex(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
|
|||
int XFileMesh::
|
||||
add_normal(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
|
||||
int next_index = _normals.size();
|
||||
XFileNormal *normal = new XFileNormal(egg_vertex, egg_prim);
|
||||
XFileNormal *normal = new XFileNormal;
|
||||
normal->set_from_egg(egg_vertex, egg_prim);
|
||||
if (normal->_has_normal) {
|
||||
_has_normals = true;
|
||||
}
|
||||
|
|
@ -127,6 +166,156 @@ add_normal(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::add_material
|
||||
// Access: Public
|
||||
// Description: Creates a new XFileMaterial, if one does not already
|
||||
// exist for the indicated material, and returns its
|
||||
// index.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int XFileMesh::
|
||||
add_material(EggPrimitive *egg_prim) {
|
||||
int next_index = _materials.size();
|
||||
XFileMaterial *material = new XFileMaterial;
|
||||
material->set_from_egg(egg_prim);
|
||||
if (material->has_material()) {
|
||||
_has_materials = true;
|
||||
}
|
||||
|
||||
pair<UniqueMaterials::iterator, bool> result =
|
||||
_unique_materials.insert(UniqueMaterials::value_type(material, next_index));
|
||||
|
||||
if (result.second) {
|
||||
// Successfully added; this is a new material.
|
||||
_materials.push_back(material);
|
||||
return next_index;
|
||||
} else {
|
||||
// Not successfully added; there is already a material with these
|
||||
// properties. Return that one instead.
|
||||
delete material;
|
||||
return (*result.first).second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::add_vertex
|
||||
// Access: Public
|
||||
// Description: Adds the newly-created XFileVertex unequivocally to
|
||||
// the mesh, returning its index number. The XFileMesh
|
||||
// object becomes the owner of the XFileVertex
|
||||
// pointer, and will delete it when it destructs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int XFileMesh::
|
||||
add_vertex(XFileVertex *vertex) {
|
||||
int next_index = _vertices.size();
|
||||
_unique_vertices.insert(UniqueVertices::value_type(vertex, next_index));
|
||||
_vertices.push_back(vertex);
|
||||
return next_index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::add_normal
|
||||
// Access: Public
|
||||
// Description: Adds the newly-created XFileNormal unequivocally to
|
||||
// the mesh, returning its index number. The XFileMesh
|
||||
// object becomes the owner of the XFileNormal
|
||||
// pointer, and will delete it when it destructs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int XFileMesh::
|
||||
add_normal(XFileNormal *normal) {
|
||||
int next_index = _normals.size();
|
||||
_unique_normals.insert(UniqueNormals::value_type(normal, next_index));
|
||||
_normals.push_back(normal);
|
||||
return next_index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::add_material
|
||||
// Access: Public
|
||||
// Description: Adds the newly-created XFileMaterial unequivocally to
|
||||
// the mesh, returning its index number. The XFileMesh
|
||||
// object becomes the owner of the XFileMaterial
|
||||
// pointer, and will delete it when it destructs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int XFileMesh::
|
||||
add_material(XFileMaterial *material) {
|
||||
int next_index = _materials.size();
|
||||
_unique_materials.insert(UniqueMaterials::value_type(material, next_index));
|
||||
_materials.push_back(material);
|
||||
return next_index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::create_polygons
|
||||
// Access: Public
|
||||
// Description: Creates a slew of EggPolygons according to the faces
|
||||
// in the mesh, and adds them to the indicated parent
|
||||
// node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileMesh::
|
||||
create_polygons(EggGroupNode *egg_parent,
|
||||
EggTextureCollection &textures,
|
||||
EggMaterialCollection &materials) {
|
||||
EggVertexPool *vpool = new EggVertexPool(get_name());
|
||||
egg_parent->add_child(vpool);
|
||||
Faces::const_iterator fi;
|
||||
for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
|
||||
XFileFace *face = (*fi);
|
||||
|
||||
EggPolygon *egg_poly = new EggPolygon;
|
||||
egg_parent->add_child(egg_poly);
|
||||
|
||||
// Set up the vertices for the polygon.
|
||||
XFileFace::Vertices::reverse_iterator vi;
|
||||
for (vi = face->_vertices.rbegin(); vi != face->_vertices.rend(); ++vi) {
|
||||
int vertex_index = (*vi)._vertex_index;
|
||||
int normal_index = (*vi)._normal_index;
|
||||
if (vertex_index < 0 || vertex_index >= (int)_vertices.size()) {
|
||||
cerr << "Vertex index out of range in Mesh.\n";
|
||||
return false;
|
||||
}
|
||||
XFileVertex *vertex = _vertices[vertex_index];
|
||||
XFileNormal *normal = (XFileNormal *)NULL;
|
||||
|
||||
if (normal_index >= 0 && normal_index < (int)_normals.size()) {
|
||||
normal = _normals[normal_index];
|
||||
}
|
||||
|
||||
// Create a temporary EggVertex before adding it to the pool.
|
||||
EggVertex temp_vtx;
|
||||
temp_vtx.set_pos(LCAST(double, vertex->_point));
|
||||
if (vertex->_has_color) {
|
||||
temp_vtx.set_color(vertex->_color);
|
||||
}
|
||||
if (vertex->_has_uv) {
|
||||
TexCoordd uv = LCAST(double, vertex->_uv);
|
||||
// Windows draws the UV's upside-down.
|
||||
uv[1] = 1.0 - uv[1];
|
||||
temp_vtx.set_uv(uv);
|
||||
}
|
||||
|
||||
if (normal != (XFileNormal *)NULL && normal->_has_normal) {
|
||||
temp_vtx.set_normal(LCAST(double, normal->_normal));
|
||||
}
|
||||
|
||||
// Now get a real EggVertex matching our template.
|
||||
EggVertex *egg_vtx = vpool->create_unique_vertex(temp_vtx);
|
||||
egg_poly->add_vertex(egg_vtx);
|
||||
}
|
||||
|
||||
// And apply the material for the polygon.
|
||||
int material_index = face->_material_index;
|
||||
if (material_index >= 0 && material_index < (int)_materials.size()) {
|
||||
XFileMaterial *material = _materials[material_index];
|
||||
material->apply_to_egg(egg_poly, textures, materials);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::has_normals
|
||||
// Access: Public
|
||||
|
|
@ -160,6 +349,40 @@ has_uvs() const {
|
|||
return _has_uvs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::has_materials
|
||||
// Access: Public
|
||||
// Description: Returns true if any of the faces added to this mesh
|
||||
// used a real material, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileMesh::
|
||||
has_materials() const {
|
||||
return _has_materials;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::get_num_materials
|
||||
// Access: Public
|
||||
// Description: Returns the number of distinct materials associated
|
||||
// with the mesh.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int XFileMesh::
|
||||
get_num_materials() const {
|
||||
return _materials.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::get_material
|
||||
// Access: Public
|
||||
// Description: Returns a pointer to the nth materials associated
|
||||
// with the mesh.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileMaterial *XFileMesh::
|
||||
get_material(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_materials.size(), (XFileMaterial *)NULL);
|
||||
return _materials[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::make_mesh_data
|
||||
// Access: Public
|
||||
|
|
@ -274,3 +497,222 @@ make_uv_data(Datagram &raw_data) {
|
|||
raw_data.add_float32(uv[1]);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::make_material_list_data
|
||||
// Access: Public
|
||||
// Description: Fills the datagram with the raw data for the DX
|
||||
// MeshMaterialList template.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileMesh::
|
||||
make_material_list_data(Datagram &raw_data) {
|
||||
raw_data.clear();
|
||||
raw_data.add_int32(_materials.size());
|
||||
raw_data.add_int32(_faces.size());
|
||||
Faces::const_iterator fi;
|
||||
for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
|
||||
XFileFace *face = (*fi);
|
||||
raw_data.add_int32(face->_material_index);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::read_mesh_data
|
||||
// Access: Public
|
||||
// Description: Fills the structure based on the raw data from the
|
||||
// Mesh template.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileMesh::
|
||||
read_mesh_data(const Datagram &raw_data) {
|
||||
DatagramIterator di(raw_data);
|
||||
|
||||
clear();
|
||||
|
||||
int i, j;
|
||||
int num_vertices = di.get_int32();
|
||||
for (i = 0; i < num_vertices; i++) {
|
||||
XFileVertex *vertex = new XFileVertex;
|
||||
vertex->_point[0] = di.get_float32();
|
||||
vertex->_point[1] = di.get_float32();
|
||||
vertex->_point[2] = di.get_float32();
|
||||
add_vertex(vertex);
|
||||
}
|
||||
|
||||
int num_faces = di.get_int32();
|
||||
for (i = 0; i < num_faces; i++) {
|
||||
XFileFace *face = new XFileFace;
|
||||
|
||||
num_vertices = di.get_int32();
|
||||
for (j = 0; j < num_vertices; j++) {
|
||||
XFileFace::Vertex vertex;
|
||||
vertex._vertex_index = di.get_int32();
|
||||
vertex._normal_index = -1;
|
||||
|
||||
face->_vertices.push_back(vertex);
|
||||
}
|
||||
_faces.push_back(face);
|
||||
}
|
||||
|
||||
if (di.get_remaining_size() != 0) {
|
||||
cerr << "Ignoring " << di.get_remaining_size() << " trailing Mesh.\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::read_normal_data
|
||||
// Access: Public
|
||||
// Description: Fills the structure based on the raw data from the
|
||||
// MeshNormals template.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileMesh::
|
||||
read_normal_data(const Datagram &raw_data) {
|
||||
DatagramIterator di(raw_data);
|
||||
|
||||
int num_normals = di.get_int32();
|
||||
int i;
|
||||
for (i = 0; i < num_normals; i++) {
|
||||
XFileNormal *normal = new XFileNormal;
|
||||
normal->_normal[0] = di.get_float32();
|
||||
normal->_normal[1] = di.get_float32();
|
||||
normal->_normal[2] = di.get_float32();
|
||||
normal->_has_normal = true;
|
||||
add_normal(normal);
|
||||
}
|
||||
|
||||
int num_faces = di.get_int32();
|
||||
|
||||
if (num_faces != _faces.size()) {
|
||||
cerr << "Incorrect number of faces in MeshNormals.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_faces; i++) {
|
||||
XFileFace *face = _faces[i];
|
||||
int num_vertices = di.get_int32();
|
||||
if (num_vertices != face->_vertices.size()) {
|
||||
cerr << "Incorrect number of vertices for face in MeshNormals.\n";
|
||||
return false;
|
||||
}
|
||||
for (int j = 0; j < num_vertices; j++) {
|
||||
face->_vertices[j]._normal_index = di.get_int32();
|
||||
}
|
||||
}
|
||||
|
||||
if (di.get_remaining_size() != 0) {
|
||||
cerr << "Ignoring " << di.get_remaining_size()
|
||||
<< " trailing MeshNormals.\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::read_color_data
|
||||
// Access: Public
|
||||
// Description: Fills the structure based on the raw data from the
|
||||
// MeshVertexColors template.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileMesh::
|
||||
read_color_data(const Datagram &raw_data) {
|
||||
DatagramIterator di(raw_data);
|
||||
|
||||
int num_colors = di.get_int32();
|
||||
int i;
|
||||
for (i = 0; i < num_colors; i++) {
|
||||
int vertex_index = di.get_int32();
|
||||
if (vertex_index < 0 || vertex_index >= _vertices.size()) {
|
||||
cerr << "Vertex index out of range in MeshVertexColors.\n";
|
||||
return false;
|
||||
}
|
||||
XFileVertex *vertex = _vertices[vertex_index];
|
||||
vertex->_color[0] = di.get_float32();
|
||||
vertex->_color[1] = di.get_float32();
|
||||
vertex->_color[2] = di.get_float32();
|
||||
vertex->_color[3] = di.get_float32();
|
||||
vertex->_has_color = true;
|
||||
}
|
||||
|
||||
if (di.get_remaining_size() != 0) {
|
||||
cerr << "Ignoring " << di.get_remaining_size()
|
||||
<< " trailing MeshVertexColors.\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::read_uv_data
|
||||
// Access: Public
|
||||
// Description: Fills the structure based on the raw data from the
|
||||
// MeshTextureCoords template.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileMesh::
|
||||
read_uv_data(const Datagram &raw_data) {
|
||||
DatagramIterator di(raw_data);
|
||||
|
||||
int num_vertices = di.get_int32();
|
||||
if (num_vertices != _vertices.size()) {
|
||||
cerr << "Wrong number of vertices in MeshTextureCoords.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < num_vertices; i++) {
|
||||
XFileVertex *vertex = _vertices[i];
|
||||
vertex->_uv[0] = di.get_float32();
|
||||
vertex->_uv[1] = di.get_float32();
|
||||
vertex->_has_uv = true;
|
||||
}
|
||||
|
||||
if (di.get_remaining_size() != 0) {
|
||||
cerr << "Ignoring " << di.get_remaining_size()
|
||||
<< " trailing MeshTextureCoords.\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileMesh::read_material_list_data
|
||||
// Access: Public
|
||||
// Description: Fills the structure based on the raw data from the
|
||||
// MaterialList template.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileMesh::
|
||||
read_material_list_data(const Datagram &raw_data) {
|
||||
DatagramIterator di(raw_data);
|
||||
|
||||
di.get_int32(); /* num_materials */
|
||||
int num_faces = di.get_int32();
|
||||
|
||||
if (num_faces > _faces.size()) {
|
||||
cerr << "Too many faces in MaterialList.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
int material_index = -1;
|
||||
int i = 0;
|
||||
while (i < num_faces) {
|
||||
XFileFace *face = _faces[i];
|
||||
material_index = di.get_int32();
|
||||
face->_material_index = material_index;
|
||||
i++;
|
||||
}
|
||||
|
||||
// The rest of the faces get the same material index as the last
|
||||
// one in the list.
|
||||
while (i < (int)_faces.size()) {
|
||||
XFileFace *face = _faces[i];
|
||||
face->_material_index = material_index;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (di.get_remaining_size() != 0) {
|
||||
cerr << "Ignoring " << di.get_remaining_size()
|
||||
<< " trailing MeshMaterialList.\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,56 +23,88 @@
|
|||
#include "pvector.h"
|
||||
#include "pmap.h"
|
||||
#include "indirectCompareTo.h"
|
||||
#include "namable.h"
|
||||
|
||||
class XFileMesh;
|
||||
class XFileVertex;
|
||||
class XFileNormal;
|
||||
class XFileMaterial;
|
||||
class XFileFace;
|
||||
class EggGroupNode;
|
||||
class EggVertex;
|
||||
class EggPolygon;
|
||||
class EggPrimitive;
|
||||
class EggTextureCollection;
|
||||
class EggMaterialCollection;
|
||||
class Datagram;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileMesh
|
||||
// Description : This is a collection of polygons; i.e. a polyset.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileMesh {
|
||||
class XFileMesh : public Namable {
|
||||
public:
|
||||
XFileMesh();
|
||||
~XFileMesh();
|
||||
|
||||
void clear();
|
||||
|
||||
void add_polygon(EggPolygon *egg_poly);
|
||||
int add_vertex(EggVertex *egg_vertex, EggPrimitive *egg_prim);
|
||||
int add_normal(EggVertex *egg_vertex, EggPrimitive *egg_prim);
|
||||
int add_material(EggPrimitive *egg_prim);
|
||||
|
||||
int add_vertex(XFileVertex *vertex);
|
||||
int add_normal(XFileNormal *normal);
|
||||
int add_material(XFileMaterial *material);
|
||||
|
||||
bool create_polygons(EggGroupNode *egg_parent,
|
||||
EggTextureCollection &textures,
|
||||
EggMaterialCollection &materials);
|
||||
|
||||
bool has_normals() const;
|
||||
bool has_colors() const;
|
||||
bool has_uvs() const;
|
||||
bool has_materials() const;
|
||||
|
||||
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);
|
||||
|
||||
bool read_mesh_data(const Datagram &raw_data);
|
||||
bool read_normal_data(const Datagram &raw_data);
|
||||
bool read_color_data(const Datagram &raw_data);
|
||||
bool read_uv_data(const Datagram &raw_data);
|
||||
bool read_material_list_data(const Datagram &raw_data);
|
||||
|
||||
private:
|
||||
typedef pvector<XFileVertex *> Vertices;
|
||||
typedef pvector<XFileNormal *> Normals;
|
||||
typedef pvector<XFileMaterial *> Materials;
|
||||
typedef pvector<XFileFace *> Faces;
|
||||
|
||||
Vertices _vertices;
|
||||
Normals _normals;
|
||||
Materials _materials;
|
||||
Faces _faces;
|
||||
|
||||
private:
|
||||
typedef pmap<XFileVertex *, int, IndirectCompareTo<XFileVertex> > UniqueVertices;
|
||||
typedef pmap<XFileNormal *, int, IndirectCompareTo<XFileNormal> > UniqueNormals;
|
||||
typedef pmap<XFileMaterial *, int, IndirectCompareTo<XFileMaterial> > UniqueMaterials;
|
||||
UniqueVertices _unique_vertices;
|
||||
UniqueNormals _unique_normals;
|
||||
UniqueMaterials _unique_materials;
|
||||
|
||||
bool _has_normals;
|
||||
bool _has_colors;
|
||||
bool _has_uvs;
|
||||
bool _has_materials;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,15 +26,24 @@
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileNormal::
|
||||
XFileNormal(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
|
||||
_has_normal = true;
|
||||
XFileNormal() {
|
||||
_normal.set(0.0, 0.0, 0.0);
|
||||
_has_normal = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileNormal::set_from_egg
|
||||
// Access: Public
|
||||
// Description: Sets the structure up from the indicated egg data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileNormal::
|
||||
set_from_egg(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
|
||||
if (egg_vertex->has_normal()) {
|
||||
_normal = LCAST(float, egg_vertex->get_normal());
|
||||
_has_normal = true;
|
||||
} else if (egg_prim->has_normal()) {
|
||||
_normal = LCAST(float, egg_prim->get_normal());
|
||||
} else {
|
||||
_normal.set(0.0, 0.0, 0.0);
|
||||
_has_normal = false;
|
||||
_has_normal = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ class EggPrimitive;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class XFileNormal {
|
||||
public:
|
||||
XFileNormal(EggVertex *egg_vertex, EggPrimitive *egg_prim);
|
||||
XFileNormal();
|
||||
void set_from_egg(EggVertex *egg_vertex, EggPrimitive *egg_prim);
|
||||
int compare_to(const XFileNormal &other) const;
|
||||
|
||||
Normalf _normal;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
// Filename: xFileToEgg.cxx
|
||||
// Created by: drose (21Jun01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "xFileToEgg.h"
|
||||
#include "xFileToEggConverter.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEgg::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileToEgg::
|
||||
XFileToEgg() :
|
||||
SomethingToEgg("DirectX", ".x")
|
||||
{
|
||||
add_normals_options();
|
||||
add_transform_options();
|
||||
add_texture_path_options();
|
||||
add_rel_dir_options();
|
||||
add_search_path_options(false);
|
||||
|
||||
set_program_description
|
||||
("This program converts DirectX retained-mode (.x) files to egg. This "
|
||||
"is a simple file format that only supports basic polygons, materials, "
|
||||
"and textures, in a hierarchy.");
|
||||
|
||||
redescribe_option
|
||||
("cs",
|
||||
"Specify the coordinate system of the input " + _format_name +
|
||||
" file. Normally, this is y-up-left.");
|
||||
|
||||
_coordinate_system = CS_yup_left;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEgg::run
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileToEgg::
|
||||
run() {
|
||||
_data.set_coordinate_system(_coordinate_system);
|
||||
|
||||
XFileToEggConverter converter;
|
||||
converter.set_egg_data(&_data, false);
|
||||
converter.set_texture_path_convert(_texture_path_convert, _make_rel_dir);
|
||||
|
||||
if (!converter.convert_file(_input_filename)) {
|
||||
nout << "Unable to read " << _input_filename << "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
write_egg_file();
|
||||
nout << "\n";
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
XFileToEgg prog;
|
||||
prog.parse_command_line(argc, argv);
|
||||
prog.run();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// Filename: xFileToEgg.h
|
||||
// Created by: drose (21Jun01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef XFILETOEGG_H
|
||||
#define XFILETOEGG_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "somethingToEgg.h"
|
||||
#include "xFileToEggConverter.h"
|
||||
|
||||
#include "dSearchPath.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileToEgg
|
||||
// Description : A program to read a DirectX "x" file and generate an
|
||||
// egg file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileToEgg : public SomethingToEgg {
|
||||
public:
|
||||
XFileToEgg();
|
||||
|
||||
void run();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,713 @@
|
|||
// Filename: xFileToEggConverter.cxx
|
||||
// Created by: drose (21Jun01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "xFileToEggConverter.h"
|
||||
#include "xFileMesh.h"
|
||||
#include "xFileMaterial.h"
|
||||
#include "eggData.h"
|
||||
#include "eggGroup.h"
|
||||
#include "datagram.h"
|
||||
|
||||
// This must be included only in exactly one .cxx file, since
|
||||
// including defines the structure!
|
||||
#include <rmxftmpl.h>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileToEggConverter::
|
||||
XFileToEggConverter() {
|
||||
_dx_file = NULL;
|
||||
_dx_file_enum = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileToEggConverter::
|
||||
XFileToEggConverter(const XFileToEggConverter ©) :
|
||||
SomethingToEggConverter(copy)
|
||||
{
|
||||
_dx_file = NULL;
|
||||
_dx_file_enum = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileToEggConverter::
|
||||
~XFileToEggConverter() {
|
||||
close();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description: Allocates and returns a new copy of the converter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
SomethingToEggConverter *XFileToEggConverter::
|
||||
make_copy() {
|
||||
return new XFileToEggConverter(*this);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::get_name
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the English name of the file type this
|
||||
// converter supports.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string XFileToEggConverter::
|
||||
get_name() const {
|
||||
return "DirectX";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::get_extension
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the common extension of the file type this
|
||||
// converter supports.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string XFileToEggConverter::
|
||||
get_extension() const {
|
||||
return "x";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_file
|
||||
// Access: Public, Virtual
|
||||
// Description: Handles the reading of the input file and converting
|
||||
// it to egg. Returns true if successful, false
|
||||
// otherwise.
|
||||
//
|
||||
// This is designed to be as generic as possible,
|
||||
// generally in support of run-time loading.
|
||||
// Command-line converters may choose to use
|
||||
// convert_flt() instead, as it provides more control.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_file(const Filename &filename) {
|
||||
HRESULT hr;
|
||||
|
||||
close();
|
||||
hr = DirectXFileCreate(&_dx_file);
|
||||
if (hr != DXFILE_OK) {
|
||||
nout << "Unable to create X interface.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Register our templates.
|
||||
hr = _dx_file->RegisterTemplates(D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
|
||||
if (hr != DXFILE_OK) {
|
||||
nout << "Unable to register templates.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
string os_file = filename.to_os_specific();
|
||||
hr = _dx_file->CreateEnumObject
|
||||
((void *)os_file.c_str(), DXFILELOAD_FROMFILE, &_dx_file_enum);
|
||||
if (hr != DXFILE_OK) {
|
||||
nout << "Unable to open X file: " << os_file << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return get_toplevel();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::close
|
||||
// Access: Public
|
||||
// Description: Finalizes and closes the file previously opened via
|
||||
// convert_file().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileToEggConverter::
|
||||
close() {
|
||||
if (_dx_file != NULL) {
|
||||
if (_dx_file_enum != NULL) {
|
||||
_dx_file_enum->Release();
|
||||
_dx_file_enum = NULL;
|
||||
}
|
||||
_dx_file->Release();
|
||||
_dx_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::get_toplevel
|
||||
// Access: Private
|
||||
// Description: Pulls off all of the top-level objects in the .x file
|
||||
// and converts them, and their descendents, to the
|
||||
// appropriate egg structures.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
get_toplevel() {
|
||||
HRESULT hr;
|
||||
LPDIRECTXFILEDATA obj;
|
||||
|
||||
hr = _dx_file_enum->GetNextDataObject(&obj);
|
||||
while (hr == DXFILE_OK) {
|
||||
if (!convert_data_object(obj, _egg_data)) {
|
||||
return false;
|
||||
}
|
||||
hr = _dx_file_enum->GetNextDataObject(&obj);
|
||||
}
|
||||
|
||||
if (hr != DXFILEERR_NOMOREOBJECTS) {
|
||||
cerr << "Error extracting top-level objects.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_object
|
||||
// Access: Private
|
||||
// Description: Converts the indicated object to the appropriate egg
|
||||
// structures.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_object(LPDIRECTXFILEOBJECT obj, EggGroupNode *egg_parent) {
|
||||
HRESULT hr;
|
||||
LPDIRECTXFILEDATA data_obj;
|
||||
|
||||
// See if the object is a data object.
|
||||
hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
|
||||
if (hr == DD_OK) {
|
||||
// It is.
|
||||
return convert_data_object(data_obj, egg_parent);
|
||||
}
|
||||
|
||||
// It isn't.
|
||||
cerr << "Ignoring object of unknown type: " << get_object_name(obj)
|
||||
<< "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_data_object
|
||||
// Access: Private
|
||||
// Description: Converts the indicated object to the appropriate egg
|
||||
// structures.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_data_object(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) {
|
||||
HRESULT hr;
|
||||
|
||||
// Determine what type of data object we have.
|
||||
const GUID *type;
|
||||
hr = obj->GetType(&type);
|
||||
if (hr != DXFILE_OK) {
|
||||
cerr << "Unable to get type of template\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*type == TID_D3DRMFrame) {
|
||||
if (!convert_frame(obj, egg_parent)) {
|
||||
return false;
|
||||
}
|
||||
} else if (*type == TID_D3DRMMesh) {
|
||||
if (!convert_mesh(obj, egg_parent)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
cerr << "Ignoring data object of unknown type: " << get_object_name(obj)
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_frame
|
||||
// Access: Private
|
||||
// Description: Converts the indicated frame to the appropriate egg
|
||||
// structures.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_frame(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) {
|
||||
HRESULT hr;
|
||||
|
||||
string name = get_object_name(obj);
|
||||
EggGroup *group = new EggGroup(name);
|
||||
egg_parent->add_child(group);
|
||||
|
||||
// Now walk through the children of the frame.
|
||||
LPDIRECTXFILEOBJECT child_obj;
|
||||
|
||||
hr = obj->GetNextObject(&child_obj);
|
||||
while (hr == DXFILE_OK) {
|
||||
if (!convert_object(child_obj, group)) {
|
||||
return false;
|
||||
}
|
||||
hr = obj->GetNextObject(&child_obj);
|
||||
}
|
||||
|
||||
if (hr != DXFILEERR_NOMOREOBJECTS) {
|
||||
cerr << "Error extracting children of frame " << name << ".\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_mesh
|
||||
// Access: Private
|
||||
// Description: Converts the indicated mesh to the appropriate egg
|
||||
// structures.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_mesh(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) {
|
||||
HRESULT hr;
|
||||
|
||||
Datagram raw_data;
|
||||
if (!get_data(obj, raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
XFileMesh mesh;
|
||||
mesh.set_name(get_object_name(obj));
|
||||
if (!mesh.read_mesh_data(raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now process all the child objects of the mesh.
|
||||
LPDIRECTXFILEOBJECT child_obj;
|
||||
|
||||
hr = obj->GetNextObject(&child_obj);
|
||||
while (hr == DXFILE_OK) {
|
||||
if (!convert_mesh_object(child_obj, mesh)) {
|
||||
return false;
|
||||
}
|
||||
hr = obj->GetNextObject(&child_obj);
|
||||
}
|
||||
|
||||
if (hr != DXFILEERR_NOMOREOBJECTS) {
|
||||
cerr << "Error extracting children of mesh " << get_object_name(obj)
|
||||
<< ".\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mesh.create_polygons(egg_parent, _textures, _materials)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_mesh_object
|
||||
// Access: Private
|
||||
// Description: Converts the indicated object, a child of a Mesh, to
|
||||
// the appropriate egg structures.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_mesh_object(LPDIRECTXFILEOBJECT obj, XFileMesh &mesh) {
|
||||
HRESULT hr;
|
||||
LPDIRECTXFILEDATA data_obj;
|
||||
|
||||
// See if the object is a data object.
|
||||
hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
|
||||
if (hr == DD_OK) {
|
||||
// It is.
|
||||
return convert_mesh_data_object(data_obj, mesh);
|
||||
}
|
||||
|
||||
// It isn't.
|
||||
cerr << "Ignoring object of unknown type: " << get_object_name(obj)
|
||||
<< "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_mesh_data_object
|
||||
// Access: Private
|
||||
// Description: Converts the indicated data object, a child of a
|
||||
// Mesh, to the appropriate egg structures.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_mesh_data_object(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
|
||||
HRESULT hr;
|
||||
|
||||
// Determine what type of data object we have.
|
||||
const GUID *type;
|
||||
hr = obj->GetType(&type);
|
||||
if (hr != DXFILE_OK) {
|
||||
cerr << "Unable to get type of template\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*type == TID_D3DRMMeshNormals) {
|
||||
if (!convert_mesh_normals(obj, mesh)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (*type == TID_D3DRMMeshVertexColors) {
|
||||
if (!convert_mesh_colors(obj, mesh)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (*type == TID_D3DRMMeshTextureCoords) {
|
||||
if (!convert_mesh_uvs(obj, mesh)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (*type == TID_D3DRMMeshMaterialList) {
|
||||
if (!convert_mesh_material_list(obj, mesh)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
cerr << "Ignoring data object of unknown type: " << get_object_name(obj)
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_mesh_normals
|
||||
// Access: Private
|
||||
// Description: Converts the indicated MeshNormals template
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_mesh_normals(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
|
||||
Datagram raw_data;
|
||||
if (!get_data(obj, raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mesh.read_normal_data(raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_mesh_colors
|
||||
// Access: Private
|
||||
// Description: Converts the indicated MeshVertexColors template
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_mesh_colors(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
|
||||
Datagram raw_data;
|
||||
if (!get_data(obj, raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mesh.read_color_data(raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_mesh_uvs
|
||||
// Access: Private
|
||||
// Description: Converts the indicated MeshTextureCoords template
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_mesh_uvs(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
|
||||
Datagram raw_data;
|
||||
if (!get_data(obj, raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mesh.read_uv_data(raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_mesh_material_list
|
||||
// Access: Private
|
||||
// Description: Converts the indicated MeshMaterialList template
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_mesh_material_list(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
|
||||
HRESULT hr;
|
||||
|
||||
Datagram raw_data;
|
||||
if (!get_data(obj, raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mesh.read_material_list_data(raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we need to process the children of the material list. These
|
||||
// will be the materials.
|
||||
LPDIRECTXFILEOBJECT child_obj;
|
||||
|
||||
hr = obj->GetNextObject(&child_obj);
|
||||
while (hr == DXFILE_OK) {
|
||||
if (!convert_material_list_object(child_obj, mesh)) {
|
||||
return false;
|
||||
}
|
||||
hr = obj->GetNextObject(&child_obj);
|
||||
}
|
||||
|
||||
if (hr != DXFILEERR_NOMOREOBJECTS) {
|
||||
cerr << "Error extracting children of MeshMaterialList "
|
||||
<< get_object_name(obj) << ".\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_material_list_object
|
||||
// Access: Private
|
||||
// Description: Converts the indicated object, a child of a
|
||||
// MeshMaterialList.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_material_list_object(LPDIRECTXFILEOBJECT obj, XFileMesh &mesh) {
|
||||
HRESULT hr;
|
||||
LPDIRECTXFILEDATA data_obj;
|
||||
|
||||
// See if the object is a data object.
|
||||
hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
|
||||
if (hr == DD_OK) {
|
||||
// It is.
|
||||
return convert_material_list_data_object(data_obj, mesh);
|
||||
}
|
||||
|
||||
// It isn't.
|
||||
cerr << "Ignoring object of unknown type: " << get_object_name(obj)
|
||||
<< "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_material_list_data_object
|
||||
// Access: Private
|
||||
// Description: Converts the indicated data object, a child of a
|
||||
// MeshMaterialList.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_material_list_data_object(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
|
||||
HRESULT hr;
|
||||
|
||||
// Determine what type of data object we have.
|
||||
const GUID *type;
|
||||
hr = obj->GetType(&type);
|
||||
if (hr != DXFILE_OK) {
|
||||
cerr << "Unable to get type of template\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*type == TID_D3DRMMaterial) {
|
||||
if (!convert_material(obj, mesh)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
cerr << "Ignoring data object of unknown type: " << get_object_name(obj)
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_material
|
||||
// Access: Private
|
||||
// Description: Converts the indicated Material template object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_material(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
|
||||
HRESULT hr;
|
||||
|
||||
Datagram raw_data;
|
||||
if (!get_data(obj, raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
XFileMaterial *material = new XFileMaterial;
|
||||
|
||||
if (!material->read_material_data(raw_data)) {
|
||||
delete material;
|
||||
return false;
|
||||
}
|
||||
|
||||
mesh.add_material(material);
|
||||
|
||||
// Now we need to process the children of the material. There
|
||||
// should only be one, and it will be a texture.
|
||||
LPDIRECTXFILEOBJECT child_obj;
|
||||
|
||||
hr = obj->GetNextObject(&child_obj);
|
||||
while (hr == DXFILE_OK) {
|
||||
if (!convert_material_object(child_obj, *material)) {
|
||||
return false;
|
||||
}
|
||||
hr = obj->GetNextObject(&child_obj);
|
||||
}
|
||||
|
||||
if (hr != DXFILEERR_NOMOREOBJECTS) {
|
||||
cerr << "Error extracting children of Material "
|
||||
<< get_object_name(obj) << ".\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_material_object
|
||||
// Access: Private
|
||||
// Description: Converts the indicated object, a child of a
|
||||
// Material.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_material_object(LPDIRECTXFILEOBJECT obj, XFileMaterial &material) {
|
||||
HRESULT hr;
|
||||
LPDIRECTXFILEDATA data_obj;
|
||||
|
||||
// See if the object is a data object.
|
||||
hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
|
||||
if (hr == DD_OK) {
|
||||
// It is.
|
||||
return convert_material_data_object(data_obj, material);
|
||||
}
|
||||
|
||||
// It isn't.
|
||||
cerr << "Ignoring object of unknown type: " << get_object_name(obj)
|
||||
<< "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_material_data_object
|
||||
// Access: Private
|
||||
// Description: Converts the indicated data object, a child of a
|
||||
// Material.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_material_data_object(LPDIRECTXFILEDATA obj, XFileMaterial &material) {
|
||||
HRESULT hr;
|
||||
|
||||
// Determine what type of data object we have.
|
||||
const GUID *type;
|
||||
hr = obj->GetType(&type);
|
||||
if (hr != DXFILE_OK) {
|
||||
cerr << "Unable to get type of template\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*type == TID_D3DRMTextureFilename) {
|
||||
if (!convert_texture(obj, material)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
cerr << "Ignoring data object of unknown type: " << get_object_name(obj)
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::convert_texture
|
||||
// Access: Private
|
||||
// Description: Converts the indicated TextureFilename template object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
convert_texture(LPDIRECTXFILEDATA obj, XFileMaterial &material) {
|
||||
Datagram raw_data;
|
||||
if (!get_data(obj, raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!material.read_texture_data(raw_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::get_object_name
|
||||
// Access: Private
|
||||
// Description: Returns the name of the indicated object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string XFileToEggConverter::
|
||||
get_object_name(LPDIRECTXFILEOBJECT obj) {
|
||||
HRESULT hr;
|
||||
|
||||
DWORD length = 0;
|
||||
obj->GetName(NULL, &length);
|
||||
|
||||
if (length == 0) {
|
||||
return string();
|
||||
}
|
||||
|
||||
char *buffer = new char[length];
|
||||
hr = obj->GetName(buffer, &length);
|
||||
|
||||
string result;
|
||||
if (hr != DXFILE_OK) {
|
||||
cerr << "Unable to get object name.\n";
|
||||
} else {
|
||||
result = buffer;
|
||||
}
|
||||
|
||||
delete[] buffer;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileToEggConverter::get_data
|
||||
// Access: Private
|
||||
// Description: Extracts out the raw data for the indicated object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileToEggConverter::
|
||||
get_data(LPDIRECTXFILEDATA obj, Datagram &raw_data) {
|
||||
HRESULT hr;
|
||||
DWORD length;
|
||||
void *data;
|
||||
hr = obj->GetData(NULL, &length, &data);
|
||||
if (hr != DXFILE_OK) {
|
||||
cerr << "Unable to get data for " << get_object_name(obj) << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
raw_data.clear();
|
||||
raw_data.append_data(data, length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
// Filename: xFileToEggConverter.h
|
||||
// Created by: drose (21Jun01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef XFILETOEGGCONVERTER_H
|
||||
#define XFILETOEGGCONVERTER_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "somethingToEggConverter.h"
|
||||
#include "eggTextureCollection.h"
|
||||
#include "eggMaterialCollection.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <d3d.h>
|
||||
#include <dxfile.h>
|
||||
#include <rmxfguid.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
|
||||
class EggGroupNode;
|
||||
class Datagram;
|
||||
class XFileMesh;
|
||||
class XFileMaterial;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileToEggConverter
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileToEggConverter : public SomethingToEggConverter {
|
||||
public:
|
||||
XFileToEggConverter();
|
||||
XFileToEggConverter(const XFileToEggConverter ©);
|
||||
~XFileToEggConverter();
|
||||
|
||||
virtual SomethingToEggConverter *make_copy();
|
||||
|
||||
virtual string get_name() const;
|
||||
virtual string get_extension() const;
|
||||
|
||||
virtual bool convert_file(const Filename &filename);
|
||||
void close();
|
||||
|
||||
private:
|
||||
bool get_toplevel();
|
||||
bool convert_object(LPDIRECTXFILEOBJECT obj, EggGroupNode *egg_parent);
|
||||
bool convert_data_object(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent);
|
||||
bool convert_frame(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent);
|
||||
bool convert_mesh(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent);
|
||||
|
||||
bool convert_mesh_object(LPDIRECTXFILEOBJECT obj, XFileMesh &mesh);
|
||||
bool convert_mesh_data_object(LPDIRECTXFILEDATA obj, XFileMesh &mesh);
|
||||
bool convert_mesh_normals(LPDIRECTXFILEDATA obj, XFileMesh &mesh);
|
||||
bool convert_mesh_colors(LPDIRECTXFILEDATA obj, XFileMesh &mesh);
|
||||
bool convert_mesh_uvs(LPDIRECTXFILEDATA obj, XFileMesh &mesh);
|
||||
bool convert_mesh_material_list(LPDIRECTXFILEDATA obj, XFileMesh &mesh);
|
||||
bool convert_material_list_object(LPDIRECTXFILEOBJECT obj, XFileMesh &mesh);
|
||||
bool convert_material_list_data_object(LPDIRECTXFILEDATA obj, XFileMesh &mesh);
|
||||
bool convert_material(LPDIRECTXFILEDATA obj, XFileMesh &mesh);
|
||||
bool convert_material_object(LPDIRECTXFILEOBJECT obj, XFileMaterial &material);
|
||||
bool convert_material_data_object(LPDIRECTXFILEDATA obj, XFileMaterial &material);
|
||||
bool convert_texture(LPDIRECTXFILEDATA obj, XFileMaterial &material);
|
||||
|
||||
string get_object_name(LPDIRECTXFILEOBJECT obj);
|
||||
bool get_data(LPDIRECTXFILEDATA obj, Datagram &raw_data);
|
||||
|
||||
LPDIRECTXFILE _dx_file;
|
||||
LPDIRECTXFILEENUMOBJECT _dx_file_enum;
|
||||
|
||||
EggTextureCollection _textures;
|
||||
EggMaterialCollection _materials;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -26,25 +26,45 @@
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileVertex::
|
||||
XFileVertex(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
|
||||
_has_color = true;
|
||||
_has_uv = true;
|
||||
XFileVertex() {
|
||||
_has_color = false;
|
||||
_has_uv = false;
|
||||
_point.set(0.0, 0.0, 0.0);
|
||||
_uv.set(0.0, 0.0);
|
||||
_color.set(1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileVertex::set_from_egg
|
||||
// Access: Public
|
||||
// Description: Sets the structure up from the indicated egg data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileVertex::
|
||||
set_from_egg(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
|
||||
_point = LCAST(float, egg_vertex->get_pos3());
|
||||
|
||||
if (egg_vertex->has_uv()) {
|
||||
_uv = LCAST(float, egg_vertex->get_uv());
|
||||
} else {
|
||||
_uv.set(0.0, 0.0);
|
||||
_has_uv = false;
|
||||
TexCoordd uv = egg_vertex->get_uv();
|
||||
if (egg_prim->has_texture()) {
|
||||
// Check if there's a texture matrix on the texture.
|
||||
EggTexture *egg_tex = egg_prim->get_texture();
|
||||
if (egg_tex->has_transform()) {
|
||||
uv = uv * egg_tex->get_transform();
|
||||
}
|
||||
}
|
||||
|
||||
_uv[0] = uv[0];
|
||||
// Windows draws the UV's upside-down.
|
||||
_uv[1] = 1.0 - uv[1];
|
||||
_has_uv = true;
|
||||
}
|
||||
|
||||
if (egg_vertex->has_color()) {
|
||||
_color = egg_vertex->get_color();
|
||||
_has_color = true;
|
||||
} else if (egg_prim->has_color()) {
|
||||
_color = egg_prim->get_color();
|
||||
} else {
|
||||
_color.set(1.0, 1.0, 1.0, 1.0);
|
||||
_has_color = false;
|
||||
_has_color = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ class EggPrimitive;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class XFileVertex {
|
||||
public:
|
||||
XFileVertex(EggVertex *egg_vertex, EggPrimitive *egg_poly);
|
||||
XFileVertex();
|
||||
void set_from_egg(EggVertex *egg_vertex, EggPrimitive *egg_poly);
|
||||
int compare_to(const XFileVertex &other) const;
|
||||
|
||||
Vertexf _point;
|
||||
|
|
|
|||
Loading…
Reference in New Issue