Browse Source

GeomVertexFormat::maybe_align_columns_for_animation()

David Rose 14 years ago
parent
commit
95db6ebaca

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

@@ -184,21 +184,6 @@ ConfigVariableInt egg_vertex_max_num_joints
           "more than this number of joints, the joints with the lesser membership "
           "value are ignored.  Set this to -1 to allow any number of joints."));
 
-ConfigVariableBool egg_vertex_animation_align_16
-("egg-vertex-animation-align-16", 
-#ifdef LINMATH_ALIGN
- true,
-#else
- false,
-#endif
- PRC_DESC("If this is true, then animated vertices will be created with 4-component "
-          "floats and aligned to 16-byte boundaries, to allow efficient vectorization "
-          "(e.g. SSE2) operations when computing animations.  If this is false, "
-          "animated vertices will be packed as tightly as possible, in the normal way, "
-          "which will optimize the amount of memory that must be sent to the graphics "
-          "card, but prevent the use of SSE2 to calculate animation.  This does not "
-          "affect unanimated vertices, which are always packed tightly."));
-
 ConfigureFn(config_egg2pg) {
   init_libegg2pg();
 }

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

@@ -54,7 +54,6 @@ extern EXPCL_PANDAEGG ConfigVariableBool egg_emulate_bface;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_preload_simple_textures;
 extern EXPCL_PANDAEGG ConfigVariableDouble egg_vertex_membership_quantize;
 extern EXPCL_PANDAEGG ConfigVariableInt egg_vertex_max_num_joints;
-extern EXPCL_PANDAEGG ConfigVariableBool egg_vertex_animation_align_16;
 
 extern EXPCL_PANDAEGG void init_libegg2pg();
 

+ 12 - 38
panda/src/egg2pg/eggLoader.cxx

