49 ~EggToObjConverter() {
94 if (_egg_data->get_coordinate_system() == CS_default) {
95 _egg_data->set_coordinate_system(CS_zup_right);
98 if (!process(filename)) {
107 bool EggToObjConverter::
109 _egg_data->flatten_transforms();
110 collect_vertices(_egg_data);
113 Filename obj_filename = Filename::text_filename(filename);
116 if (file ==
nullptr) {
119 if (egg_precision != 0) {
120 file->precision(egg_precision);
123 _current_group =
nullptr;
132 write_vertices(*file,
"v", 3, _unique_vert3);
133 write_vertices(*file,
"v", 4, _unique_vert4);
134 write_vertices(*file,
"vt", 2, _unique_uv2);
135 write_vertices(*file,
"vt", 3, _unique_uv3);
136 write_vertices(*file,
"vn", 3, _unique_norm);
138 write_faces(*file, _egg_data);
140 bool success = (file !=
nullptr);
151 void EggToObjConverter::
152 collect_vertices(
EggNode *egg_node) {
153 if (egg_node->
is_of_type(EggPrimitive::get_class_type())) {
155 EggPrimitive::iterator pi;
156 for (pi = egg_prim->begin(); pi != egg_prim->end(); ++pi) {
160 }
else if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
163 EggGroupNode::iterator ci;
164 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
165 collect_vertices(*ci);
174 void EggToObjConverter::
175 write_faces(ostream &out,
EggNode *egg_node) {
176 if (egg_node->
is_of_type(EggPrimitive::get_class_type())) {
177 const char *prim_type =
nullptr;
178 if (egg_node->
is_of_type(EggPolygon::get_class_type())) {
180 }
else if (egg_node->
is_of_type(EggPoint::get_class_type())) {
182 }
else if (egg_node->
is_of_type(EggLine::get_class_type())) {
186 if (prim_type !=
nullptr) {
187 write_group_reference(out, egg_node);
192 EggPrimitive::iterator pi;
193 for (pi = egg_prim->begin(); pi != egg_prim->end(); ++pi) {
194 VertexDef &vdef = _vmap[(*pi)];
199 if (vdef._vert3_index != -1) {
200 vert_index = vdef._vert3_index + 1;
201 }
else if (vdef._vert4_index != -1) {
202 vert_index = vdef._vert4_index + 1 + (int)_unique_vert3.size();
205 if (vdef._uv2_index != -1) {
206 uv_index = vdef._uv2_index + 1;
207 }
else if (vdef._uv3_index != -1) {
208 uv_index = vdef._uv3_index + 1 + (int)_unique_uv2.size();
211 if (vdef._norm_index != -1) {
212 norm_index = vdef._norm_index + 1;
215 if (vert_index == -1) {
219 if (norm_index != -1) {
220 if (uv_index != -1) {
221 out <<
" " << vert_index <<
"/" << uv_index <<
"/" << norm_index;
223 out <<
" " << vert_index <<
"//" << norm_index;
225 }
else if (uv_index != -1) {
226 out <<
" " << vert_index <<
"/" << uv_index;
228 out <<
" " << vert_index;
233 }
else if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
236 EggGroupNode::iterator ci;
237 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
238 write_faces(out, *ci);
246 void EggToObjConverter::
247 write_group_reference(ostream &out,
EggNode *egg_node) {
249 if (egg_group == _current_group) {
255 get_group_name(group_name, egg_group);
256 if (group_name.empty()) {
257 out <<
"g default\n";
259 out <<
"g" << group_name <<
"\n";
261 _current_group = egg_group;
268 void EggToObjConverter::
269 get_group_name(
string &group_name,
EggGroupNode *egg_group) {
270 string name =
trim(egg_group->get_name());
275 for (string::const_iterator ni = name.begin(); ni != name.end(); ++ni) {
286 if (egg_parent !=
nullptr) {
287 get_group_name(group_name, egg_parent);
295 void EggToObjConverter::
297 VertexDef &vdef = _vmap[vertex];
301 vdef._vert3_index = record_unique(_unique_vert3, vertex->
get_pos1());
304 vdef._vert3_index = record_unique(_unique_vert3, vertex->
get_pos2());
307 vdef._vert3_index = record_unique(_unique_vert3, vertex->
get_pos3());
310 vdef._vert4_index = record_unique(_unique_vert4, vertex->
get_pos4());
315 vdef._uv2_index = record_unique(_unique_uv2, vertex->
get_uv(
""));
316 }
else if (vertex->
has_uvw(
"")) {
317 vdef._uv3_index = record_unique(_unique_uv3, vertex->
get_uvw(
""));
320 if (vertex->has_normal()) {
321 vdef._norm_index = record_unique(_unique_norm, vertex->get_normal());
330 int EggToObjConverter::
331 record_unique(UniqueVertices &unique,
const LVecBase4d &vec) {
334 int index = unique.size();
335 UniqueVertices::iterator ui = unique.insert(UniqueVertices::value_type(vec, index)).first;
344 int EggToObjConverter::
345 record_unique(UniqueVertices &unique,
const LVecBase3d &vec) {
346 return record_unique(unique, LVecBase4d(vec[0], vec[1], vec[2], 0.0));
354 int EggToObjConverter::
355 record_unique(UniqueVertices &unique,
const LVecBase2d &vec) {
356 return record_unique(unique, LVecBase4d(vec[0], vec[1], 0.0, 0.0));
364 int EggToObjConverter::
365 record_unique(UniqueVertices &unique,
double pos) {
366 return record_unique(unique, LVecBase4d(pos, 0.0, 0.0, 0.0));
373 void EggToObjConverter::
374 write_vertices(ostream &out,
const string &prefix,
int num_components,
375 const UniqueVertices &unique) {
377 int num_vertices = (int)unique.size();
378 const LVecBase4d **vertices = (
const LVecBase4d **)PANDA_MALLOC_ARRAY(num_vertices *
sizeof(LVecBase4d *));
379 memset(vertices, 0, num_vertices *
sizeof(LVecBase4d *));
380 UniqueVertices::const_iterator ui;
381 for (ui = unique.begin(); ui != unique.end(); ++ui) {
382 int index = (*ui).second;
383 const LVecBase4d &vec = (*ui).first;
384 nassertv(index >= 0 && index < num_vertices);
385 nassertv(vertices[index] ==
nullptr);
386 vertices[index] = &vec;
389 for (
int i = 0; i < num_vertices; ++i) {
391 const LVecBase4d &vec = *(vertices[i]);
392 for (
int ci = 0; ci < num_components; ++ci) {
393 out <<
" " << vec[ci];
397 PANDA_FREE_ARRAY(vertices);
403 EggToObjConverter::VertexDef::