Преглед на файлове

SceneGraphReducer::remove_column()

David Rose преди 18 години
родител
ревизия
0b703e2f14

+ 25 - 0
panda/src/gobj/geomVertexArrayFormat.cxx

@@ -314,6 +314,8 @@ remove_column(const InternalName *name) {
 ////////////////////////////////////////////////////////////////////
 void GeomVertexArrayFormat::
 clear_columns() {
+  nassertv(!_is_registered);
+
   _columns.clear();
   _columns_by_name.clear();
   _columns_unsorted = false;
@@ -322,6 +324,29 @@ clear_columns() {
   _pad_to = 1;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexArrayFormat::pack_columns
+//       Access: Published
+//  Description: Removes wasted space between columns.
+////////////////////////////////////////////////////////////////////
+void GeomVertexArrayFormat::
+pack_columns() {
+  nassertv(!_is_registered);
+
+  Columns orig_columns;
+  orig_columns.swap(_columns);
+  clear_columns();
+
+  int last_pos = 0;
+
+  Columns::const_iterator ci;
+  for (ci = orig_columns.begin(); ci != orig_columns.end(); ++ci) {
+    GeomVertexColumn *column = (*ci);
+    add_column(column->get_name(), column->get_num_components(),
+               column->get_numeric_type(), column->get_contents());
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomVertexArrayFormat::get_column
 //       Access: Published

+ 1 - 0
panda/src/gobj/geomVertexArrayFormat.h

@@ -95,6 +95,7 @@ PUBLISHED:
   int add_column(const GeomVertexColumn &column);
   void remove_column(const InternalName *name);
   void clear_columns();
+  void pack_columns();
 
   INLINE int get_num_columns() const;
   INLINE const GeomVertexColumn *get_column(int i) const;

+ 15 - 0
panda/src/gobj/geomVertexFormat.cxx

@@ -519,6 +519,21 @@ remove_column(const InternalName *name) {
   // problem; quietly return.
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexFormat::pack_columns
+//       Access: Published
+//  Description: Removes wasted space between columns.
+////////////////////////////////////////////////////////////////////
+void GeomVertexFormat::
+pack_columns() {
+  nassertv(!_is_registered);
+  Arrays::const_iterator ai;
+  for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
+    (*ai)->pack_columns();
+  }
+}
+
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomVertexFormat::output
 //       Access: Published

+ 1 - 0
panda/src/gobj/geomVertexFormat.h

@@ -98,6 +98,7 @@ PUBLISHED:
   INLINE bool has_column(const InternalName *name) const;
 
   void remove_column(const InternalName *name);
+  void pack_columns();
 
   INLINE int get_num_points() const;
   INLINE const InternalName *get_point(int n) const;

+ 13 - 0
panda/src/pgraph/geomTransformer.I

@@ -86,6 +86,19 @@ operator < (const GeomTransformer::SourceColors &other) const {
   return (_color.compare_to(other._color) < 0);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomTransformer::SourceFormat::Ordering Operator
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE bool GeomTransformer::SourceFormat::
+operator < (const GeomTransformer::SourceFormat &other) const {
+  if (_format != other._format) {
+    return _format < other._format;
+  }
+  return _vertex_data < other._vertex_data;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomTransformer::NewCollectedKey::Ordering Operator
 //       Access: Public

+ 90 - 8
panda/src/pgraph/geomTransformer.cxx

@@ -32,10 +32,11 @@
 #include "geomMunger.h"
 #include "config_pgraph.h"
 
-static PStatCollector apply_vertex_collector("*:Flatten:apply:vertex");
-static PStatCollector apply_texcoord_collector("*:Flatten:apply:texcoord");
-static PStatCollector apply_set_color_collector("*:Flatten:apply:set color");
-static PStatCollector apply_scale_color_collector("*:Flatten:apply:scale color");
+PStatCollector GeomTransformer::_apply_vertex_collector("*:Flatten:apply:vertex");
+PStatCollector GeomTransformer::_apply_texcoord_collector("*:Flatten:apply:texcoord");
+PStatCollector GeomTransformer::_apply_set_color_collector("*:Flatten:apply:set color");
+PStatCollector GeomTransformer::_apply_scale_color_collector("*:Flatten:apply:scale color");
+PStatCollector GeomTransformer::_apply_set_format_collector("*:Flatten:apply:set format");
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomTransformer::Constructor
@@ -78,7 +79,7 @@ GeomTransformer::
 ////////////////////////////////////////////////////////////////////
 bool GeomTransformer::
 transform_vertices(Geom *geom, const LMatrix4f &mat) {
-  PStatTimer timer(apply_vertex_collector);
+  PStatTimer timer(_apply_vertex_collector);
 
   nassertr(geom != (Geom *)NULL, false);
   SourceVertices sv;
@@ -165,7 +166,7 @@ transform_vertices(GeomNode *node, const LMatrix4f &mat) {
 bool GeomTransformer::
 transform_texcoords(Geom *geom, const InternalName *from_name, 
                     InternalName *to_name, const LMatrix4f &mat) {
-  PStatTimer timer(apply_texcoord_collector);
+  PStatTimer timer(_apply_texcoord_collector);
 
   nassertr(geom != (Geom *)NULL, false);
 
@@ -252,7 +253,7 @@ transform_texcoords(GeomNode *node, const InternalName *from_name,
 ////////////////////////////////////////////////////////////////////
 bool GeomTransformer::
 set_color(Geom *geom, const Colorf &color) {
-  PStatTimer timer(apply_set_color_collector);
+  PStatTimer timer(_apply_set_color_collector);
 
   SourceColors sc;
   sc._color = color;
@@ -311,7 +312,7 @@ set_color(GeomNode *node, const Colorf &color) {
 ////////////////////////////////////////////////////////////////////
 bool GeomTransformer::
 transform_colors(Geom *geom, const LVecBase4f &scale) {
-  PStatTimer timer(apply_scale_color_collector);
+  PStatTimer timer(_apply_scale_color_collector);
 
   nassertr(geom != (Geom *)NULL, false);
 
@@ -392,6 +393,87 @@ apply_state(GeomNode *node, const RenderState *state) {
   return any_changed;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomTransformer::set_format
+//       Access: Public
+//  Description: Changes the GeomVertexData of the indicated Geom to
+//               use the specified format.
+////////////////////////////////////////////////////////////////////
+bool GeomTransformer::
+set_format(Geom *geom, const GeomVertexFormat *new_format) {
+  PStatTimer timer(_apply_set_format_collector);
+
+  nassertr(geom != (Geom *)NULL, false);
+
+  SourceFormat sf;
+  sf._format = new_format;
+  sf._vertex_data = geom->get_vertex_data();
+  
+  PT(GeomVertexData) &new_data = _format[sf];
+  if (new_data.is_null()) {
+    if (sf._vertex_data->get_format() == new_format) {
+      // No change.
+      return false;
+    }
+
+    // We have not yet converted this vertex data.  Do so now.
+    new_data = new GeomVertexData(*sf._vertex_data);
+    new_data->set_format(new_format);
+  }
+  
+  geom->set_vertex_data(new_data);
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomTransformer::remove_column
+//       Access: Public
+//  Description: Removes the named column from the vertex data in the
+//               Geom.  Returns true if the Geom was changed, false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+bool GeomTransformer::
+remove_column(Geom *geom, const InternalName *column) {
+  CPT(GeomVertexFormat) format = geom->get_vertex_data()->get_format();
+  if (!format->has_column(column)) {
+    return false;
+  }
+
+  PT(GeomVertexFormat) new_format = new GeomVertexFormat(*format);
+  new_format->remove_column(column);
+  new_format->pack_columns();
+  format = GeomVertexFormat::register_format(new_format);
+
+  return set_format(geom, format);
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomTransformer::remove_column
+//       Access: Public
+//  Description: Removes the named column from the vertex datas within
+//               the GeomNode.  Returns true if the GeomNode was
+//               changed, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool GeomTransformer::
+remove_column(GeomNode *node, const InternalName *column) {
+  bool any_changed = false;
+
+  GeomNode::CDWriter cdata(node->_cycler);
+  GeomNode::GeomList::iterator gi;
+  GeomNode::GeomList &geoms = *(cdata->modify_geoms());
+  for (gi = geoms.begin(); gi != geoms.end(); ++gi) {
+    GeomNode::GeomEntry &entry = (*gi);
+    PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
+    if (remove_column(new_geom, column)) {
+      entry._geom = new_geom;
+      any_changed = true;
+    }
+  }
+
+  return any_changed;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomTransformer::collect_vertex_data
 //       Access: Public

+ 21 - 0
panda/src/pgraph/geomTransformer.h

@@ -71,6 +71,10 @@ public:
 
   bool apply_state(GeomNode *node, const RenderState *state);
 
+  bool set_format(Geom *geom, const GeomVertexFormat *new_format);
+  bool remove_column(Geom *geom, const InternalName *column);
+  bool remove_column(GeomNode *node, const InternalName *column);
+
   int collect_vertex_data(Geom *geom, int collect_bits);
   int collect_vertex_data(GeomNode *node, int collect_bits);
 
@@ -116,6 +120,17 @@ private:
   // modified from the original colors (e.g. via a ColorScaleAttrib).
   NewColors _fcolors, _tcolors;
 
+  // For set_format(): record (format + vertex_data) -> vertex_data.
+  class SourceFormat {
+  public:
+    INLINE bool operator < (const SourceFormat &other) const;
+
+    CPT(GeomVertexFormat) _format;
+    CPT(GeomVertexData) _vertex_data;
+  };
+  typedef pmap<SourceFormat, PT(GeomVertexData) > NewFormat;
+  NewFormat _format;
+
   class AlreadyCollectedData {
   public:
     CPT(GeomVertexData) _data;
@@ -135,6 +150,12 @@ private:
   };
   typedef pmap< NewCollectedKey, PT(GeomVertexData) > NewCollectedData;
   NewCollectedData _new_collected_data;
+
+  static PStatCollector _apply_vertex_collector;
+  static PStatCollector _apply_texcoord_collector;
+  static PStatCollector _apply_set_color_collector;
+  static PStatCollector _apply_scale_color_collector;
+  static PStatCollector _apply_set_format_collector;
 };
 
 #include "geomTransformer.I"

+ 42 - 1
panda/src/pgraph/sceneGraphReducer.cxx

@@ -28,6 +28,7 @@
 
 PStatCollector SceneGraphReducer::_flatten_collector("*:Flatten:flatten");
 PStatCollector SceneGraphReducer::_apply_collector("*:Flatten:apply");
+PStatCollector SceneGraphReducer::_remove_column_collector("*:Flatten:remove column");
 PStatCollector SceneGraphReducer::_collect_collector("*:Flatten:collect");
 PStatCollector SceneGraphReducer::_make_nonindexed_collector("*:Flatten:make nonindexed");
 PStatCollector SceneGraphReducer::_unify_collector("*:Flatten:unify");
@@ -129,6 +130,19 @@ flatten(PandaNode *root, int combine_siblings_bits) {
   return num_total_nodes;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: SceneGraphReducer::remove_column
+//       Access: Published
+//  Description: Removes the indicated data column from any
+//               GeomVertexDatas found at the indicated root and
+//               below.  Returns the number of GeomNodes modified.
+////////////////////////////////////////////////////////////////////
+int SceneGraphReducer::
+remove_column(PandaNode *root, const InternalName *column) {
+  PStatTimer timer(_remove_column_collector);
+  return r_remove_column(root, column, _transformer);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: SceneGraphReducer::unify
 //       Access: Published
@@ -675,6 +689,33 @@ choose_name(PandaNode *preserve, PandaNode *source1, PandaNode *source2) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: SceneGraphReducer::r_remove_column
+//       Access: Private
+//  Description: The recursive implementation of remove_column().
+////////////////////////////////////////////////////////////////////
+int SceneGraphReducer::
+r_remove_column(PandaNode *node, const InternalName *column,
+                GeomTransformer &transformer) {
+  int num_changed = 0;
+
+  if (node->is_geom_node()) {
+    // When we come to a geom node, collect.
+    if (transformer.remove_column(DCAST(GeomNode, node), column)) {
+      ++num_changed;
+    }
+  }
+    
+  PandaNode::Children children = node->get_children();
+  int num_children = children.get_num_children();
+  for (int i = 0; i < num_children; ++i) {
+    num_changed +=
+      r_remove_column(children.get_child(i), column, transformer);
+  }
+
+  return num_changed;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: SceneGraphReducer::r_collect_vertex_data
 //       Access: Private
@@ -702,7 +743,7 @@ r_collect_vertex_data(PandaNode *node, int collect_bits,
     GeomTransformer new_transformer(transformer);
 
     if (node->is_geom_node()) {
-      // When we come to geom node, collect.
+      // When we come to a geom node, collect.
       if (new_transformer.collect_vertex_data(DCAST(GeomNode, node), collect_bits)) {
         ++num_created;
       }

+ 6 - 0
panda/src/pgraph/sceneGraphReducer.h

@@ -135,6 +135,8 @@ PUBLISHED:
 
   int flatten(PandaNode *root, int combine_siblings_bits);
 
+  int remove_column(PandaNode *root, const InternalName *column);
+
   INLINE int collect_vertex_data(PandaNode *root, int collect_bits = ~0);
   INLINE int make_nonindexed(PandaNode *root, int nonindexed_bits = ~0);
   void unify(PandaNode *root);
@@ -166,6 +168,9 @@ protected:
   void choose_name(PandaNode *preserve, PandaNode *source1, 
                    PandaNode *source2);
 
+  int r_remove_column(PandaNode *node, const InternalName *column,
+                      GeomTransformer &transformer);
+
   int r_collect_vertex_data(PandaNode *node, int collect_bits,
                             GeomTransformer &transformer);
   int r_make_nonindexed(PandaNode *node, int collect_bits);
@@ -180,6 +185,7 @@ private:
 
   static PStatCollector _flatten_collector;
   static PStatCollector _apply_collector;
+  static PStatCollector _remove_column_collector;
   static PStatCollector _collect_collector;
   static PStatCollector _make_nonindexed_collector;
   static PStatCollector _unify_collector;