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

support NT_float64 as a vertex numeric type

David Rose преди 14 години
родител
ревизия
72f97c2107

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

@@ -56,6 +56,16 @@ ConfigVariableDouble egg_flatten_radius
           "the user to specify what should be considered \"small\".  Set "
           "it to 0.0 to disable this feature."));
 
+ConfigVariableBool egg_float64_vertices
+("egg-float64-vertices", false,
+ PRC_DESC("When this is true, the egg loader will store the vertices "
+          "for all geometry in a 64-bit double-precision float, instead "
+          "of the standard 32-bit single-precision float.  You almost never "
+          "want to set this true, since current hardware does not support "
+          "double-precision vertices, and setting this will just require the "
+          "driver to downsample the vertices at load time, making everything "
+          "slower."));
+
 ConfigVariableBool egg_unify
 ("egg-unify", true,
  PRC_DESC("When this is true, then in addition to flattening the scene graph "

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

@@ -37,8 +37,9 @@ extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_filters;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_clamp;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_decals;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_flatten;
-extern EXPCL_PANDAEGG ConfigVariableBool egg_unify;
 extern EXPCL_PANDAEGG ConfigVariableDouble egg_flatten_radius;
+extern EXPCL_PANDAEGG ConfigVariableBool egg_float64_vertices;
+extern EXPCL_PANDAEGG ConfigVariableBool egg_unify;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_combine_geoms;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_rigid_geometry;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_flat_shading;

+ 23 - 18
panda/src/egg2pg/eggLoader.cxx

@@ -622,8 +622,8 @@ show_normals(EggVertexPool *vertex_pool, GeomNode *geom_node) {
     LPoint3d pos = vert->get_pos3();
 
     if (vert->has_normal()) {
-      vertex.add_data3f(LCAST(float, pos));
-      vertex.add_data3f(LCAST(float, pos + vert->get_normal() * egg_normal_scale));
+      vertex.add_data3d(pos);
+      vertex.add_data3d(pos + vert->get_normal() * egg_normal_scale);
       color.add_data4f(1.0f, 0.0f, 0.0f, 1.0f);
       color.add_data4f(1.0f, 0.0f, 0.0f, 1.0f);
       primitive->add_next_vertices(2);
@@ -636,16 +636,16 @@ show_normals(EggVertexPool *vertex_pool, GeomNode *geom_node) {
     for (uvi = vert->uv_begin(); uvi != vert->uv_end(); ++uvi) {
       EggVertexUV *uv_obj = (*uvi);
       if (uv_obj->has_tangent()) {
-        vertex.add_data3f(LCAST(float, pos));
-        vertex.add_data3f(LCAST(float, pos + uv_obj->get_tangent() * egg_normal_scale));
+        vertex.add_data3d(pos);
+        vertex.add_data3d(pos + uv_obj->get_tangent() * egg_normal_scale);
         color.add_data4f(0.0f, 1.0f, 0.0f, 1.0f);
         color.add_data4f(0.0f, 1.0f, 0.0f, 1.0f);
         primitive->add_next_vertices(2);
         primitive->close_primitive();
       }
       if (uv_obj->has_binormal()) {
-        vertex.add_data3f(LCAST(float, pos));
-        vertex.add_data3f(LCAST(float, pos + uv_obj->get_binormal() * egg_normal_scale));
+        vertex.add_data3d(pos);
+        vertex.add_data3d(pos + uv_obj->get_binormal() * egg_normal_scale);
         color.add_data4f(0.0f, 0.0f, 1.0f, 1.0f);
         color.add_data4f(0.0f, 0.0f, 1.0f, 1.0f);
         primitive->add_next_vertices(2);
@@ -2199,10 +2199,15 @@ make_vertex_data(const EggRenderState *render_state,
   }
 
   // Decide on the format for the vertices.
+  Geom::NumericType vertex_numeric_type = Geom::NT_float32;
+  if (egg_float64_vertices) {
+    vertex_numeric_type = Geom::NT_float64;
+  }
+
   PT(GeomVertexArrayFormat) array_format = new GeomVertexArrayFormat;
   array_format->add_column
     (InternalName::get_vertex(), vertex_pool->get_num_dimensions(),
-     Geom::NT_float32, Geom::C_point);
+     vertex_numeric_type, Geom::C_point);
 
   if (vertex_pool->has_normals()) {
     array_format->add_column
@@ -2335,7 +2340,7 @@ make_vertex_data(const EggRenderState *render_state,
     GeomVertexFormat::register_format(temp_format);
 
   // Now create a new GeomVertexData using the indicated format.  It
-  // is actually correct to create it with UH_static even it
+  // is actually correct to create it with UH_static even though it
   // represents a dynamic object, because the vertex data itself won't
   // be changing--just the result of applying the animation is
   // dynamic.
@@ -2348,7 +2353,7 @@ make_vertex_data(const EggRenderState *render_state,
     vertex_data->set_slider_table(SliderTable::register_table(slider_table));
   }
 
-  // And fill the data from the vertex pool.
+  // And fill in the data from the vertex pool.
   EggVertexPool::const_iterator vi;
   for (vi = vertex_pool->begin(); vi != vertex_pool->end(); ++vi) {
     GeomVertexWriter gvw(vertex_data);
@@ -2356,7 +2361,7 @@ make_vertex_data(const EggRenderState *render_state,
     gvw.set_row(vertex->get_index());
 
     gvw.set_column(InternalName::get_vertex());
-    gvw.add_data4f(LCAST(float, vertex->get_pos4() * transform));
+    gvw.add_data4d(vertex->get_pos4() * transform);
 
     if (is_dynamic) {
       EggMorphVertexList::const_iterator mvi;
@@ -2365,7 +2370,7 @@ make_vertex_data(const EggRenderState *render_state,
         CPT(InternalName) delta_name = 
           InternalName::get_morph(InternalName::get_vertex(), morph.get_name());
         gvw.set_column(delta_name);
-        gvw.add_data3f(LCAST(float, morph.get_offset() * transform));
+        gvw.add_data3d(morph.get_offset() * transform);
       }
     }
 
@@ -2373,7 +2378,7 @@ make_vertex_data(const EggRenderState *render_state,
       gvw.set_column(InternalName::get_normal());
       Normald orig_normal = vertex->get_normal();
       Normald transformed_normal = normalize(orig_normal * transform);
-      gvw.add_data3f(LCAST(float, transformed_normal));
+      gvw.add_data3d(transformed_normal);
 
       if (is_dynamic) {
         EggMorphNormalList::const_iterator mni;
@@ -2385,7 +2390,7 @@ make_vertex_data(const EggRenderState *render_state,
           Normald morphed_normal = orig_normal + morph.get_offset();
           Normald transformed_morphed_normal = normalize(morphed_normal * transform);
           LVector3d delta = transformed_morphed_normal - transformed_normal;
-          gvw.add_data3f(LCAST(float, delta));
+          gvw.add_data3d(delta);
         }
       }
     }
@@ -2422,7 +2427,7 @@ make_vertex_data(const EggRenderState *render_state,
         uvw = uvw * (*buv).second->get_transform3d();
       }
 
-      gvw.set_data3f(LCAST(float, uvw));
+      gvw.set_data3d(uvw);
 
       if (is_dynamic) {
         EggMorphTexCoordList::const_iterator mti;
@@ -2437,7 +2442,7 @@ make_vertex_data(const EggRenderState *render_state,
             duvw = (new_uvw * (*buv).second->get_transform3d()) - uvw;
           }
           
-          gvw.add_data3f(LCAST(float, duvw));
+          gvw.add_data3d(duvw);
         }
       }
 
@@ -2448,9 +2453,9 @@ make_vertex_data(const EggRenderState *render_state,
         if (gvw.has_column()) {
           LVector3d tangent = egg_uv->get_tangent();
           LVector3d binormal = egg_uv->get_binormal();
-          gvw.add_data3f(LCAST(float, tangent));
+          gvw.add_data3d(tangent);
           gvw.set_column(InternalName::get_binormal_name(name));
-          gvw.add_data3f(LCAST(float, binormal));
+          gvw.add_data3d(binormal);
         }          
       }
     }
@@ -2751,7 +2756,7 @@ make_sphere(EggGroup *egg_group, EggGroup::CollideFlags flags,
         radius2 = max(radius2, v.length_squared());
       }
 
-      center = LCAST(float,d_center);
+      center = LCAST(float, d_center);
       radius = sqrtf(radius2);
 
       //egg2pg_cat.debug() << "make_sphere radius: " << radius << "\n";

+ 3 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -5736,6 +5736,9 @@ get_numeric_type(Geom::NumericType numeric_type) {
 
   case Geom::NT_float32:
     return GL_FLOAT;
+
+  case Geom::NT_float64:
+    return GL_DOUBLE;
   }
 
   GLCAT.error()

+ 3 - 0
panda/src/gobj/geomEnums.cxx

@@ -95,6 +95,9 @@ operator << (ostream &out, GeomEnums::NumericType numeric_type) {
     
   case GeomEnums::NT_float32:
     return out << "float32";
+    
+  case GeomEnums::NT_float64:
+    return out << "float64";
   }
 
   return out << "**invalid numeric type (" << (int)numeric_type << ")**";

+ 2 - 1
panda/src/gobj/geomEnums.h

@@ -181,7 +181,8 @@ PUBLISHED:
     NT_uint32,       // An integer 0..4294967296
     NT_packed_dcba,  // DirectX style, four byte values packed in a uint32
     NT_packed_dabc,  // DirectX packed color order (ARGB)
-    NT_float32,      // A floating-point number
+    NT_float32,      // A single-precision float
+    NT_float64,      // A double-precision float
   };
 
   // The contents determine the semantic meaning of a numeric value

Файловите разлики са ограничени, защото са твърде много
+ 817 - 111
panda/src/gobj/geomVertexColumn.cxx


+ 103 - 0
panda/src/gobj/geomVertexColumn.h

@@ -103,10 +103,17 @@ private:
   class Packer {
   public:
     virtual ~Packer();
+
     virtual float get_data1f(const unsigned char *pointer);
     virtual const LVecBase2f &get_data2f(const unsigned char *pointer);
     virtual const LVecBase3f &get_data3f(const unsigned char *pointer);
     virtual const LVecBase4f &get_data4f(const unsigned char *pointer);
+
+    virtual double get_data1d(const unsigned char *pointer);
+    virtual const LVecBase2d &get_data2d(const unsigned char *pointer);
+    virtual const LVecBase3d &get_data3d(const unsigned char *pointer);
+    virtual const LVecBase4d &get_data4d(const unsigned char *pointer);
+
     virtual int get_data1i(const unsigned char *pointer);
     virtual const int *get_data2i(const unsigned char *pointer);
     virtual const int *get_data3i(const unsigned char *pointer);
@@ -116,6 +123,11 @@ private:
     virtual void set_data2f(unsigned char *pointer, const LVecBase2f &data);
     virtual void set_data3f(unsigned char *pointer, const LVecBase3f &data);
     virtual void set_data4f(unsigned char *pointer, const LVecBase4f &data);
+
+    virtual void set_data1d(unsigned char *pointer, double data);
+    virtual void set_data2d(unsigned char *pointer, const LVecBase2d &data);
+    virtual void set_data3d(unsigned char *pointer, const LVecBase3d &data);
+    virtual void set_data4d(unsigned char *pointer, const LVecBase4d &data);
     
     virtual void set_data1i(unsigned char *pointer, int a);
     virtual void set_data2i(unsigned char *pointer, int a, int b);
@@ -142,6 +154,9 @@ private:
     LVecBase2f _v2;
     LVecBase3f _v3;
     LVecBase4f _v4;
+    LVecBase2d _v2d;
+    LVecBase3d _v3d;
+    LVecBase4d _v4d;
     int _i[4];
     unsigned int _a, _b, _c, _d;
   };
@@ -158,10 +173,18 @@ private:
     virtual const LVecBase2f &get_data2f(const unsigned char *pointer);
     virtual const LVecBase3f &get_data3f(const unsigned char *pointer);
     virtual const LVecBase4f &get_data4f(const unsigned char *pointer);
+    virtual double get_data1d(const unsigned char *pointer);
+    virtual const LVecBase2d &get_data2d(const unsigned char *pointer);
+    virtual const LVecBase3d &get_data3d(const unsigned char *pointer);
+    virtual const LVecBase4d &get_data4d(const unsigned char *pointer);
     virtual void set_data1f(unsigned char *pointer, float data);
     virtual void set_data2f(unsigned char *pointer, const LVecBase2f &data);
     virtual void set_data3f(unsigned char *pointer, const LVecBase3f &data);
     virtual void set_data4f(unsigned char *pointer, const LVecBase4f &data);
+    virtual void set_data1d(unsigned char *pointer, double data);
+    virtual void set_data2d(unsigned char *pointer, const LVecBase2d &data);
+    virtual void set_data3d(unsigned char *pointer, const LVecBase3d &data);
+    virtual void set_data4d(unsigned char *pointer, const LVecBase4d &data);
 
     virtual const char *get_name() const {
       return "Packer_point";
@@ -174,9 +197,13 @@ private:
   class Packer_color : public Packer {
   public:
     virtual const LVecBase4f &get_data4f(const unsigned char *pointer);
+    virtual const LVecBase4d &get_data4d(const unsigned char *pointer);
     virtual void set_data1f(unsigned char *pointer, float data);
     virtual void set_data2f(unsigned char *pointer, const LVecBase2f &data);
     virtual void set_data3f(unsigned char *pointer, const LVecBase3f &data);
+    virtual void set_data1d(unsigned char *pointer, double data);
+    virtual void set_data2d(unsigned char *pointer, const LVecBase2d &data);
+    virtual void set_data3d(unsigned char *pointer, const LVecBase3d &data);
 
     virtual const char *get_name() const {
       return "Packer_color";
@@ -263,6 +290,82 @@ private:
     }
   };
 
+  class Packer_float64_3 : public Packer {
+  public:
+    virtual const LVecBase3d &get_data3d(const unsigned char *pointer);
+    virtual void set_data3d(unsigned char *pointer, const LVecBase3d &value);
+
+    virtual const char *get_name() const {
+      return "Packer_float64_3";
+    }
+  };
+
+  class Packer_point_float64_2 : public Packer_point {
+  public:
+    virtual const LVecBase2d &get_data2d(const unsigned char *pointer);
+    virtual void set_data2d(unsigned char *pointer, const LVecBase2d &value);
+
+    virtual const char *get_name() const {
+      return "Packer_point_float64_2";
+    }
+  };
+
+  class Packer_point_float64_3 : public Packer_point {
+  public:
+    virtual const LVecBase3d &get_data3d(const unsigned char *pointer);
+    virtual void set_data3d(unsigned char *pointer, const LVecBase3d &value);
+
+    virtual const char *get_name() const {
+      return "Packer_point_float64_3";
+    }
+  };
+
+  class Packer_point_float64_4 : public Packer_point {
+  public:
+    virtual const LVecBase4d &get_data4d(const unsigned char *pointer);
+    virtual void set_data4d(unsigned char *pointer, const LVecBase4d &value);
+
+    virtual const char *get_name() const {
+      return "Packer_point_float64_4";
+    }
+  };
+
+  class Packer_nativedouble_3 : public Packer_float64_3 {
+  public:
+    virtual const LVecBase3d &get_data3d(const unsigned char *pointer);
+
+    virtual const char *get_name() const {
+      return "Packer_nativedouble_3";
+    }
+  };
+
+  class Packer_point_nativedouble_2 : public Packer_point_float64_2 {
+  public:
+    virtual const LVecBase2d &get_data2d(const unsigned char *pointer);
+
+    virtual const char *get_name() const {
+      return "Packer_nativedouble_2";
+    }
+  };
+
+  class Packer_point_nativedouble_3 : public Packer_point_float64_3 {
+  public:
+    virtual const LVecBase3d &get_data3d(const unsigned char *pointer);
+
+    virtual const char *get_name() const {
+      return "Packer_point_nativedouble_3";
+    }
+  };
+
+  class Packer_point_nativedouble_4 : public Packer_point_float64_4 {
+  public:
+    virtual const LVecBase4d &get_data4d(const unsigned char *pointer);
+
+    virtual const char *get_name() const {
+      return "Packer_point_nativedouble_4";
+    }
+  };
+
   class Packer_argb_packed : public Packer_color {
   public:
     virtual const LVecBase4f &get_data4f(const unsigned char *pointer);

+ 10 - 0
panda/src/gobj/geomVertexData.cxx

@@ -2262,6 +2262,16 @@ set_num_rows(int n) {
         pointer += stride;
       }
       break;
+
+    case NT_float64:
+      while (pointer < stop) {
+        PN_float64 *pi = (PN_float64 *)pointer;
+        for (int i = 0; i < num_values; i++) {
+          pi[i] = 1.0f;
+        }
+        pointer += stride;
+      }
+      break;
     }          
   }
 

+ 52 - 0
panda/src/gobj/geomVertexReader.I

@@ -499,6 +499,58 @@ get_data4f() {
   return _packer->get_data4f(inc_pointer());
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexReader::get_data1d
+//       Access: Published
+//  Description: Returns the data associated with the read row,
+//               expressed as a 1-component value, and advances the
+//               read row.
+////////////////////////////////////////////////////////////////////
+INLINE double GeomVertexReader::
+get_data1d() {
+  nassertr(has_column(), 0.0f);
+  return _packer->get_data1d(inc_pointer());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexReader::get_data2d
+//       Access: Published
+//  Description: Returns the data associated with the read row,
+//               expressed as a 2-component value, and advances the
+//               read row.
+////////////////////////////////////////////////////////////////////
+INLINE const LVecBase2d &GeomVertexReader::
+get_data2d() {
+  nassertr(has_column(), LVecBase2d::zero());
+  return _packer->get_data2d(inc_pointer());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexReader::get_data3d
+//       Access: Published
+//  Description: Returns the data associated with the read row,
+//               expressed as a 3-component value, and advances the
+//               read row.
+////////////////////////////////////////////////////////////////////
+INLINE const LVecBase3d &GeomVertexReader::
+get_data3d() {
+  nassertr(has_column(), LVecBase3d::zero());
+  return _packer->get_data3d(inc_pointer());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexReader::get_data4d
+//       Access: Published
+//  Description: Returns the data associated with the read row,
+//               expressed as a 4-component value, and advances the
+//               read row.
+////////////////////////////////////////////////////////////////////
+INLINE const LVecBase4d &GeomVertexReader::
+get_data4d() {
+  nassertr(has_column(), LVecBase4d::zero());
+  return _packer->get_data4d(inc_pointer());
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomVertexReader::get_data1i
 //       Access: Published

+ 5 - 0
panda/src/gobj/geomVertexReader.h

@@ -109,6 +109,11 @@ PUBLISHED:
   INLINE const LVecBase3f &get_data3f();
   INLINE const LVecBase4f &get_data4f();
 
+  INLINE double get_data1d();
+  INLINE const LVecBase2d &get_data2d();
+  INLINE const LVecBase3d &get_data3d();
+  INLINE const LVecBase4d &get_data4d();
+
   INLINE int get_data1i();
   INLINE const int *get_data2i();
   INLINE const int *get_data3i();

+ 204 - 0
panda/src/gobj/geomVertexWriter.I

@@ -511,6 +511,108 @@ set_data4f(const LVecBase4f &data) {
   _packer->set_data4f(inc_pointer(), data);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::set_data1d
+//       Access: Published
+//  Description: Sets the write row to a particular 1-component
+//               value, and advances the write row.
+//
+//               It is an error for the write row to advance past
+//               the end of data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+set_data1d(double data) {
+  nassertv(has_column());
+  _packer->set_data1d(inc_pointer(), data);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::set_data2d
+//       Access: Published
+//  Description: Sets the write row to a particular 2-component
+//               value, and advances the write row.
+//
+//               It is an error for the write row to advance past
+//               the end of data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+set_data2d(double x, double y) {
+  set_data2d(LVecBase2d(x, y));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::set_data2d
+//       Access: Published
+//  Description: Sets the write row to a particular 2-component
+//               value, and advances the write row.
+//
+//               It is an error for the write row to advance past
+//               the end of data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+set_data2d(const LVecBase2d &data) {
+  nassertv(has_column());
+  _packer->set_data2d(inc_pointer(), data);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::set_data3d
+//       Access: Published
+//  Description: Sets the write row to a particular 3-component
+//               value, and advances the write row.
+//
+//               It is an error for the write row to advance past
+//               the end of data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+set_data3d(double x, double y, double z) {
+  set_data3d(LVecBase3d(x, y, z));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::set_data3d
+//       Access: Published
+//  Description: Sets the write row to a particular 3-component
+//               value, and advances the write row.
+//
+//               It is an error for the write row to advance past
+//               the end of data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+set_data3d(const LVecBase3d &data) {
+  nassertv(has_column());
+  _packer->set_data3d(inc_pointer(), data);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::set_data4d
+//       Access: Published
+//  Description: Sets the write row to a particular 4-component
+//               value, and advances the write row.
+//
+//               It is an error for the write row to advance past
+//               the end of data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+set_data4d(double x, double y, double z, double w) {
+  set_data4d(LVecBase4d(x, y, z, w));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::set_data4d
+//       Access: Published
+//  Description: Sets the write row to a particular 4-component
+//               value, and advances the write row.
+//
+//               It is an error for the write row to advance past
+//               the end of data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+set_data4d(const LVecBase4d &data) {
+  nassertv(has_column());
+  _packer->set_data4d(inc_pointer(), data);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomVertexWriter::set_data1i
 //       Access: Published
@@ -715,6 +817,108 @@ add_data4f(const LVecBase4f &data) {
   _packer->set_data4f(inc_add_pointer(), data);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::add_data1d
+//       Access: Published
+//  Description: Sets the write row to a particular 1-component
+//               value, and advances the write row.
+//
+//               If the write row advances past the end of data,
+//               implicitly adds a new row to the data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+add_data1d(double data) {
+  nassertv(has_column());
+  _packer->set_data1d(inc_add_pointer(), data);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::add_data2d
+//       Access: Published
+//  Description: Sets the write row to a particular 2-component
+//               value, and advances the write row.
+//
+//               If the write row advances past the end of data,
+//               implicitly adds a new row to the data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+add_data2d(double x, double y) {
+  add_data2d(LVecBase2d(x, y));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::add_data2d
+//       Access: Published
+//  Description: Sets the write row to a particular 2-component
+//               value, and advances the write row.
+//
+//               If the write row advances past the end of data,
+//               implicitly adds a new row to the data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+add_data2d(const LVecBase2d &data) {
+  nassertv(has_column());
+  _packer->set_data2d(inc_add_pointer(), data);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::add_data3d
+//       Access: Published
+//  Description: Sets the write row to a particular 3-component
+//               value, and advances the write row.
+//
+//               If the write row advances past the end of data,
+//               implicitly adds a new row to the data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+add_data3d(double x, double y, double z) {
+  add_data3d(LVecBase3d(x, y, z));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::add_data3d
+//       Access: Published
+//  Description: Sets the write row to a particular 3-component
+//               value, and advances the write row.
+//
+//               If the write row advances past the end of data,
+//               implicitly adds a new row to the data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+add_data3d(const LVecBase3d &data) {
+  nassertv(has_column());
+  _packer->set_data3d(inc_add_pointer(), data);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::add_data4d
+//       Access: Published
+//  Description: Sets the write row to a particular 4-component
+//               value, and advances the write row.
+//
+//               If the write row advances past the end of data,
+//               implicitly adds a new row to the data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+add_data4d(double x, double y, double z, double w) {
+  add_data4d(LVecBase4d(x, y, z, w));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexWriter::add_data4d
+//       Access: Published
+//  Description: Sets the write row to a particular 4-component
+//               value, and advances the write row.
+//
+//               If the write row advances past the end of data,
+//               implicitly adds a new row to the data.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexWriter::
+add_data4d(const LVecBase4d &data) {
+  nassertv(has_column());
+  _packer->set_data4d(inc_add_pointer(), data);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomVertexWriter::add_data1i
 //       Access: Published

+ 16 - 0
panda/src/gobj/geomVertexWriter.h

@@ -122,6 +122,14 @@ PUBLISHED:
   INLINE void set_data4f(float x, float y, float z, float w);
   INLINE void set_data4f(const LVecBase4f &data);
 
+  INLINE void set_data1d(double data);
+  INLINE void set_data2d(double x, double y);
+  INLINE void set_data2d(const LVecBase2d &data);
+  INLINE void set_data3d(double x, double y, double z);
+  INLINE void set_data3d(const LVecBase3d &data);
+  INLINE void set_data4d(double x, double y, double z, double w);
+  INLINE void set_data4d(const LVecBase4d &data);
+
   INLINE void set_data1i(int data);
   INLINE void set_data2i(int a, int b);
   INLINE void set_data2i(const int data[2]);
@@ -138,6 +146,14 @@ PUBLISHED:
   INLINE void add_data4f(float x, float y, float z, float w);
   INLINE void add_data4f(const LVecBase4f &data);
 
+  INLINE void add_data1d(double data);
+  INLINE void add_data2d(double x, double y);
+  INLINE void add_data2d(const LVecBase2d &data);
+  INLINE void add_data3d(double x, double y, double z);
+  INLINE void add_data3d(const LVecBase3d &data);
+  INLINE void add_data4d(double x, double y, double z, double w);
+  INLINE void add_data4d(const LVecBase4d &data);
+
   INLINE void add_data1i(int data);
   INLINE void add_data2i(int a, int b);
   INLINE void add_data2i(const int data[2]);

Някои файлове не бяха показани, защото твърде много файлове са промени