00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "xFileMaker.h"
00016 #include "xFileMesh.h"
00017 #include "xFileMaterial.h"
00018 #include "config_xfile.h"
00019
00020 #include "pnotify.h"
00021 #include "eggGroupNode.h"
00022 #include "eggGroup.h"
00023 #include "eggBin.h"
00024 #include "eggPolysetMaker.h"
00025 #include "eggVertexPool.h"
00026 #include "eggVertex.h"
00027 #include "eggPolygon.h"
00028 #include "eggData.h"
00029 #include "pvector.h"
00030 #include "vector_int.h"
00031 #include "string_utils.h"
00032 #include "datagram.h"
00033
00034
00035
00036
00037
00038
00039 XFileMaker::
00040 XFileMaker() {
00041 _mesh_index = 0;
00042 _x_file = new XFile;
00043 }
00044
00045
00046
00047
00048
00049
00050 XFileMaker::
00051 ~XFileMaker() {
00052 }
00053
00054
00055
00056
00057
00058
00059
00060 bool XFileMaker::
00061 write(const Filename &filename) {
00062 return _x_file->write(filename);
00063 }
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 bool XFileMaker::
00074 add_tree(EggData *egg_data) {
00075 _meshes.clear();
00076
00077
00078 EggPolysetMaker pmaker;
00079 pmaker.make_bins(egg_data);
00080
00081
00082 if (!recurse_nodes(egg_data, _x_file)) {
00083 return false;
00084 }
00085
00086
00087 Meshes::iterator mi;
00088 for (mi = _meshes.begin(); mi != _meshes.end(); ++mi) {
00089 if (!finalize_mesh((*mi).first, (*mi).second)) {
00090 return false;
00091 }
00092 }
00093 _meshes.clear();
00094
00095 return true;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104 bool XFileMaker::
00105 add_node(EggNode *egg_node, XFileNode *x_parent) {
00106 if (egg_node->is_of_type(EggBin::get_class_type())) {
00107 return add_bin(DCAST(EggBin, egg_node), x_parent);
00108
00109 } else if (egg_node->is_of_type(EggGroup::get_class_type())) {
00110 return add_group(DCAST(EggGroup, egg_node), x_parent);
00111
00112 } else if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
00113
00114 EggGroupNode *egg_group = DCAST(EggGroupNode, egg_node);
00115
00116 if (xfile_one_mesh) {
00117
00118
00119 if (!recurse_nodes(egg_group, x_parent)) {
00120 return false;
00121 }
00122
00123 } else {
00124
00125 XFileDataNode *x_frame = x_parent->add_Frame(egg_group->get_name());
00126
00127 if (!recurse_nodes(egg_group, x_frame)) {
00128 return false;
00129 }
00130 }
00131
00132 return true;
00133 }
00134
00135
00136 return true;
00137 }
00138
00139
00140
00141
00142
00143
00144 bool XFileMaker::
00145 add_group(EggGroup *egg_group, XFileNode *x_parent) {
00146 if (xfile_one_mesh) {
00147
00148
00149 if (!recurse_nodes(egg_group, x_parent)) {
00150 return false;
00151 }
00152
00153 } else {
00154
00155 XFileDataNode *x_frame = x_parent->add_Frame(egg_group->get_name());
00156
00157
00158 if (egg_group->has_transform()) {
00159 x_frame->add_FrameTransformMatrix(egg_group->get_transform3d());
00160 }
00161
00162 if (!recurse_nodes(egg_group, x_frame)) {
00163 return false;
00164 }
00165 }
00166
00167 return true;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176 bool XFileMaker::
00177 add_bin(EggBin *egg_bin, XFileNode *x_parent) {
00178 switch (egg_bin->get_bin_number()) {
00179 case EggPolysetMaker::BN_polyset:
00180 return add_polyset(egg_bin, x_parent);
00181 }
00182
00183 xfile_cat.error()
00184 << "Unexpected bin type " << egg_bin->get_bin_number() << "\n";
00185 return false;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194 bool XFileMaker::
00195 add_polyset(EggBin *egg_bin, XFileNode *x_parent) {
00196
00197 egg_bin->remove_invalid_primitives(true);
00198
00199 XFileMesh *mesh = get_mesh(x_parent);
00200
00201 EggGroupNode::iterator ci;
00202 for (ci = egg_bin->begin(); ci != egg_bin->end(); ++ci) {
00203 EggPolygon *poly;
00204 DCAST_INTO_R(poly, *ci, false);
00205
00206 mesh->add_polygon(poly);
00207 }
00208
00209 return true;
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219 bool XFileMaker::
00220 recurse_nodes(EggGroupNode *egg_node, XFileNode *x_parent) {
00221 EggGroupNode::iterator ci;
00222 for (ci = egg_node->begin(); ci != egg_node->end(); ++ci) {
00223 EggNode *child = (*ci);
00224 if (!add_node(child, x_parent)) {
00225 return false;
00226 }
00227 }
00228
00229 return true;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238 XFileMesh *XFileMaker::
00239 get_mesh(XFileNode *x_parent) {
00240 Meshes::iterator mi = _meshes.find(x_parent);
00241 if (mi != _meshes.end()) {
00242
00243
00244 return (*mi).second;
00245 }
00246
00247
00248 XFileMesh *mesh = new XFileMesh;
00249 _meshes.insert(Meshes::value_type(x_parent, mesh));
00250 return mesh;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260 bool XFileMaker::
00261 finalize_mesh(XFileNode *x_parent, XFileMesh *mesh) {
00262
00263 _mesh_index++;
00264 string mesh_index = format_string(_mesh_index);
00265
00266
00267 mesh->make_x_mesh(x_parent, mesh_index);
00268
00269 return true;
00270 }