Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

pandatool/src/xfile/xFileToEggConverter.cxx

Go to the documentation of this file.
00001 // Filename: xFileToEggConverter.cxx
00002 // Created by:  drose (21Jun01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "xFileToEggConverter.h"
00020 #include "xFileMesh.h"
00021 #include "xFileMaterial.h"
00022 #include "xFileTemplates.h"
00023 #include "config_xfile.h"
00024 
00025 #include "eggData.h"
00026 #include "eggGroup.h"
00027 #include "datagram.h"
00028 #include "eggMaterialCollection.h"
00029 #include "eggTextureCollection.h"
00030 #include "dcast.h"
00031 
00032 ////////////////////////////////////////////////////////////////////
00033 //     Function: XFileToEggConverter::Constructor
00034 //       Access: Public
00035 //  Description:
00036 ////////////////////////////////////////////////////////////////////
00037 XFileToEggConverter::
00038 XFileToEggConverter() {
00039   _dx_file = NULL;
00040   _dx_file_enum = NULL;
00041 }
00042 
00043 ////////////////////////////////////////////////////////////////////
00044 //     Function: XFileToEggConverter::Copy Constructor
00045 //       Access: Public
00046 //  Description:
00047 ////////////////////////////////////////////////////////////////////
00048 XFileToEggConverter::
00049 XFileToEggConverter(const XFileToEggConverter &copy) :
00050   SomethingToEggConverter(copy)
00051 {
00052   _dx_file = NULL;
00053   _dx_file_enum = NULL;
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: XFileToEggConverter::Destructor
00058 //       Access: Public
00059 //  Description:
00060 ////////////////////////////////////////////////////////////////////
00061 XFileToEggConverter::
00062 ~XFileToEggConverter() {
00063   close();
00064 }
00065 
00066 ////////////////////////////////////////////////////////////////////
00067 //     Function: XFileToEggConverter::make_copy
00068 //       Access: Public, Virtual
00069 //  Description: Allocates and returns a new copy of the converter.
00070 ////////////////////////////////////////////////////////////////////
00071 SomethingToEggConverter *XFileToEggConverter::
00072 make_copy() {
00073   return new XFileToEggConverter(*this);
00074 }
00075 
00076 
00077 ////////////////////////////////////////////////////////////////////
00078 //     Function: XFileToEggConverter::get_name
00079 //       Access: Public, Virtual
00080 //  Description: Returns the English name of the file type this
00081 //               converter supports.
00082 ////////////////////////////////////////////////////////////////////
00083 string XFileToEggConverter::
00084 get_name() const {
00085   return "DirectX";
00086 }
00087 
00088 ////////////////////////////////////////////////////////////////////
00089 //     Function: XFileToEggConverter::get_extension
00090 //       Access: Public, Virtual
00091 //  Description: Returns the common extension of the file type this
00092 //               converter supports.
00093 ////////////////////////////////////////////////////////////////////
00094 string XFileToEggConverter::
00095 get_extension() const {
00096   return "x";
00097 }
00098 
00099 ////////////////////////////////////////////////////////////////////
00100 //     Function: XFileToEggConverter::convert_file
00101 //       Access: Public, Virtual
00102 //  Description: Handles the reading of the input file and converting
00103 //               it to egg.  Returns true if successful, false
00104 //               otherwise.
00105 //
00106 //               This is designed to be as generic as possible,
00107 //               generally in support of run-time loading.
00108 //               Command-line converters may choose to use
00109 //               convert_flt() instead, as it provides more control.
00110 ////////////////////////////////////////////////////////////////////
00111 bool XFileToEggConverter::
00112 convert_file(const Filename &filename) {
00113   HRESULT hr;
00114 
00115   close();
00116   hr = DirectXFileCreate(&_dx_file);
00117   if (hr != DXFILE_OK) {
00118     nout << "Unable to create X interface.\n";
00119     return false;
00120   }
00121 
00122   // Register our templates.
00123   hr = _dx_file->RegisterTemplates(D3DRM_XTEMPLATES, d3drm_xtemplates_length);
00124   if (hr != DXFILE_OK) {
00125     nout << "Unable to register templates.\n";
00126     return false;
00127   }
00128 
00129   string os_file = filename.to_os_specific();
00130   hr = _dx_file->CreateEnumObject
00131     ((void *)os_file.c_str(), DXFILELOAD_FROMFILE, &_dx_file_enum);
00132   if (hr != DXFILE_OK) {
00133     nout << "Unable to open X file: " << os_file << "\n";
00134     return false;
00135   }
00136 
00137   if (_egg_data->get_coordinate_system() == CS_default) {
00138     _egg_data->set_coordinate_system(CS_yup_left);
00139   }
00140 
00141   return get_toplevel();
00142 }
00143 
00144 ////////////////////////////////////////////////////////////////////
00145 //     Function: XFileToEggConverter::close
00146 //       Access: Public
00147 //  Description: Finalizes and closes the file previously opened via
00148 //               convert_file().
00149 ////////////////////////////////////////////////////////////////////
00150 void XFileToEggConverter::
00151 close() {
00152   if (_dx_file != NULL) {
00153     if (_dx_file_enum != NULL) {
00154       _dx_file_enum->Release();
00155       _dx_file_enum = NULL;
00156     }
00157     _dx_file->Release();
00158     _dx_file = NULL;
00159   }
00160 }
00161 
00162 ////////////////////////////////////////////////////////////////////
00163 //     Function: XFileToEggConverter::create_unique_texture
00164 //       Access: Public
00165 //  Description: Returns an EggTexture pointer whose properties match
00166 //               that of the the given EggTexture, except for the tref
00167 //               name.
00168 ////////////////////////////////////////////////////////////////////
00169 EggTexture *XFileToEggConverter::
00170 create_unique_texture(const EggTexture &copy) {
00171   return _textures.create_unique_texture(copy, ~EggTexture::E_tref_name);
00172 }
00173 
00174 ////////////////////////////////////////////////////////////////////
00175 //     Function: XFileToEggConverter::create_unique_material
00176 //       Access: Public
00177 //  Description: Returns an EggMaterial pointer whose properties match
00178 //               that of the the given EggMaterial, except for the mref
00179 //               name.
00180 ////////////////////////////////////////////////////////////////////
00181 EggMaterial *XFileToEggConverter::
00182 create_unique_material(const EggMaterial &copy) {
00183   return _materials.create_unique_material(copy, ~EggMaterial::E_mref_name);
00184 }
00185 
00186 ////////////////////////////////////////////////////////////////////
00187 //     Function: XFileToEggConverter::get_toplevel
00188 //       Access: Private
00189 //  Description: Pulls off all of the top-level objects in the .x file
00190 //               and converts them, and their descendents, to the
00191 //               appropriate egg structures.
00192 ////////////////////////////////////////////////////////////////////
00193 bool XFileToEggConverter::
00194 get_toplevel() {
00195   HRESULT hr;
00196   LPDIRECTXFILEDATA obj;
00197 
00198   hr = _dx_file_enum->GetNextDataObject(&obj);
00199   while (hr == DXFILE_OK) {
00200     if (!convert_data_object(obj, _egg_data)) {
00201       return false;
00202     }
00203     hr = _dx_file_enum->GetNextDataObject(&obj);
00204   }
00205 
00206   if (hr != DXFILEERR_NOMOREOBJECTS) {
00207     xfile_cat.error()
00208       << "Error extracting top-level objects.\n";
00209     return false;
00210   }
00211 
00212   return true;
00213 }
00214 
00215 ////////////////////////////////////////////////////////////////////
00216 //     Function: XFileToEggConverter::convert_object
00217 //       Access: Private
00218 //  Description: Converts the indicated object to the appropriate egg
00219 //               structures.
00220 ////////////////////////////////////////////////////////////////////
00221 bool XFileToEggConverter::
00222 convert_object(LPDIRECTXFILEOBJECT obj, EggGroupNode *egg_parent) {
00223   HRESULT hr;
00224   LPDIRECTXFILEDATA data_obj;
00225 
00226   // See if the object is a data object.
00227   hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
00228   if (hr == DD_OK) {
00229     // It is.
00230     return convert_data_object(data_obj, egg_parent);
00231   }
00232 
00233   // It isn't.
00234   xfile_cat.error()
00235     << "Ignoring object of unknown type: " << get_object_name(obj)
00236     << "\n";
00237   return true;
00238 }
00239 
00240 
00241 ////////////////////////////////////////////////////////////////////
00242 //     Function: XFileToEggConverter::convert_data_object
00243 //       Access: Private
00244 //  Description: Converts the indicated object to the appropriate egg
00245 //               structures.
00246 ////////////////////////////////////////////////////////////////////
00247 bool XFileToEggConverter::
00248 convert_data_object(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) {
00249   HRESULT hr;
00250 
00251   // Determine what type of data object we have.
00252   const GUID *type;
00253   hr = obj->GetType(&type);
00254   if (hr != DXFILE_OK) {
00255     xfile_cat.error()
00256       << "Unable to get type of template\n";
00257     return false;
00258   }
00259 
00260   if (*type == mydef_TID_D3DRMHeader) {
00261     // Quietly ignore headers.
00262 
00263   } else if (*type == TID_D3DRMFrame) {
00264     if (!convert_frame(obj, egg_parent)) {
00265       return false;
00266     }
00267 
00268   } else if (*type == TID_D3DRMFrameTransformMatrix) {
00269     if (!convert_transform(obj, egg_parent)) {
00270       return false;
00271     }
00272 
00273   } else if (*type == TID_D3DRMMesh) {
00274     if (!convert_mesh(obj, egg_parent)) {
00275       return false;
00276     }
00277 
00278   } else {
00279     xfile_cat.error()
00280       << "Ignoring data object of unknown type: " << get_object_name(obj)
00281       << "\n";
00282   }
00283   
00284   return true;
00285 }
00286 
00287 ////////////////////////////////////////////////////////////////////
00288 //     Function: XFileToEggConverter::convert_frame
00289 //       Access: Private
00290 //  Description: Converts the indicated frame to the appropriate egg
00291 //               structures.
00292 ////////////////////////////////////////////////////////////////////
00293 bool XFileToEggConverter::
00294 convert_frame(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) {
00295   HRESULT hr;
00296 
00297   string name = get_object_name(obj);
00298   EggGroup *group = new EggGroup(name);
00299   egg_parent->add_child(group);
00300 
00301   // Now walk through the children of the frame.
00302   LPDIRECTXFILEOBJECT child_obj;
00303 
00304   hr = obj->GetNextObject(&child_obj);
00305   while (hr == DXFILE_OK) {
00306     if (!convert_object(child_obj, group)) {
00307       return false;
00308     }
00309     hr = obj->GetNextObject(&child_obj);
00310   }
00311 
00312   if (hr != DXFILEERR_NOMOREOBJECTS) {
00313     xfile_cat.error()
00314       << "Error extracting children of frame " << name << ".\n";
00315     return false;
00316   }
00317 
00318   return true;
00319 }
00320 
00321 ////////////////////////////////////////////////////////////////////
00322 //     Function: XFileToEggConverter::convert_transform
00323 //       Access: Private
00324 //  Description: Reads a transform matrix, a child of a given frame,
00325 //               and applies it to the node.  Normally this can only
00326 //               be done if the node in question is an EggGroup, which
00327 //               should be the case if the transform was a child of a
00328 //               frame.
00329 ////////////////////////////////////////////////////////////////////
00330 bool XFileToEggConverter::
00331 convert_transform(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) {
00332   Datagram raw_data;
00333   if (!get_data(obj, raw_data)) {
00334     return false;
00335   }
00336 
00337   DatagramIterator di(raw_data);
00338   LMatrix4f mat;
00339   mat.read_datagram(di);
00340 
00341   if (egg_parent->is_of_type(EggGroup::get_class_type())) {
00342     EggGroup *egg_group = DCAST(EggGroup, egg_parent);
00343     egg_group->set_transform(LCAST(double, mat));
00344     egg_group->set_group_type(EggGroup::GT_instance);
00345   } else {
00346     xfile_cat.error()
00347       << "Transform " << get_object_name(obj)
00348       << " encountered without frame!\n";
00349   }
00350 
00351   return true;
00352 }
00353 
00354 ////////////////////////////////////////////////////////////////////
00355 //     Function: XFileToEggConverter::convert_mesh
00356 //       Access: Private
00357 //  Description: Converts the indicated mesh to the appropriate egg
00358 //               structures.
00359 ////////////////////////////////////////////////////////////////////
00360 bool XFileToEggConverter::
00361 convert_mesh(LPDIRECTXFILEDATA obj, EggGroupNode *egg_parent) {
00362   HRESULT hr;
00363 
00364   Datagram raw_data;
00365   if (!get_data(obj, raw_data)) {
00366     return false;
00367   }
00368 
00369   XFileMesh mesh;
00370   mesh.set_name(get_object_name(obj));
00371   if (!mesh.read_mesh_data(raw_data)) {
00372     return false;
00373   }
00374 
00375   // Now process all the child objects of the mesh.
00376   LPDIRECTXFILEOBJECT child_obj;
00377 
00378   hr = obj->GetNextObject(&child_obj);
00379   while (hr == DXFILE_OK) {
00380     if (!convert_mesh_object(child_obj, mesh)) {
00381       return false;
00382     }
00383     hr = obj->GetNextObject(&child_obj);
00384   }
00385 
00386   if (hr != DXFILEERR_NOMOREOBJECTS) {
00387     xfile_cat.error()
00388       << "Error extracting children of mesh " << get_object_name(obj)
00389       << ".\n";
00390     return false;
00391   }
00392 
00393   if (!mesh.create_polygons(egg_parent, this)) {
00394     return false;
00395   }
00396 
00397   return true;
00398 }
00399 
00400 ////////////////////////////////////////////////////////////////////
00401 //     Function: XFileToEggConverter::convert_mesh_object
00402 //       Access: Private
00403 //  Description: Converts the indicated object, a child of a Mesh, to
00404 //               the appropriate egg structures.
00405 ////////////////////////////////////////////////////////////////////
00406 bool XFileToEggConverter::
00407 convert_mesh_object(LPDIRECTXFILEOBJECT obj, XFileMesh &mesh) {
00408   HRESULT hr;
00409   LPDIRECTXFILEDATA data_obj;
00410 
00411   // See if the object is a data object.
00412   hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
00413   if (hr == DD_OK) {
00414     // It is.
00415     return convert_mesh_data_object(data_obj, mesh);
00416   }
00417 
00418   // It isn't.
00419   xfile_cat.error()
00420     << "Ignoring object of unknown type: " << get_object_name(obj)
00421     << "\n";
00422   return true;
00423 }
00424 
00425 ////////////////////////////////////////////////////////////////////
00426 //     Function: XFileToEggConverter::convert_mesh_data_object
00427 //       Access: Private
00428 //  Description: Converts the indicated data object, a child of a
00429 //               Mesh, to the appropriate egg structures.
00430 ////////////////////////////////////////////////////////////////////
00431 bool XFileToEggConverter::
00432 convert_mesh_data_object(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
00433   HRESULT hr;
00434 
00435   // Determine what type of data object we have.
00436   const GUID *type;
00437   hr = obj->GetType(&type);
00438   if (hr != DXFILE_OK) {
00439     xfile_cat.error()
00440       << "Unable to get type of template\n";
00441     return false;
00442   }
00443 
00444   if (*type == TID_D3DRMMeshNormals) {
00445     if (!convert_mesh_normals(obj, mesh)) {
00446       return false;
00447     }
00448 
00449   } else if (*type == TID_D3DRMMeshVertexColors) {
00450     if (!convert_mesh_colors(obj, mesh)) {
00451       return false;
00452     }
00453 
00454   } else if (*type == TID_D3DRMMeshTextureCoords) {
00455     if (!convert_mesh_uvs(obj, mesh)) {
00456       return false;
00457     }
00458 
00459   } else if (*type == TID_D3DRMMeshMaterialList) {
00460     if (!convert_mesh_material_list(obj, mesh)) {
00461       return false;
00462     }
00463 
00464   } else {
00465     xfile_cat.error()
00466       << "Ignoring data object of unknown type: " << get_object_name(obj)
00467       << "\n";
00468   }
00469   
00470   return true;
00471 }
00472 
00473 ////////////////////////////////////////////////////////////////////
00474 //     Function: XFileToEggConverter::convert_mesh_normals
00475 //       Access: Private
00476 //  Description: Converts the indicated MeshNormals template
00477 //               object.
00478 ////////////////////////////////////////////////////////////////////
00479 bool XFileToEggConverter::
00480 convert_mesh_normals(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
00481   Datagram raw_data;
00482   if (!get_data(obj, raw_data)) {
00483     return false;
00484   }
00485 
00486   if (!mesh.read_normal_data(raw_data)) {
00487     return false;
00488   }
00489 
00490   return true;
00491 }
00492 
00493 ////////////////////////////////////////////////////////////////////
00494 //     Function: XFileToEggConverter::convert_mesh_colors
00495 //       Access: Private
00496 //  Description: Converts the indicated MeshVertexColors template
00497 //               object.
00498 ////////////////////////////////////////////////////////////////////
00499 bool XFileToEggConverter::
00500 convert_mesh_colors(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
00501   Datagram raw_data;
00502   if (!get_data(obj, raw_data)) {
00503     return false;
00504   }
00505 
00506   if (!mesh.read_color_data(raw_data)) {
00507     return false;
00508   }
00509 
00510   return true;
00511 }
00512 
00513 ////////////////////////////////////////////////////////////////////
00514 //     Function: XFileToEggConverter::convert_mesh_uvs
00515 //       Access: Private
00516 //  Description: Converts the indicated MeshTextureCoords template
00517 //               object.
00518 ////////////////////////////////////////////////////////////////////
00519 bool XFileToEggConverter::
00520 convert_mesh_uvs(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
00521   Datagram raw_data;
00522   if (!get_data(obj, raw_data)) {
00523     return false;
00524   }
00525 
00526   if (!mesh.read_uv_data(raw_data)) {
00527     return false;
00528   }
00529 
00530   return true;
00531 }
00532 
00533 ////////////////////////////////////////////////////////////////////
00534 //     Function: XFileToEggConverter::convert_mesh_material_list
00535 //       Access: Private
00536 //  Description: Converts the indicated MeshMaterialList template
00537 //               object.
00538 ////////////////////////////////////////////////////////////////////
00539 bool XFileToEggConverter::
00540 convert_mesh_material_list(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
00541   HRESULT hr;
00542 
00543   Datagram raw_data;
00544   if (!get_data(obj, raw_data)) {
00545     return false;
00546   }
00547 
00548   if (!mesh.read_material_list_data(raw_data)) {
00549     return false;
00550   }
00551 
00552   // Now we need to process the children of the material list.  These
00553   // will be the materials.
00554   LPDIRECTXFILEOBJECT child_obj;
00555 
00556   hr = obj->GetNextObject(&child_obj);
00557   while (hr == DXFILE_OK) {
00558     if (!convert_material_list_object(child_obj, mesh)) {
00559       return false;
00560     }
00561     hr = obj->GetNextObject(&child_obj);
00562   }
00563 
00564   if (hr != DXFILEERR_NOMOREOBJECTS) {
00565     xfile_cat.error()
00566       << "Error extracting children of MeshMaterialList "
00567       << get_object_name(obj) << ".\n";
00568     return false;
00569   }
00570 
00571   return true;
00572 }
00573 
00574 ////////////////////////////////////////////////////////////////////
00575 //     Function: XFileToEggConverter::convert_material_list_object
00576 //       Access: Private
00577 //  Description: Converts the indicated object, a child of a
00578 //               MeshMaterialList.
00579 ////////////////////////////////////////////////////////////////////
00580 bool XFileToEggConverter::
00581 convert_material_list_object(LPDIRECTXFILEOBJECT obj, XFileMesh &mesh) {
00582   HRESULT hr;
00583   LPDIRECTXFILEDATA data_obj;
00584 
00585   // See if the object is a data object.
00586   hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
00587   if (hr == DD_OK) {
00588     // It is.
00589     return convert_material_list_data_object(data_obj, mesh);
00590   }
00591 
00592   // It isn't.
00593   xfile_cat.error()
00594     << "Ignoring object of unknown type: " << get_object_name(obj)
00595     << "\n";
00596   return true;
00597 }
00598 
00599 ////////////////////////////////////////////////////////////////////
00600 //     Function: XFileToEggConverter::convert_material_list_data_object
00601 //       Access: Private
00602 //  Description: Converts the indicated data object, a child of a
00603 //               MeshMaterialList.
00604 ////////////////////////////////////////////////////////////////////
00605 bool XFileToEggConverter::
00606 convert_material_list_data_object(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
00607   HRESULT hr;
00608 
00609   // Determine what type of data object we have.
00610   const GUID *type;
00611   hr = obj->GetType(&type);
00612   if (hr != DXFILE_OK) {
00613     xfile_cat.error()
00614       << "Unable to get type of template\n";
00615     return false;
00616   }
00617 
00618   if (*type == TID_D3DRMMaterial) {
00619     if (!convert_material(obj, mesh)) {
00620       return false;
00621     }
00622   } else {
00623     xfile_cat.error()
00624       << "Ignoring data object of unknown type: " << get_object_name(obj)
00625       << "\n";
00626   }
00627   
00628   return true;
00629 }
00630 
00631 ////////////////////////////////////////////////////////////////////
00632 //     Function: XFileToEggConverter::convert_material
00633 //       Access: Private
00634 //  Description: Converts the indicated Material template object.
00635 ////////////////////////////////////////////////////////////////////
00636 bool XFileToEggConverter::
00637 convert_material(LPDIRECTXFILEDATA obj, XFileMesh &mesh) {
00638   HRESULT hr;
00639 
00640   Datagram raw_data;
00641   if (!get_data(obj, raw_data)) {
00642     return false;
00643   }
00644 
00645   XFileMaterial *material = new XFileMaterial;
00646 
00647   if (!material->read_material_data(raw_data)) {
00648     delete material;
00649     return false;
00650   }
00651 
00652   mesh.add_material(material);
00653 
00654   // Now we need to process the children of the material.  There
00655   // should only be one, and it will be a texture.
00656   LPDIRECTXFILEOBJECT child_obj;
00657 
00658   hr = obj->GetNextObject(&child_obj);
00659   while (hr == DXFILE_OK) {
00660     if (!convert_material_object(child_obj, *material)) {
00661       return false;
00662     }
00663     hr = obj->GetNextObject(&child_obj);
00664   }
00665 
00666   if (hr != DXFILEERR_NOMOREOBJECTS) {
00667     xfile_cat.error()
00668       << "Error extracting children of Material " 
00669       << get_object_name(obj) << ".\n";
00670     return false;
00671   }
00672 
00673   return true;
00674 }
00675 
00676 ////////////////////////////////////////////////////////////////////
00677 //     Function: XFileToEggConverter::convert_material_object
00678 //       Access: Private
00679 //  Description: Converts the indicated object, a child of a
00680 //               Material.
00681 ////////////////////////////////////////////////////////////////////
00682 bool XFileToEggConverter::
00683 convert_material_object(LPDIRECTXFILEOBJECT obj, XFileMaterial &material) {
00684   HRESULT hr;
00685   LPDIRECTXFILEDATA data_obj;
00686 
00687   // See if the object is a data object.
00688   hr = obj->QueryInterface(IID_IDirectXFileData, (void **)&data_obj);
00689   if (hr == DD_OK) {
00690     // It is.
00691     return convert_material_data_object(data_obj, material);
00692   }
00693 
00694   // It isn't.
00695   xfile_cat.error()
00696     << "Ignoring object of unknown type: " << get_object_name(obj)
00697     << "\n";
00698   return true;
00699 }
00700 
00701 ////////////////////////////////////////////////////////////////////
00702 //     Function: XFileToEggConverter::convert_material_data_object
00703 //       Access: Private
00704 //  Description: Converts the indicated data object, a child of a
00705 //               Material.
00706 ////////////////////////////////////////////////////////////////////
00707 bool XFileToEggConverter::
00708 convert_material_data_object(LPDIRECTXFILEDATA obj, XFileMaterial &material) {
00709   HRESULT hr;
00710 
00711   // Determine what type of data object we have.
00712   const GUID *type;
00713   hr = obj->GetType(&type);
00714   if (hr != DXFILE_OK) {
00715     xfile_cat.error()
00716       << "Unable to get type of template\n";
00717     return false;
00718   }
00719 
00720   if (*type == TID_D3DRMTextureFilename) {
00721     if (!convert_texture(obj, material)) {
00722       return false;
00723     }
00724   } else {
00725     xfile_cat.error()
00726       << "Ignoring data object of unknown type: " << get_object_name(obj)
00727       << "\n";
00728   }
00729   
00730   return true;
00731 }
00732 
00733 ////////////////////////////////////////////////////////////////////
00734 //     Function: XFileToEggConverter::convert_texture
00735 //       Access: Private
00736 //  Description: Converts the indicated TextureFilename template object.
00737 ////////////////////////////////////////////////////////////////////
00738 bool XFileToEggConverter::
00739 convert_texture(LPDIRECTXFILEDATA obj, XFileMaterial &material) {
00740   Datagram raw_data;
00741   if (!get_data(obj, raw_data)) {
00742     return false;
00743   }
00744 
00745   if (!material.read_texture_data(raw_data)) {
00746     return false;
00747   }
00748 
00749   return true;
00750 }
00751 
00752 ////////////////////////////////////////////////////////////////////
00753 //     Function: XFileToEggConverter::get_object_name
00754 //       Access: Private
00755 //  Description: Returns the name of the indicated object.
00756 ////////////////////////////////////////////////////////////////////
00757 string XFileToEggConverter::
00758 get_object_name(LPDIRECTXFILEOBJECT obj) {
00759   HRESULT hr;
00760 
00761   DWORD length = 0;
00762   obj->GetName(NULL, &length);
00763   
00764   if (length == 0) {
00765     return string();
00766   }
00767 
00768   char *buffer = new char[length];
00769   hr = obj->GetName(buffer, &length);
00770 
00771   string result;
00772   if (hr != DXFILE_OK) {
00773     xfile_cat.error()
00774       << "Unable to get object name.\n";
00775   } else {
00776     result = buffer;
00777   }
00778 
00779   delete[] buffer;
00780   return result;
00781 }
00782 
00783 ////////////////////////////////////////////////////////////////////
00784 //     Function: XFileToEggConverter::get_data
00785 //       Access: Private
00786 //  Description: Extracts out the raw data for the indicated object.
00787 ////////////////////////////////////////////////////////////////////
00788 bool XFileToEggConverter::
00789 get_data(LPDIRECTXFILEDATA obj, Datagram &raw_data) {
00790   HRESULT hr;
00791   DWORD length;
00792   void *data;
00793   hr = obj->GetData(NULL, &length, &data);
00794   if (hr != DXFILE_OK) {
00795     xfile_cat.error()
00796       << "Unable to get data for " << get_object_name(obj) << "\n";
00797     return false;
00798   }
00799 
00800   raw_data.clear();
00801   raw_data.append_data(data, length);
00802 
00803   return true;
00804 }

Generated on Fri May 2 03:21:55 2003 for Panda-Tool by doxygen1.3