@@ -2212,37 +2212,16 @@ make_vertex_data(const EggRenderState *render_state,
   if (di != _vertex_pool_data.end()) {
     return (*di).second;
   }
-
-  bool align_16 = false;
-  if (is_dynamic) {
-    align_16 = egg_vertex_animation_align_16;
-  }
   
   PT(GeomVertexArrayFormat) array_format = new GeomVertexArrayFormat;
-  if (align_16) {
-    // Enforce a 4-component float and a 16-byte alignment.
-    array_format->add_column
-      (InternalName::get_vertex(), 4,
-       Geom::NT_stdfloat, Geom::C_point, -1, 16);
-  } else {
-    // Allow a tightly-packed 3-component float.
-    array_format->add_column
-      (InternalName::get_vertex(), vertex_pool->get_num_dimensions(),
-       Geom::NT_stdfloat, Geom::C_point);
-  }
+  array_format->add_column
+    (InternalName::get_vertex(), vertex_pool->get_num_dimensions(),
+     Geom::NT_stdfloat, Geom::C_point);
 
   if (vertex_pool->has_normals()) {
-    if (align_16) {
-      // Enforce a 4-component float and a 16-byte alignment.
-      array_format->add_column
-        (InternalName::get_normal(), 4,
-         Geom::NT_stdfloat, Geom::C_vector, -1, 16);
-    } else {
-      // Allow a tightly-packed 3-component float.
-      array_format->add_column
-        (InternalName::get_normal(), 3,
-         Geom::NT_stdfloat, Geom::C_vector);
-    }
+    array_format->add_column
+      (InternalName::get_normal(), 3,
+       Geom::NT_stdfloat, Geom::C_vector);
   }
 
   if (!ignore_color) {
@@ -2274,17 +2253,10 @@ make_vertex_data(const EggRenderState *render_state,
     PT(InternalName) iname_t = InternalName::get_tangent_name(name);
     PT(InternalName) iname_b = InternalName::get_binormal_name(name);
 
-    if (align_16) {
-      array_format->add_column
-        (iname_t, 4, Geom::NT_stdfloat, Geom::C_vector, -1, 16);
-      array_format->add_column
-        (iname_b, 4, Geom::NT_stdfloat, Geom::C_vector, -1, 16);
-    } else {
-      array_format->add_column
-        (iname_t, 3, Geom::NT_stdfloat, Geom::C_vector);
-      array_format->add_column
-        (iname_b, 3, Geom::NT_stdfloat, Geom::C_vector);
-    }
+    array_format->add_column
+      (iname_t, 3, Geom::NT_stdfloat, Geom::C_vector);
+    array_format->add_column
+      (iname_b, 3, Geom::NT_stdfloat, Geom::C_vector);
   }
 
   vector_string aux_names;
@@ -2379,6 +2351,8 @@ make_vertex_data(const EggRenderState *render_state,
     name = character_maker->get_name();
   }
 
+  temp_format->maybe_align_columns_for_animation();
+
   CPT(GeomVertexFormat) format =
     GeomVertexFormat::register_format(temp_format);
 

+ 19 - 2
panda/src/gobj/config_gobj.cxx

@@ -282,8 +282,25 @@ ConfigVariableInt vertex_column_alignment
           "GeomVertexFormat.  Setting this value globally could result in "
           "much needless wasted space in all vertex data objects, but it "
           "could be useful for simple experiments.  Also see "
-          "egg-vertex-animation-align-16 for a variable that controls "
-          "this alignment for the vertex-animation columns only."));
+          "vertex-animation-align-16 for a variable that controls "
+          "this alignment for the vertex animation columns only."));
+
+ConfigVariableBool vertex_animation_align_16
+("vertex-animation-align-16", 
+#ifdef LINMATH_ALIGN
+ true,
+#else
+ false,
+#endif
+ PRC_DESC("If this is true, then animated vertices will be created with 4-component "
+          "floats and aligned to 16-byte boundaries, to allow efficient vectorization "
+          "(e.g. SSE2) operations when computing animations.  If this is false, "
+          "animated vertices will be packed as tightly as possible, in the normal way, "
+          "which will optimize the amount of memory that must be sent to the graphics "
+          "card, but prevent the use of SSE2 to calculate animation.  This does not "
+          "affect unanimated vertices, which are always packed tightly.  This also "
+          "impacts only vertex formats created within Panda subsystems; custom "
+          "vertex formats are not affected."));
 
 ConfigVariableEnum<AutoTextureScale> textures_power_2
 ("textures-power-2", ATS_down,

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

@@ -65,6 +65,7 @@ extern EXPCL_PANDA_GOBJ ConfigVariableBool dump_generated_shaders;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool enforce_attrib_lock;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool vertices_float64;
 extern EXPCL_PANDA_GOBJ ConfigVariableInt vertex_column_alignment;
+extern EXPCL_PANDA_GOBJ ConfigVariableBool vertex_animation_align_16;
 
 extern EXPCL_PANDA_GOBJ ConfigVariableEnum<AutoTextureScale> textures_power_2;
 extern EXPCL_PANDA_GOBJ ConfigVariableEnum<AutoTextureScale> textures_square;

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

@@ -364,6 +364,41 @@ pack_columns() {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexArrayFormat::align_columns_for_animation
+//       Access: Published
+//  Description: Reprocesses the columns in the format to align the
+//               C_point and C_vector columns to 16-byte boundaries to
+//               allow for the more efficient SSE2 operations
+//               (assuming SSE2 is enabled in the build).
+//
+//               The caller is responsible for testing
+//               vertex_animation_align_16 to decide whether to call
+//               this method.
+////////////////////////////////////////////////////////////////////
+void GeomVertexArrayFormat::
+align_columns_for_animation() {
+  nassertv(!_is_registered);
+
+  Columns orig_columns;
+  orig_columns.swap(_columns);
+  clear_columns();
+
+  Columns::const_iterator ci;
+  for (ci = orig_columns.begin(); ci != orig_columns.end(); ++ci) {
+    GeomVertexColumn *column = (*ci);
+    if ((column->get_contents() == C_point || column->get_contents() == C_vector) &&
+        (column->get_numeric_type() == NT_float32 || column->get_numeric_type() == NT_float64) &&
+        column->get_num_components() >= 3) {
+      add_column(column->get_name(), 4, column->get_numeric_type(), column->get_contents(), -1, 16);
+    } else {
+      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

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

+ 36 - 1
panda/src/gobj/geomVertexFormat.cxx

@@ -566,6 +566,41 @@ pack_columns() {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexFormat::align_columns_for_animation
+//       Access: Published
+//  Description: Reprocesses the columns in the format to align the
+//               C_point and C_vector columns to 16-byte boundaries to
+//               allow for the more efficient SSE2 operations
+//               (assuming SSE2 is enabled in the build).
+//
+//               Also see maybe_align_columns_for_animation().
+////////////////////////////////////////////////////////////////////
+void GeomVertexFormat::
+align_columns_for_animation() {
+  nassertv(!_is_registered);
+  Arrays::iterator ai;
+  for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
+    if ((*ai)->is_registered()) {
+      (*ai) = new GeomVertexArrayFormat(*(*ai));
+    }
+    (*ai)->align_columns_for_animation();
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexFormat::maybe_align_columns_for_animation
+//       Access: Published
+//  Description: Calls align_columns_for_animation() if this format's
+//               AnimationSpec indicates that it contains animated
+//               vertices, and if vertex-animation-align-16 is true.
+////////////////////////////////////////////////////////////////////
+void GeomVertexFormat::
+maybe_align_columns_for_animation() {
+  if (_animation.get_animation_type() == AT_panda && vertex_animation_align_16) {
+    align_columns_for_animation();
+  }
+}
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomVertexFormat::output
@@ -608,7 +643,7 @@ write(ostream &out, int indent_level) const {
 
   if (_animation.get_animation_type() != AT_none) {
     indent(out, indent_level)
-      << "anim " << _animation;
+      << "anim " << _animation << "\n";
   }
 }
 

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

@@ -100,6 +100,8 @@ PUBLISHED:
 
   void remove_column(const InternalName *name);
   void pack_columns();
+  void align_columns_for_animation();
+  void maybe_align_columns_for_animation();
 
   INLINE int get_num_points() const;
   INLINE const InternalName *get_point(int n) const;

+ 1 - 0
panda/src/grutil/rigidBodyCombiner.cxx

@@ -252,6 +252,7 @@ convert_vd(const VertexTransform *transform, const GeomVertexData *orig) {
   GeomVertexAnimationSpec spec;
   spec.set_panda();
   format->set_animation(spec);
+  format->maybe_align_columns_for_animation();
 
   CPT(GeomVertexFormat) new_format = GeomVertexFormat::register_format(format);
   CPT(GeomVertexData) converted = orig->convert_to(new_format);

+ 1 - 19
panda/src/pgraph/geomTransformer.cxx

@@ -131,25 +131,7 @@ transform_vertices(Geom *geom, const LMatrix4 &mat) {
   if (new_data._vdata.is_null()) {
     // We have not yet converted these vertices.  Do so now.
     PT(GeomVertexData) new_vdata = new GeomVertexData(*sv._vertex_data);
-    CPT(GeomVertexFormat) format = new_vdata->get_format();
-    
-    int ci;
-    for (ci = 0; ci < format->get_num_points(); ci++) {
-      GeomVertexRewriter data(new_vdata, format->get_point(ci));
-      
-      while (!data.is_at_end()) {
-        const LPoint3 &point = data.get_data3();
-        data.set_data3(point * mat);
-      }
-    }
-    for (ci = 0; ci < format->get_num_vectors(); ci++) {
-      GeomVertexRewriter data(new_vdata, format->get_vector(ci));
-      
-      while (!data.is_at_end()) {
-        const LVector3 &vector = data.get_data3();
-        data.set_data3(normalize(vector * mat));
-      }
-    }
+    new_vdata->transform_vertices(mat);
     new_data._vdata = new_vdata;
   }