Browse Source

egg-emulate-bface

David Rose 19 years ago
parent
commit
9253d0b298

+ 7 - 0
panda/src/egg2pg/config_egg2pg.cxx

@@ -145,6 +145,13 @@ ConfigVariableInt egg_max_indices
  PRC_DESC("Specifies the maximum number of vertex indices that will be "
           "added to any one GeomPrimitive by the egg loader."));
 
+ConfigVariableBool egg_emulate_bface
+("egg-emulate-bface", false,
+ PRC_DESC("When this is true, the bface flag applied to a polygon will "
+          "cause two different polygons to be created, back-to-back.  When "
+          "it is false, a single polygon will be created with the two_sided "
+          "flag set on it."));
+
 ConfigureFn(config_egg2pg) {
   init_libegg2pg();
 }

+ 1 - 0
panda/src/egg2pg/config_egg2pg.h

@@ -53,6 +53,7 @@ extern EXPCL_PANDAEGG ConfigVariableBool egg_suppress_hidden;
 extern EXPCL_PANDAEGG ConfigVariableEnum<EggRenderMode::AlphaMode> egg_alpha_mode;
 extern EXPCL_PANDAEGG ConfigVariableInt egg_max_vertices;
 extern EXPCL_PANDAEGG ConfigVariableInt egg_max_indices;
+extern EXPCL_PANDAEGG ConfigVariableBool egg_emulate_bface;
 
 extern EXPCL_PANDAEGG void init_libegg2pg();
 

+ 56 - 0
panda/src/egg2pg/eggLoader.cxx

@@ -189,6 +189,10 @@ build_graph() {
   // single polyset.
   separate_switches(_data);
 
+  if (egg_emulate_bface) {
+    emulate_bface(_data);
+  }
+
   // Then bin up the polysets and LOD nodes.
   _data->remove_invalid_primitives(true);
   EggBinner binner(*this);
@@ -1516,6 +1520,58 @@ separate_switches(EggNode *egg_node) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggLoader::emulate_bface
+//       Access: Private
+//  Description: Looks for EggPolygons with a bface flag applied to
+//               them.  Any such polygons are duplicated into a pair
+//               of back-to-back polygons, and the bface flag is
+//               removed.
+////////////////////////////////////////////////////////////////////
+void EggLoader::
+emulate_bface(EggNode *egg_node) {
+  if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
+    EggGroupNode *egg_group = DCAST(EggGroupNode, egg_node);
+    PT(EggGroupNode) dup_prims = new EggGroupNode;
+
+    EggGroupNode::iterator ci;
+    for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
+      PT(EggNode) child = (*ci);
+      if (child->is_of_type(EggPolygon::get_class_type())) {
+        EggPolygon *poly = DCAST(EggPolygon, child);
+        if (poly->get_bface_flag()) {
+          poly->set_bface_flag(false);
+
+          PT(EggPolygon) dup_poly = new EggPolygon(*poly);
+          dup_poly->reverse_vertex_ordering();
+          if (dup_poly->has_normal()) {
+            dup_poly->set_normal(-dup_poly->get_normal());
+          }
+
+          // Also reverse the normal on any vertices.
+          EggPolygon::iterator vi;
+          for (vi = dup_poly->begin(); vi != dup_poly->end(); ++vi) {
+            EggVertex *vertex = (*vi);
+            if (vertex->has_normal()) {
+              EggVertex dup_vertex(*vertex);
+              dup_vertex.set_normal(-dup_vertex.get_normal());
+              EggVertex *new_vertex = vertex->get_pool()->create_unique_vertex(dup_vertex);
+              dup_poly->replace(vi, new_vertex);
+            }
+          }
+          dup_prims->add_child(dup_poly);
+        }
+      }
+
+      emulate_bface(child);
+    }
+
+    // Now that we've iterated through all the children, add in any
+    // duplicated polygons we generated.
+    egg_group->steal_children(*dup_prims);
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggLoader::make_node
 //       Access: Private

+ 1 - 0
panda/src/egg2pg/eggLoader.h

@@ -129,6 +129,7 @@ private:
   PT(TextureStage) make_texture_stage(const EggTexture *egg_tex);
 
   void separate_switches(EggNode *egg_node);
+  void emulate_bface(EggNode *egg_node);
 
   PandaNode *make_node(EggNode *egg_node, PandaNode *parent);
   PandaNode *make_node(EggBin *egg_bin, PandaNode *parent);