mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
robustify xfile some more
This commit is contained in:
parent
679f9cdc13
commit
99d7222df4
@ -33,7 +33,7 @@
|
|||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
XFileMesh::
|
XFileMesh::
|
||||||
XFileMesh() {
|
XFileMesh(CoordinateSystem cs) : _cs(cs) {
|
||||||
_has_normals = false;
|
_has_normals = false;
|
||||||
_has_colors = false;
|
_has_colors = false;
|
||||||
_has_uvs = false;
|
_has_uvs = false;
|
||||||
@ -260,6 +260,13 @@ add_material(XFileMaterial *material) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool XFileMesh::
|
bool XFileMesh::
|
||||||
create_polygons(EggGroupNode *egg_parent, XFileToEggConverter *converter) {
|
create_polygons(EggGroupNode *egg_parent, XFileToEggConverter *converter) {
|
||||||
|
if (has_name()) {
|
||||||
|
// Put a named mesh within its own group.
|
||||||
|
EggGroup *egg_group = new EggGroup(get_name());
|
||||||
|
egg_parent->add_child(egg_group);
|
||||||
|
egg_parent = egg_group;
|
||||||
|
}
|
||||||
|
|
||||||
EggVertexPool *vpool = new EggVertexPool(get_name());
|
EggVertexPool *vpool = new EggVertexPool(get_name());
|
||||||
egg_parent->add_child(vpool);
|
egg_parent->add_child(vpool);
|
||||||
Faces::const_iterator fi;
|
Faces::const_iterator fi;
|
||||||
@ -302,6 +309,10 @@ create_polygons(EggGroupNode *egg_parent, XFileToEggConverter *converter) {
|
|||||||
temp_vtx.set_normal(LCAST(double, normal->_normal));
|
temp_vtx.set_normal(LCAST(double, normal->_normal));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transform the vertex into the appropriate (global) coordinate
|
||||||
|
// space.
|
||||||
|
temp_vtx.transform(egg_parent->get_node_to_vertex());
|
||||||
|
|
||||||
// Now get a real EggVertex matching our template.
|
// Now get a real EggVertex matching our template.
|
||||||
EggVertex *egg_vtx = vpool->create_unique_vertex(temp_vtx);
|
EggVertex *egg_vtx = vpool->create_unique_vertex(temp_vtx);
|
||||||
egg_poly->add_vertex(egg_vtx);
|
egg_poly->add_vertex(egg_vtx);
|
||||||
@ -315,6 +326,13 @@ create_polygons(EggGroupNode *egg_parent, XFileToEggConverter *converter) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!has_normals()) {
|
||||||
|
// If we don't have explicit normals, make some up, per the DX
|
||||||
|
// spec. Since the DX spec doesn't mention anything about a
|
||||||
|
// crease angle, we should be as generous as possible.
|
||||||
|
egg_parent->recompute_vertex_normals(180.0, _cs);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "pmap.h"
|
#include "pmap.h"
|
||||||
#include "indirectCompareTo.h"
|
#include "indirectCompareTo.h"
|
||||||
#include "namable.h"
|
#include "namable.h"
|
||||||
|
#include "coordinateSystem.h"
|
||||||
|
|
||||||
class XFileMesh;
|
class XFileMesh;
|
||||||
class XFileVertex;
|
class XFileVertex;
|
||||||
@ -43,7 +44,7 @@ class Datagram;
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class XFileMesh : public Namable {
|
class XFileMesh : public Namable {
|
||||||
public:
|
public:
|
||||||
XFileMesh();
|
XFileMesh(CoordinateSystem cs = CS_yup_left);
|
||||||
~XFileMesh();
|
~XFileMesh();
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
@ -86,6 +87,8 @@ private:
|
|||||||
typedef pvector<XFileMaterial *> Materials;
|
typedef pvector<XFileMaterial *> Materials;
|
||||||
typedef pvector<XFileFace *> Faces;
|
typedef pvector<XFileFace *> Faces;
|
||||||
|
|
||||||
|
CoordinateSystem _cs;
|
||||||
|
|
||||||
Vertices _vertices;
|
Vertices _vertices;
|
||||||
Normals _normals;
|
Normals _normals;
|
||||||
Materials _materials;
|
Materials _materials;
|
||||||
|
@ -195,9 +195,13 @@ get_toplevel() {
|
|||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
LPDIRECTXFILEDATA obj;
|
LPDIRECTXFILEDATA obj;
|
||||||
|
|
||||||
|
PT(EggGroup) egg_toplevel = new EggGroup;
|
||||||
|
bool any_frames = false;
|
||||||
|
|
||||||
hr = _dx_file_enum->GetNextDataObject(&obj);
|
hr = _dx_file_enum->GetNextDataObject(&obj);
|
||||||
while (hr == DXFILE_OK) {
|
while (hr == DXFILE_OK) {
|
||||||
if (!convert_data_object(obj, _egg_data)) {
|
if (!convert_toplevel_object(obj, _egg_data,
|
||||||
|
egg_toplevel, any_frames)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
hr = _dx_file_enum->GetNextDataObject(&obj);
|
hr = _dx_file_enum->GetNextDataObject(&obj);
|
||||||
@ -209,6 +213,71 @@ get_toplevel() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!any_frames) {
|
||||||
|
// If the file contained no frames at all, then all of the meshes
|
||||||
|
// that appeared at the toplevel were meant to be directly
|
||||||
|
// included.
|
||||||
|
_egg_data->steal_children(*egg_toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileToEggConverter::convert_toplevel_object
|
||||||
|
// Access: Private
|
||||||
|
// Description: Converts the indicated object, encountered outside of
|
||||||
|
// any Frames, to the appropriate egg structures.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileToEggConverter::
|
||||||
|
convert_toplevel_object(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent,
|
||||||
|
EggGroupNode *egg_toplevel, bool &any_frames) {
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
// Determine what type of data object we have.
|
||||||
|
const GUID *type;
|
||||||
|
hr = obj->GetType(&type);
|
||||||
|
if (hr != DXFILE_OK) {
|
||||||
|
xfile_cat.error()
|
||||||
|
<< "Unable to get type of template\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*type == mydef_TID_D3DRMHeader) {
|
||||||
|
// Quietly ignore headers.
|
||||||
|
|
||||||
|
} else if (*type == TID_D3DRMMaterial) {
|
||||||
|
// Quietly ignore toplevel materials. These will presumably be
|
||||||
|
// referenced below.
|
||||||
|
|
||||||
|
} else if (*type == TID_D3DRMFrame) {
|
||||||
|
any_frames = true;
|
||||||
|
if (!convert_frame(obj, egg_parent)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (*type == TID_D3DRMFrameTransformMatrix) {
|
||||||
|
if (!convert_transform(obj, egg_parent)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (*type == TID_D3DRMMesh) {
|
||||||
|
// Assume a Mesh at the toplevel is just present to define a
|
||||||
|
// reference that will be included below. Convert it into the
|
||||||
|
// egg_toplevel group, where it will be ignored unless there are
|
||||||
|
// no frames at all in the file.
|
||||||
|
if (!convert_mesh(obj, egg_toplevel)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (xfile_cat.is_debug()) {
|
||||||
|
xfile_cat.debug()
|
||||||
|
<< "Ignoring toplevel object of unknown type: "
|
||||||
|
<< get_object_name(obj) << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,6 +291,7 @@ bool XFileToEggConverter::
|
|||||||
convert_object(LPDIRECTXFILEOBJECT obj, EggGroupNode *egg_parent) {
|
convert_object(LPDIRECTXFILEOBJECT obj, EggGroupNode *egg_parent) {
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
LPDIRECTXFILEDATA data_obj;
|
LPDIRECTXFILEDATA data_obj;
|
||||||
|
LPDIRECTXFILEDATAREFERENCE ref_obj;
|
||||||
|
|
||||||
// See if the object is a data object.
|
// See if the object is a data object.
|
||||||
hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
|
hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
|
||||||
@ -230,6 +300,15 @@ convert_object(LPDIRECTXFILEOBJECT obj, EggGroupNode *egg_parent) {
|
|||||||
return convert_data_object(data_obj, egg_parent);
|
return convert_data_object(data_obj, egg_parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Or maybe it's a reference to a previous object.
|
||||||
|
hr = obj->QueryInterface(IID_IDirectXFileDataReference, (void **)&ref_obj);
|
||||||
|
if (hr == DD_OK) {
|
||||||
|
// It is.
|
||||||
|
if (ref_obj->Resolve(&data_obj) == DXFILE_OK) {
|
||||||
|
return convert_data_object(data_obj, egg_parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// It isn't.
|
// It isn't.
|
||||||
if (xfile_cat.is_debug()) {
|
if (xfile_cat.is_debug()) {
|
||||||
xfile_cat.debug()
|
xfile_cat.debug()
|
||||||
@ -345,7 +424,7 @@ convert_transform(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) {
|
|||||||
if (egg_parent->is_of_type(EggGroup::get_class_type())) {
|
if (egg_parent->is_of_type(EggGroup::get_class_type())) {
|
||||||
EggGroup *egg_group = DCAST(EggGroup, egg_parent);
|
EggGroup *egg_group = DCAST(EggGroup, egg_parent);
|
||||||
egg_group->set_transform(LCAST(double, mat));
|
egg_group->set_transform(LCAST(double, mat));
|
||||||
egg_group->set_group_type(EggGroup::GT_instance);
|
|
||||||
} else {
|
} else {
|
||||||
xfile_cat.error()
|
xfile_cat.error()
|
||||||
<< "Transform " << get_object_name(obj)
|
<< "Transform " << get_object_name(obj)
|
||||||
@ -370,7 +449,7 @@ convert_mesh(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFileMesh mesh;
|
XFileMesh mesh(_egg_data->get_coordinate_system());
|
||||||
mesh.set_name(get_object_name(obj));
|
mesh.set_name(get_object_name(obj));
|
||||||
if (!mesh.read_mesh_data(raw_data)) {
|
if (!mesh.read_mesh_data(raw_data)) {
|
||||||
return false;
|
return false;
|
||||||
@ -411,6 +490,7 @@ bool XFileToEggConverter::
|
|||||||
convert_mesh_object(LPDIRECTXFILEOBJECT obj, XFileMesh &mesh) {
|
convert_mesh_object(LPDIRECTXFILEOBJECT obj, XFileMesh &mesh) {
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
LPDIRECTXFILEDATA data_obj;
|
LPDIRECTXFILEDATA data_obj;
|
||||||
|
LPDIRECTXFILEDATAREFERENCE ref_obj;
|
||||||
|
|
||||||
// See if the object is a data object.
|
// See if the object is a data object.
|
||||||
hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
|
hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
|
||||||
@ -419,6 +499,15 @@ convert_mesh_object(LPDIRECTXFILEOBJECT obj, XFileMesh &mesh) {
|
|||||||
return convert_mesh_data_object(data_obj, mesh);
|
return convert_mesh_data_object(data_obj, mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Or maybe it's a reference to a previous object.
|
||||||
|
hr = obj->QueryInterface(IID_IDirectXFileDataReference, (void **)&ref_obj);
|
||||||
|
if (hr == DD_OK) {
|
||||||
|
// It is.
|
||||||
|
if (ref_obj->Resolve(&data_obj) == DXFILE_OK) {
|
||||||
|
return convert_mesh_data_object(data_obj, mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// It isn't.
|
// It isn't.
|
||||||
if (xfile_cat.is_debug()) {
|
if (xfile_cat.is_debug()) {
|
||||||
xfile_cat.debug()
|
xfile_cat.debug()
|
||||||
@ -705,6 +794,7 @@ bool XFileToEggConverter::
|
|||||||
convert_material_object(LPDIRECTXFILEOBJECT obj, XFileMaterial &material) {
|
convert_material_object(LPDIRECTXFILEOBJECT obj, XFileMaterial &material) {
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
LPDIRECTXFILEDATA data_obj;
|
LPDIRECTXFILEDATA data_obj;
|
||||||
|
LPDIRECTXFILEDATAREFERENCE ref_obj;
|
||||||
|
|
||||||
// See if the object is a data object.
|
// See if the object is a data object.
|
||||||
hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
|
hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
|
||||||
@ -713,6 +803,15 @@ convert_material_object(LPDIRECTXFILEOBJECT obj, XFileMaterial &material) {
|
|||||||
return convert_material_data_object(data_obj, material);
|
return convert_material_data_object(data_obj, material);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Or maybe it's a reference to a previous object.
|
||||||
|
hr = obj->QueryInterface(IID_IDirectXFileDataReference, (void **)&ref_obj);
|
||||||
|
if (hr == DD_OK) {
|
||||||
|
// It is.
|
||||||
|
if (ref_obj->Resolve(&data_obj) == DXFILE_OK) {
|
||||||
|
return convert_material_data_object(data_obj, material);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// It isn't.
|
// It isn't.
|
||||||
if (xfile_cat.is_debug()) {
|
if (xfile_cat.is_debug()) {
|
||||||
xfile_cat.debug()
|
xfile_cat.debug()
|
||||||
|
@ -61,6 +61,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool get_toplevel();
|
bool get_toplevel();
|
||||||
|
bool convert_toplevel_object(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent,
|
||||||
|
EggGroupNode *egg_toplevel, bool &any_frames);
|
||||||
bool convert_object(LPDIRECTXFILEOBJECT obj, EggGroupNode *egg_parent);
|
bool convert_object(LPDIRECTXFILEOBJECT obj, EggGroupNode *egg_parent);
|
||||||
bool convert_data_object(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent);
|
bool convert_data_object(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent);
|
||||||
bool convert_frame(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent);
|
bool convert_frame(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user