00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "bamToEgg.h"
00016
00017 #include "pandaNode.h"
00018 #include "workingNodePath.h"
00019 #include "nodePath.h"
00020 #include "billboardEffect.h"
00021 #include "renderEffects.h"
00022 #include "transformState.h"
00023 #include "colorScaleAttrib.h"
00024 #include "colorAttrib.h"
00025 #include "textureAttrib.h"
00026 #include "cullFaceAttrib.h"
00027 #include "transparencyAttrib.h"
00028 #include "depthWriteAttrib.h"
00029 #include "lodNode.h"
00030 #include "switchNode.h"
00031 #include "sequenceNode.h"
00032 #include "collisionNode.h"
00033 #include "collisionPolygon.h"
00034 #include "collisionPlane.h"
00035 #include "collisionSphere.h"
00036 #include "collisionInvSphere.h"
00037 #include "collisionTube.h"
00038 #include "textureStage.h"
00039 #include "geomNode.h"
00040 #include "geom.h"
00041 #include "geomTriangles.h"
00042 #include "geomPoints.h"
00043 #include "geomLines.h"
00044 #include "geomVertexReader.h"
00045 #include "transformTable.h"
00046 #include "modelNode.h"
00047 #include "animBundleNode.h"
00048 #include "animChannelMatrixXfmTable.h"
00049 #include "characterJoint.h"
00050 #include "character.h"
00051 #include "string_utils.h"
00052 #include "bamFile.h"
00053 #include "bamCacheRecord.h"
00054 #include "eggSAnimData.h"
00055 #include "eggXfmAnimData.h"
00056 #include "eggXfmSAnim.h"
00057 #include "eggGroup.h"
00058 #include "eggVertexPool.h"
00059 #include "eggVertex.h"
00060 #include "eggPrimitive.h"
00061 #include "eggPolygon.h"
00062 #include "eggPoint.h"
00063 #include "eggLine.h"
00064 #include "eggTexture.h"
00065 #include "eggMaterial.h"
00066 #include "eggRenderMode.h"
00067 #include "eggTable.h"
00068 #include "somethingToEggConverter.h"
00069 #include "dcast.h"
00070 #include "pystub.h"
00071
00072
00073
00074
00075
00076
00077 BamToEgg::
00078 BamToEgg() :
00079 SomethingToEgg("bam", ".bam")
00080 {
00081 add_path_replace_options();
00082 add_path_store_options();
00083
00084 set_program_description
00085 ("This program converts native Panda bam files to egg. The conversion "
00086 "is somewhat incomplete; running egg2bam followed by bam2egg should not "
00087 "be expected to yield the same egg file you started with.");
00088
00089 redescribe_option
00090 ("cs",
00091 "Specify the coordinate system of the input " + _format_name +
00092 " file. By default, this is taken from the Config.prc file, which "
00093 "is currently " + format_string(get_default_coordinate_system()) + ".");
00094
00095 _coordinate_system = get_default_coordinate_system();
00096 }
00097
00098
00099
00100
00101
00102
00103 void BamToEgg::
00104 run() {
00105 BamFile bam_file;
00106
00107 if (!bam_file.open_read(_input_filename)) {
00108 nout << "Unable to read " << _input_filename << "\n";
00109 exit(1);
00110 }
00111
00112 nout << _input_filename << " : Bam version "
00113 << bam_file.get_file_major_ver() << "."
00114 << bam_file.get_file_minor_ver() << "\n";
00115
00116 typedef pvector<TypedWritable *> Objects;
00117 Objects objects;
00118 TypedWritable *object = bam_file.read_object();
00119
00120 if (object != (TypedWritable *)NULL &&
00121 object->is_exact_type(BamCacheRecord::get_class_type())) {
00122
00123
00124
00125
00126 object = bam_file.read_object();
00127 }
00128
00129 while (object != (TypedWritable *)NULL || !bam_file.is_eof()) {
00130 if (object != (TypedWritable *)NULL) {
00131 ReferenceCount *ref_ptr = object->as_reference_count();
00132 if (ref_ptr != NULL) {
00133 ref_ptr->ref();
00134 }
00135 objects.push_back(object);
00136 }
00137 object = bam_file.read_object();
00138 }
00139 bam_file.resolve();
00140 bam_file.close();
00141
00142 _data->set_coordinate_system(_coordinate_system);
00143 _vpool = new EggVertexPool("vpool");
00144 _data->add_child(_vpool);
00145
00146 if (objects.size() == 1 &&
00147 objects[0]->is_of_type(PandaNode::get_class_type())) {
00148 PandaNode *node = DCAST(PandaNode, objects[0]);
00149 NodePath root(node);
00150 convert_node(WorkingNodePath(root), _data, false);
00151
00152 } else {
00153 nout << "File does not contain a scene graph.\n";
00154 exit(1);
00155 }
00156
00157
00158 if (_vpool->empty()) {
00159 _data->remove_child(_vpool);
00160 }
00161
00162 write_egg_file();
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172 void BamToEgg::
00173 convert_node(const WorkingNodePath &node_path, EggGroupNode *egg_parent,
00174 bool has_decal) {
00175 PandaNode *node = node_path.node();
00176 if (node->is_geom_node()) {
00177 convert_geom_node(DCAST(GeomNode, node), node_path, egg_parent, has_decal);
00178
00179 } else if (node->is_of_type(LODNode::get_class_type())) {
00180 convert_lod_node(DCAST(LODNode, node), node_path, egg_parent, has_decal);
00181
00182 } else if (node->is_of_type(SequenceNode::get_class_type())) {
00183 convert_sequence_node(DCAST(SequenceNode, node), node_path, egg_parent, has_decal);
00184
00185 } else if (node->is_of_type(SwitchNode::get_class_type())) {
00186 convert_switch_node(DCAST(SwitchNode, node), node_path, egg_parent, has_decal);
00187
00188 } else if (node->is_of_type(CollisionNode::get_class_type())) {
00189 convert_collision_node(DCAST(CollisionNode, node), node_path, egg_parent, has_decal);
00190
00191 } else if (node->is_of_type(AnimBundleNode::get_class_type())) {
00192 convert_anim_node(DCAST(AnimBundleNode, node), node_path, egg_parent, has_decal);
00193
00194 } else if (node->is_of_type(Character::get_class_type())) {
00195 convert_character_node(DCAST(Character, node), node_path, egg_parent, has_decal);
00196
00197 } else {
00198
00199 EggGroup *egg_group = new EggGroup(node->get_name());
00200 egg_parent->add_child(egg_group);
00201 apply_node_properties(egg_group, node);
00202
00203 recurse_nodes(node_path, egg_group, has_decal);
00204 }
00205 }
00206
00207
00208
00209
00210
00211
00212
00213 void BamToEgg::
00214 convert_lod_node(LODNode *node, const WorkingNodePath &node_path,
00215 EggGroupNode *egg_parent, bool has_decal) {
00216
00217
00218 EggGroup *egg_group = new EggGroup(node->get_name());
00219 egg_parent->add_child(egg_group);
00220 apply_node_properties(egg_group, node);
00221
00222 int num_children = node->get_num_children();
00223 int num_switches = node->get_num_switches();
00224
00225 num_children = min(num_children, num_switches);
00226
00227 for (int i = 0; i < num_children; i++) {
00228 PandaNode *child = node->get_child(i);
00229
00230
00231 PT(EggGroup) next_group = new EggGroup;
00232 convert_node(WorkingNodePath(node_path, child), next_group, has_decal);
00233
00234 if (next_group->size() == 1) {
00235
00236
00237 EggNode *child_node = *next_group->begin();
00238 if (child_node->is_of_type(EggGroup::get_class_type())) {
00239 PT(EggGroup) child = DCAST(EggGroup, child_node);
00240 next_group->remove_child(child.p());
00241 next_group = child;
00242 }
00243 }
00244
00245
00246 PN_stdfloat in = node->get_in(i);
00247 PN_stdfloat out = node->get_out(i);
00248 LPoint3 center = node->get_center();
00249 EggSwitchConditionDistance dist(in, out, LCAST(double, center));
00250 next_group->set_lod(dist);
00251 egg_group->add_child(next_group.p());
00252 }
00253 }
00254
00255
00256
00257
00258
00259
00260
00261 void BamToEgg::
00262 convert_sequence_node(SequenceNode *node, const WorkingNodePath &node_path,
00263 EggGroupNode *egg_parent, bool has_decal) {
00264
00265
00266 EggGroup *egg_group = new EggGroup(node->get_name());
00267 egg_parent->add_child(egg_group);
00268 apply_node_properties(egg_group, node);
00269
00270
00271 egg_group->set_switch_flag(true);
00272 egg_group->set_switch_fps(node->get_frame_rate());
00273
00274 int num_children = node->get_num_children();
00275
00276 for (int i = 0; i < num_children; i++) {
00277 PandaNode *child = node->get_child(i);
00278
00279
00280 PT(EggGroup) next_group = new EggGroup;
00281 convert_node(WorkingNodePath(node_path, child), next_group, has_decal);
00282
00283 egg_group->add_child(next_group.p());
00284 }
00285
00286 }
00287
00288
00289
00290
00291
00292
00293
00294 void BamToEgg::
00295 convert_switch_node(SwitchNode *node, const WorkingNodePath &node_path,
00296 EggGroupNode *egg_parent, bool has_decal) {
00297
00298
00299 EggGroup *egg_group = new EggGroup(node->get_name());
00300 egg_parent->add_child(egg_group);
00301 apply_node_properties(egg_group, node);
00302
00303
00304 egg_group->set_switch_flag(true);
00305
00306 int num_children = node->get_num_children();
00307
00308 for (int i = 0; i < num_children; i++) {
00309 PandaNode *child = node->get_child(i);
00310
00311
00312 PT(EggGroup) next_group = new EggGroup;
00313 convert_node(WorkingNodePath(node_path, child), next_group, has_decal);
00314
00315 egg_group->add_child(next_group.p());
00316 }
00317 }
00318
00319
00320
00321
00322
00323
00324
00325 EggGroupNode * BamToEgg::convert_animGroup_node(AnimGroup *animGroup, double fps ) {
00326 int num_children = animGroup->get_num_children();
00327
00328 EggGroupNode *eggNode = NULL;
00329 if (animGroup->is_of_type(AnimBundle::get_class_type())) {
00330 EggTable *eggTable = new EggTable(animGroup->get_name());
00331 eggTable ->set_table_type(EggTable::TT_bundle);
00332 eggNode = eggTable;
00333 } else if (animGroup->is_of_type(AnimGroup::get_class_type())) {
00334 EggTable *eggTable = new EggTable(animGroup->get_name());
00335 eggTable ->set_table_type(EggTable::TT_table);
00336 eggNode = eggTable;
00337 }
00338
00339 if (animGroup->is_of_type(AnimChannelMatrixXfmTable::get_class_type())) {
00340 AnimChannelMatrixXfmTable *xmfTable = DCAST(AnimChannelMatrixXfmTable, animGroup);
00341 EggXfmSAnim *egg_anim = new EggXfmSAnim("xform");
00342 egg_anim->set_fps(fps);
00343 for (int i = 0; i < num_matrix_components; i++) {
00344 string componentName(1, matrix_component_letters[i]);
00345 char table_id = matrix_component_letters[i];
00346 CPTA_stdfloat table = xmfTable->get_table(table_id);
00347
00348 if (xmfTable->has_table(table_id)) {
00349 for (unsigned int j = 0; j < table.size(); j++) {
00350 egg_anim->add_component_data(componentName, table[(int)j]);
00351 }
00352 }
00353 }
00354 eggNode->add_child(egg_anim);
00355 }
00356 for (int i = 0; i < num_children; i++) {
00357 AnimGroup *animChild = animGroup->get_child(i);
00358 EggGroupNode *eggChildNode = convert_animGroup_node(animChild, fps);
00359 if (eggChildNode!=NULL) {
00360 nassertr(eggNode!=NULL, NULL);
00361 eggNode->add_child(eggChildNode);
00362 }
00363 }
00364 return eggNode;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373 void BamToEgg::
00374 convert_anim_node(AnimBundleNode *node, const WorkingNodePath &node_path,
00375 EggGroupNode *egg_parent, bool has_decal) {
00376
00377
00378
00379 EggTable *eggTable = new EggTable();
00380
00381 _data->add_child(eggTable);
00382
00383 AnimBundle *animBundle = node->get_bundle();
00384
00385
00386
00387 EggGroupNode *eggAnimation = convert_animGroup_node(animBundle, animBundle->get_base_frame_rate());
00388 eggTable->add_child(eggAnimation);
00389 }
00390
00391
00392
00393
00394
00395
00396
00397 void BamToEgg::
00398 convert_character_bundle(PartGroup *bundleNode, EggGroupNode *egg_parent, CharacterJointMap *jointMap) {
00399 int num_children = bundleNode->get_num_children();
00400
00401 EggGroupNode *joint_group = egg_parent;
00402 if (bundleNode->is_of_type(CharacterJoint::get_class_type())) {
00403 CharacterJoint *character_joint = DCAST(CharacterJoint, bundleNode);
00404
00405 LMatrix4 transformf;
00406 character_joint->get_net_transform(transformf);
00407 LMatrix4d transformd(LCAST(double, transformf));
00408 EggGroup *joint = new EggGroup(bundleNode->get_name());
00409 joint->add_matrix4(transformd);
00410 joint->set_group_type(EggGroup::GT_joint);
00411 joint_group = joint;
00412 egg_parent->add_child(joint_group);
00413 if (jointMap!=NULL) {
00414 CharacterJointMap::iterator mi = jointMap->find(character_joint);
00415 if (mi != jointMap->end()) {
00416 pvector<pair<EggVertex*,PN_stdfloat> > &joint_vertices = (*mi).second;
00417 pvector<pair<EggVertex*,PN_stdfloat> >::const_iterator vi;
00418 for (vi = joint_vertices.begin(); vi != joint_vertices.end(); ++vi) {
00419 joint->set_vertex_membership((*vi).first, (*vi).second);
00420 }
00421 }
00422 }
00423 }
00424
00425 for (int i = 0; i < num_children ; i++) {
00426 PartGroup *partGroup= bundleNode->get_child(i);
00427 convert_character_bundle(partGroup, joint_group, jointMap);
00428 }
00429
00430 }
00431
00432
00433
00434
00435
00436
00437
00438 void BamToEgg::
00439 convert_character_node(Character *node, const WorkingNodePath &node_path,
00440 EggGroupNode *egg_parent, bool has_decal) {
00441
00442
00443
00444 EggGroup *egg_group = new EggGroup(node->get_name());
00445 egg_group->set_dart_type(EggGroup::DT_default);
00446 egg_parent->add_child(egg_group);
00447 apply_node_properties(egg_group, node);
00448
00449 CharacterJointMap jointMap;
00450
00451
00452
00453
00454 int num_children = node->get_num_children();
00455 int num_bundles = node->get_num_bundles();
00456
00457 for (int i = 0; i < num_children; i++) {
00458 PandaNode *child = node->get_child(i);
00459
00460 if (child->is_geom_node()) {
00461 convert_geom_node(DCAST(GeomNode, child), WorkingNodePath(node_path, child), egg_group, has_decal, &jointMap);
00462 }
00463 }
00464
00465 for (int i = 0; i < num_bundles ; i++) {
00466 PartBundle *bundle= node->get_bundle(i);
00467 convert_character_bundle(bundle, egg_group, &jointMap);
00468 }
00469
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479 void BamToEgg::
00480 convert_collision_node(CollisionNode *node, const WorkingNodePath &node_path,
00481 EggGroupNode *egg_parent, bool has_decal) {
00482
00483
00484 EggGroup *egg_group = new EggGroup(node->get_name());
00485 egg_parent->add_child(egg_group);
00486 apply_node_properties(egg_group, node, false);
00487
00488
00489 egg_group->set_cs_type(EggGroup::CST_polyset);
00490 egg_group->set_collide_flags(EggGroup::CF_descend);
00491
00492 NodePath np = node_path.get_node_path();
00493 CPT(TransformState) net_transform = np.get_net_transform();
00494 LMatrix4 net_mat = net_transform->get_mat();
00495 LMatrix4 inv = LCAST(PN_stdfloat, egg_parent->get_vertex_frame_inv());
00496 net_mat = net_mat * inv;
00497
00498 int num_solids = node->get_num_solids();
00499
00500 if (num_solids > 0) {
00501
00502 EggVertexPool *cvpool = new EggVertexPool("vpool-collision");
00503 egg_group->add_child(cvpool);
00504
00505
00506 for (int i = 0; i < num_solids; i++) {
00507 CPT(CollisionSolid) child = node->get_solid(i);
00508 if (child->is_of_type(CollisionPolygon::get_class_type())) {
00509 EggPolygon *egg_poly = new EggPolygon;
00510 egg_group->add_child(egg_poly);
00511
00512 CPT(CollisionPolygon) poly = DCAST(CollisionPolygon, child);
00513 int num_points = poly->get_num_points();
00514 for (int j = 0; j < num_points; j++) {
00515 EggVertex egg_vert;
00516 egg_vert.set_pos(LCAST(double, poly->get_point(j) * net_mat));
00517 egg_vert.set_normal(LCAST(double, poly->get_normal() * net_mat));
00518
00519 EggVertex *new_egg_vert = cvpool->create_unique_vertex(egg_vert);
00520 egg_poly->add_vertex(new_egg_vert);
00521 }
00522 } else if (child->is_of_type(CollisionPlane::get_class_type())) {
00523 nout << "Encountered unhandled collsion type: CollisionPlane" << "\n";
00524 } else if (child->is_of_type(CollisionSphere::get_class_type())) {
00525 nout << "Encountered unhandled collsion type: CollisionSphere" << "\n";
00526 } else if (child->is_of_type(CollisionInvSphere::get_class_type())) {
00527 nout << "Encountered unhandled collsion type: CollisionInvSphere" << "\n";
00528 } else if (child->is_of_type(CollisionTube::get_class_type())) {
00529 nout << "Encountered unhandled collsion type: CollisionTube" << "\n";
00530 } else {
00531 nout << "Encountered unknown CollisionSolid" << "\n";
00532 }
00533 }
00534 }
00535
00536
00537 recurse_nodes(node_path, egg_group, has_decal);
00538 }
00539
00540
00541
00542
00543
00544
00545
00546 void BamToEgg::
00547 convert_geom_node(GeomNode *node, const WorkingNodePath &node_path,
00548 EggGroupNode *egg_parent, bool has_decal, CharacterJointMap *jointMap) {
00549 PT(EggGroup) egg_group = new EggGroup(node->get_name());
00550 bool fancy_attributes = apply_node_properties(egg_group, node);
00551
00552 if (node->get_effects()->has_decal()) {
00553 has_decal = true;
00554 }
00555
00556 if (has_decal) {
00557 egg_group->set_decal_flag(true);
00558 }
00559
00560 if (fancy_attributes || has_decal) {
00561
00562
00563
00564 egg_parent->add_child(egg_group.p());
00565 egg_parent = egg_group;
00566 }
00567
00568 NodePath np = node_path.get_node_path();
00569 CPT(RenderState) net_state = np.get_net_state();
00570 CPT(TransformState) net_transform = np.get_net_transform();
00571 LMatrix4 net_mat = net_transform->get_mat();
00572 LMatrix4 inv = LCAST(PN_stdfloat, egg_parent->get_vertex_frame_inv());
00573 net_mat = net_mat * inv;
00574
00575
00576 int num_geoms = node->get_num_geoms();
00577 for (int i = 0; i < num_geoms; ++i) {
00578 CPT(RenderState) geom_state = net_state->compose(node->get_geom_state(i));
00579
00580 const Geom *geom = node->get_geom(i);
00581 int num_primitives = geom->get_num_primitives();
00582 for (int j = 0; j < num_primitives; ++j) {
00583 const GeomPrimitive *primitive = geom->get_primitive(j);
00584 CPT(GeomPrimitive) simple = primitive->decompose();
00585 CPT(GeomVertexData) vdata = geom->get_vertex_data();
00586
00587 convert_primitive(vdata, simple, geom_state,
00588 net_mat, egg_parent, jointMap);
00589 }
00590 }
00591
00592 recurse_nodes(node_path, egg_parent, has_decal);
00593 }
00594
00595
00596
00597
00598
00599
00600 void BamToEgg::
00601 convert_primitive(const GeomVertexData *vertex_data,
00602 const GeomPrimitive *primitive,
00603 const RenderState *net_state,
00604 const LMatrix4 &net_mat, EggGroupNode *egg_parent,
00605 CharacterJointMap *jointMap) {
00606 GeomVertexReader reader(vertex_data);
00607
00608
00609 LVecBase4 color_scale(1.0f, 1.0f, 1.0f, 1.0f);
00610 const ColorScaleAttrib *csa = DCAST(ColorScaleAttrib, net_state->get_attrib(ColorScaleAttrib::get_class_type()));
00611 if (csa != (const ColorScaleAttrib *)NULL) {
00612 color_scale = csa->get_scale();
00613 }
00614
00615
00616 bool has_color_override = false;
00617 bool has_color_off = false;
00618 LColor color_override;
00619 const ColorAttrib *ca = DCAST(ColorAttrib, net_state->get_attrib(ColorAttrib::get_class_type()));
00620 if (ca != (const ColorAttrib *)NULL) {
00621 if (ca->get_color_type() == ColorAttrib::T_flat) {
00622 has_color_override = true;
00623 color_override = ca->get_color();
00624 color_override.set(color_override[0] * color_scale[0],
00625 color_override[1] * color_scale[1],
00626 color_override[2] * color_scale[2],
00627 color_override[3] * color_scale[3]);
00628
00629 } else if (ca->get_color_type() == ColorAttrib::T_off) {
00630 has_color_off = true;
00631 }
00632 }
00633
00634
00635 EggTexture *egg_tex = (EggTexture *)NULL;
00636 const TextureAttrib *ta = DCAST(TextureAttrib, net_state->get_attrib(TextureAttrib::get_class_type()));
00637 if (ta != (const TextureAttrib *)NULL) {
00638 egg_tex = get_egg_texture(ta->get_texture());
00639 }
00640
00641
00642 if ((ta != (const TextureAttrib *)NULL) && (egg_tex != (const EggTexture *)NULL)) {
00643 TextureStage* tex_stage = ta->get_on_stage(0);
00644 if (tex_stage != (const TextureStage *)NULL) {
00645 switch (tex_stage->get_mode()) {
00646 case TextureStage::M_modulate:
00647 if (has_color_off == true) {
00648 egg_tex->set_env_type(EggTexture::ET_replace);
00649 } else {
00650 egg_tex->set_env_type(EggTexture::ET_modulate);
00651 }
00652 break;
00653 case TextureStage::M_decal:
00654 egg_tex->set_env_type(EggTexture::ET_decal);
00655 break;
00656 case TextureStage::M_blend:
00657 egg_tex->set_env_type(EggTexture::ET_blend);
00658 break;
00659 case TextureStage::M_replace:
00660 egg_tex->set_env_type(EggTexture::ET_replace);
00661 break;
00662 case TextureStage::M_add:
00663 egg_tex->set_env_type(EggTexture::ET_add);
00664 break;
00665 case TextureStage::M_blend_color_scale:
00666 egg_tex->set_env_type(EggTexture::ET_blend_color_scale);
00667 break;
00668 default:
00669 break;
00670 }
00671 }
00672 }
00673
00674
00675 bool bface = false;
00676 const RenderAttrib *cf_attrib = net_state->get_attrib(CullFaceAttrib::get_class_type());
00677 if (cf_attrib != (const RenderAttrib *)NULL) {
00678 const CullFaceAttrib *cfa = DCAST(CullFaceAttrib, cf_attrib);
00679 if (cfa->get_effective_mode() == CullFaceAttrib::M_cull_none) {
00680 bface = true;
00681 }
00682 }
00683
00684
00685 bool has_depthwrite = false;
00686 DepthWriteAttrib::Mode depthwrite = DepthWriteAttrib::M_on;
00687 const RenderAttrib *dw_attrib = net_state->get_attrib(DepthWriteAttrib::get_class_type());
00688 if (dw_attrib != (const RenderAttrib *)NULL) {
00689 const DepthWriteAttrib *dwa = DCAST(DepthWriteAttrib, dw_attrib);
00690 depthwrite = dwa->get_mode();
00691 has_depthwrite = true;
00692 }
00693
00694
00695 bool has_transparency = false;
00696 TransparencyAttrib::Mode transparency = TransparencyAttrib::M_none;
00697 const RenderAttrib *tr_attrib = net_state->get_attrib(TransparencyAttrib::get_class_type());
00698 if (tr_attrib != (const RenderAttrib *)NULL) {
00699 const TransparencyAttrib *tra = DCAST(TransparencyAttrib, tr_attrib);
00700 transparency = tra->get_mode();
00701 has_transparency = true;
00702 }
00703 if (has_transparency && (egg_tex != (EggTexture *)NULL)) {
00704 EggRenderMode::AlphaMode tex_trans = EggRenderMode::AM_unspecified;
00705 switch (transparency) {
00706 case TransparencyAttrib::M_none:
00707 tex_trans = EggRenderMode::AM_off;
00708 break;
00709 case TransparencyAttrib::M_alpha:
00710 if (has_depthwrite && (depthwrite == DepthWriteAttrib::M_off)) {
00711 tex_trans = EggRenderMode::AM_blend_no_occlude;
00712 has_depthwrite = false;
00713 } else {
00714 tex_trans = EggRenderMode::AM_blend;
00715 }
00716 break;
00717 case TransparencyAttrib::M_multisample:
00718 tex_trans = EggRenderMode::AM_ms;
00719 break;
00720 case TransparencyAttrib::M_multisample_mask:
00721 tex_trans = EggRenderMode::AM_ms_mask;
00722 break;
00723 case TransparencyAttrib::M_binary:
00724 tex_trans = EggRenderMode::AM_binary;
00725 break;
00726 case TransparencyAttrib::M_dual:
00727 tex_trans = EggRenderMode::AM_dual;
00728 break;
00729 default:
00730 case TransparencyAttrib::M_notused:
00731 break;
00732 }
00733 if (tex_trans != EggRenderMode::AM_unspecified) {
00734 egg_tex->set_alpha_mode(tex_trans);
00735 }
00736 }
00737
00738
00739 LNormal normal;
00740 LColor color;
00741 CPT(TransformBlendTable) transformBlendTable = vertex_data->get_transform_blend_table();
00742
00743 int num_primitives = primitive->get_num_primitives();
00744 int num_vertices = primitive->get_num_vertices_per_primitive();
00745
00746 EggPrimitive *(*make_func)(void);
00747
00748 if (primitive->is_of_type(GeomTriangles::get_class_type())) {
00749 make_func = make_egg_polygon;
00750 } else if (primitive->is_of_type(GeomPoints::get_class_type())) {
00751 make_func = make_egg_point;
00752 } else if (primitive->is_of_type(GeomLines::get_class_type())) {
00753 make_func = make_egg_line;
00754 } else {
00755
00756 return;
00757 }
00758
00759 for (int i = 0; i < num_primitives; ++i) {
00760 PT(EggPrimitive) egg_prim = (*make_func)();
00761
00762 egg_parent->add_child(egg_prim);
00763 if (egg_tex != (EggTexture *)NULL) {
00764 egg_prim->set_texture(egg_tex);
00765 }
00766
00767 if (bface) {
00768 egg_prim->set_bface_flag(true);
00769 }
00770
00771 for (int j = 0; j < num_vertices; j++) {
00772 EggVertex egg_vert;
00773
00774
00775 reader.set_row(primitive->get_vertex(i * num_vertices + j));
00776
00777 reader.set_column(InternalName::get_vertex());
00778 LVertex vertex = reader.get_data3();
00779 egg_vert.set_pos(LCAST(double, vertex * net_mat));
00780
00781 if (vertex_data->has_column(InternalName::get_normal())) {
00782 reader.set_column(InternalName::get_normal());
00783 LNormal normal = reader.get_data3();
00784 egg_vert.set_normal(LCAST(double, normal * net_mat));
00785 }
00786 if (has_color_override) {
00787 egg_vert.set_color(color_override);
00788
00789 } else if (!has_color_off) {
00790 LColor color(1.0f, 1.0f, 1.0f, 1.0f);
00791 if (vertex_data->has_column(InternalName::get_color())) {
00792 reader.set_column(InternalName::get_color());
00793 color = reader.get_data4();
00794 }
00795 egg_vert.set_color(LColor(color[0] * color_scale[0],
00796 color[1] * color_scale[1],
00797 color[2] * color_scale[2],
00798 color[3] * color_scale[3]));
00799 }
00800
00801 if (vertex_data->has_column(InternalName::get_texcoord())) {
00802 reader.set_column(InternalName::get_texcoord());
00803 LTexCoord uv = reader.get_data2();
00804 egg_vert.set_uv(LCAST(double, uv));
00805 }
00806
00807 EggVertex *new_egg_vert = _vpool->create_unique_vertex(egg_vert);
00808
00809 if ((vertex_data->has_column(InternalName::get_transform_blend())) &&
00810 (jointMap!=NULL) && (transformBlendTable!=NULL)) {
00811 reader.set_column(InternalName::get_transform_blend());
00812 int idx = reader.get_data1i();
00813 const TransformBlend &blend = transformBlendTable->get_blend(idx);
00814 int num_weights = blend.get_num_transforms();
00815 for (int k = 0; k < num_weights; ++k) {
00816 PN_stdfloat weight = blend.get_weight(k);
00817 if (weight!=0) {
00818 const VertexTransform *vertex_transform = blend.get_transform(k);
00819 if (vertex_transform->is_of_type(JointVertexTransform::get_class_type())) {
00820 const JointVertexTransform *joint_vertex_transform = DCAST(const JointVertexTransform, vertex_transform);
00821
00822 CharacterJointMap::iterator mi = jointMap->find(joint_vertex_transform->get_joint());
00823 if (mi == jointMap->end()) {
00824 mi = jointMap->insert(CharacterJointMap::value_type(joint_vertex_transform->get_joint(), pvector<pair<EggVertex*,PN_stdfloat> >())).first;
00825 }
00826 pvector<pair<EggVertex*,PN_stdfloat> > &joint_vertices = (*mi).second;
00827 joint_vertices.push_back(pair<EggVertex*,PN_stdfloat>(new_egg_vert, weight));
00828 }
00829 }
00830 }
00831 }
00832
00833 egg_prim->add_vertex(new_egg_vert);
00834 }
00835 }
00836 }
00837
00838
00839
00840
00841
00842
00843 void BamToEgg::
00844 recurse_nodes(const WorkingNodePath &node_path, EggGroupNode *egg_parent,
00845 bool has_decal) {
00846 PandaNode *node = node_path.node();
00847 int num_children = node->get_num_children();
00848
00849 for (int i = 0; i < num_children; i++) {
00850 PandaNode *child = node->get_child(i);
00851 convert_node(WorkingNodePath(node_path, child), egg_parent, has_decal);
00852 }
00853 }
00854
00855
00856
00857
00858
00859
00860
00861
00862 bool BamToEgg::
00863 apply_node_properties(EggGroup *egg_group, PandaNode *node, bool allow_backstage) {
00864 bool any_applied = false;
00865
00866 if (node->is_overall_hidden() && allow_backstage) {
00867
00868
00869
00870 egg_group->add_object_type("backstage");
00871 }
00872
00873 if (node->has_tags()) {
00874 if (apply_tags(egg_group, node)) {
00875 any_applied = true;
00876 }
00877 }
00878
00879 if (node->is_of_type(ModelNode::get_class_type())) {
00880 ModelNode *model_node = DCAST(ModelNode, node);
00881 switch (model_node->get_preserve_transform()) {
00882 case ModelNode::PT_none:
00883 case ModelNode::PT_drop_node:
00884 break;
00885
00886 case ModelNode::PT_net:
00887 egg_group->set_dcs_type(EggGroup::DC_net);
00888 break;
00889
00890 case ModelNode::PT_local:
00891 egg_group->set_dcs_type(EggGroup::DC_local);
00892 break;
00893
00894 case ModelNode::PT_no_touch:
00895 egg_group->set_dcs_type(EggGroup::DC_no_touch);
00896 break;
00897 }
00898 }
00899
00900 const RenderEffects *effects = node->get_effects();
00901 const RenderEffect *effect = effects->get_effect(BillboardEffect::get_class_type());
00902 if (effect != (RenderEffect *)NULL) {
00903 const BillboardEffect *bbe = DCAST(BillboardEffect, effect);
00904 if (bbe->get_axial_rotate()) {
00905 egg_group->set_billboard_type(EggGroup::BT_axis);
00906 any_applied = true;
00907
00908 } else if (bbe->get_eye_relative()) {
00909 egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
00910 any_applied = true;
00911
00912 } else {
00913 egg_group->set_billboard_type(EggGroup::BT_point_world_relative);
00914 any_applied = true;
00915 }
00916 }
00917
00918 const TransformState *transform = node->get_transform();
00919 if (!transform->is_identity()) {
00920 if (transform->has_components()) {
00921
00922
00923 const LVecBase3 &scale = transform->get_scale();
00924 const LQuaternion &quat = transform->get_quat();
00925 const LVecBase3 &pos = transform->get_pos();
00926 if (!scale.almost_equal(LVecBase3(1.0f, 1.0f, 1.0f))) {
00927 egg_group->add_scale3d(LCAST(double, scale));
00928 }
00929 if (!quat.is_identity()) {
00930 egg_group->add_rotate3d(LCAST(double, quat));
00931 }
00932 if (!pos.almost_equal(LVecBase3::zero())) {
00933 egg_group->add_translate3d(LCAST(double, pos));
00934 }
00935
00936 } else if (transform->has_mat()) {
00937
00938 const LMatrix4 &mat = transform->get_mat();
00939 egg_group->set_transform3d(LCAST(double, mat));
00940 }
00941 any_applied = true;
00942 }
00943
00944 return any_applied;
00945 }
00946
00947
00948
00949
00950
00951
00952
00953 bool BamToEgg::
00954 apply_tags(EggGroup *egg_group, PandaNode *node) {
00955 ostringstream strm;
00956 char delimiter = '\n';
00957 string delimiter_str(1, delimiter);
00958 node->list_tags(strm, delimiter_str);
00959
00960 string data = strm.str();
00961 if (data.empty()) {
00962 return false;
00963 }
00964
00965 bool any_applied = false;
00966
00967 size_t p = 0;
00968 size_t q = data.find(delimiter);
00969 while (q != string::npos) {
00970 string tag = data.substr(p, q);
00971 if (apply_tag(egg_group, node, tag)) {
00972 any_applied = true;
00973 }
00974 p = q + 1;
00975 q = data.find(delimiter, p);
00976 }
00977
00978 string tag = data.substr(p);
00979 if (apply_tag(egg_group, node, tag)) {
00980 any_applied = true;
00981 }
00982
00983 return any_applied;
00984 }
00985
00986
00987
00988
00989
00990
00991 bool BamToEgg::
00992 apply_tag(EggGroup *egg_group, PandaNode *node, const string &tag) {
00993 if (!node->has_tag(tag)) {
00994 return false;
00995 }
00996
00997 string value = node->get_tag(tag);
00998 egg_group->set_tag(tag, value);
00999 return true;
01000 }
01001
01002
01003
01004
01005
01006
01007
01008 EggTexture *BamToEgg::
01009 get_egg_texture(Texture *tex) {
01010 if (tex != (Texture *)NULL) {
01011 if (tex->has_filename()) {
01012 Filename filename = _path_replace->convert_path(tex->get_filename());
01013 EggTexture temp(filename.get_basename_wo_extension(), filename);
01014 if (tex->has_alpha_filename()) {
01015 Filename alpha = _path_replace->convert_path(tex->get_alpha_filename());
01016 temp.set_alpha_filename(alpha);
01017 }
01018
01019 switch (tex->get_minfilter()) {
01020 case Texture::FT_nearest:
01021 temp.set_minfilter(EggTexture::FT_nearest);
01022 break;
01023 case Texture::FT_linear:
01024 temp.set_minfilter(EggTexture::FT_linear);
01025 break;
01026 case Texture::FT_nearest_mipmap_nearest:
01027 temp.set_minfilter(EggTexture::FT_nearest_mipmap_nearest);
01028 break;
01029 case Texture::FT_linear_mipmap_nearest:
01030 temp.set_minfilter(EggTexture::FT_linear_mipmap_nearest);
01031 break;
01032 case Texture::FT_nearest_mipmap_linear:
01033 temp.set_minfilter(EggTexture::FT_nearest_mipmap_linear);
01034 break;
01035 case Texture::FT_linear_mipmap_linear:
01036 temp.set_minfilter(EggTexture::FT_linear_mipmap_linear);
01037 break;
01038
01039 default:
01040 break;
01041 }
01042
01043 switch (tex->get_magfilter()) {
01044 case Texture::FT_nearest:
01045 temp.set_magfilter(EggTexture::FT_nearest);
01046 break;
01047 case Texture::FT_linear:
01048 temp.set_magfilter(EggTexture::FT_linear);
01049 break;
01050
01051 default:
01052 break;
01053 }
01054
01055 switch (tex->get_wrap_u()) {
01056 case Texture::WM_clamp:
01057 temp.set_wrap_u(EggTexture::WM_clamp);
01058 break;
01059 case Texture::WM_repeat:
01060 temp.set_wrap_u(EggTexture::WM_repeat);
01061 break;
01062
01063 default:
01064
01065
01066 break;
01067 }
01068
01069 switch (tex->get_wrap_v()) {
01070 case Texture::WM_clamp:
01071 temp.set_wrap_v(EggTexture::WM_clamp);
01072 break;
01073 case Texture::WM_repeat:
01074 temp.set_wrap_v(EggTexture::WM_repeat);
01075 break;
01076
01077 default:
01078
01079
01080 break;
01081 }
01082
01083 switch (tex->get_format()) {
01084 case Texture::F_red:
01085 temp.set_format(EggTexture::F_red);
01086 break;
01087 case Texture::F_green:
01088 temp.set_format(EggTexture::F_green);
01089 break;
01090 case Texture::F_blue:
01091 temp.set_format(EggTexture::F_blue);
01092 break;
01093 case Texture::F_alpha:
01094 temp.set_format(EggTexture::F_alpha);
01095 break;
01096 case Texture::F_rgb:
01097 temp.set_format(EggTexture::F_rgb);
01098 break;
01099 case Texture::F_rgb5:
01100 temp.set_format(EggTexture::F_rgb5);
01101 break;
01102 case Texture::F_rgb8:
01103 temp.set_format(EggTexture::F_rgb8);
01104 break;
01105 case Texture::F_rgb12:
01106 temp.set_format(EggTexture::F_rgb12);
01107 break;
01108 case Texture::F_rgb332:
01109 temp.set_format(EggTexture::F_rgb332);
01110 break;
01111 case Texture::F_rgba:
01112 temp.set_format(EggTexture::F_rgba);
01113 break;
01114 case Texture::F_rgbm:
01115 temp.set_format(EggTexture::F_rgbm);
01116 break;
01117 case Texture::F_rgba4:
01118 temp.set_format(EggTexture::F_rgba4);
01119 break;
01120 case Texture::F_rgba5:
01121 temp.set_format(EggTexture::F_rgba5);
01122 break;
01123 case Texture::F_rgba8:
01124 temp.set_format(EggTexture::F_rgba8);
01125 break;
01126 case Texture::F_rgba12:
01127 temp.set_format(EggTexture::F_rgba12);
01128 break;
01129 case Texture::F_luminance:
01130 temp.set_format(EggTexture::F_luminance);
01131 break;
01132 case Texture::F_luminance_alpha:
01133 temp.set_format(EggTexture::F_luminance_alpha);
01134 break;
01135 case Texture::F_luminance_alphamask:
01136 temp.set_format(EggTexture::F_luminance_alphamask);
01137 break;
01138 default:
01139 break;
01140 }
01141
01142 return _textures.create_unique_texture(temp, ~EggTexture::E_tref_name);
01143 }
01144 }
01145
01146 return NULL;
01147 }
01148
01149
01150
01151
01152
01153
01154 EggPrimitive *BamToEgg::
01155 make_egg_polygon() {
01156 return new EggPolygon;
01157 }
01158
01159
01160
01161
01162
01163
01164 EggPrimitive *BamToEgg::
01165 make_egg_point() {
01166 return new EggPoint;
01167 }
01168
01169
01170
01171
01172
01173
01174 EggPrimitive *BamToEgg::
01175 make_egg_line() {
01176 return new EggLine;
01177 }
01178
01179 int main(int argc, char *argv[]) {
01180
01181 pystub();
01182
01183 BamToEgg prog;
01184 prog.parse_command_line(argc, argv);
01185 prog.run();
01186 return 0;
01187 }