Browse Source

split out EggBase and EggSingleBase

David Rose 22 years ago
parent
commit
4bf8b08394

+ 8 - 8
pandatool/src/egg-mkfont/eggMakeFont.cxx

@@ -21,13 +21,13 @@
 #include "charPlacement.h"
 #include "pkFontFile.h"
 
-#include <string_utils.h>
-#include <eggGroup.h>
-#include <eggTexture.h>
-#include <eggVertexPool.h>
-#include <eggPolygon.h>
-#include <eggPoint.h>
-#include <pointerTo.h>
+#include "string_utils.h"
+#include "eggGroup.h"
+#include "eggTexture.h"
+#include "eggVertexPool.h"
+#include "eggPolygon.h"
+#include "eggPoint.h"
+#include "pointerTo.h"
 
 #include <math.h>
 
@@ -220,7 +220,7 @@ handle_args(ProgramBase::Args &args) {
 ////////////////////////////////////////////////////////////////////
 bool EggMakeFont::
 dispatch_dimensions(ProgramBase *self, const string &opt, const string &arg, void *) {
-  EggBase *base = (EggBase *)self;
+  EggSingleBase *base = (EggSingleBase *)self;
   EggMakeFont *me = (EggMakeFont *)base->as_writer();
   return me->ns_dispatch_dimensions(opt, arg);
 }

+ 4 - 4
pandatool/src/egg-mkfont/eggMakeFont.h

@@ -19,13 +19,13 @@
 #ifndef EGGMAKEFONT_H
 #define EGGMAKEFONT_H
 
-#include <pandatoolbase.h>
+#include "pandatoolbase.h"
 
 #include "charLayout.h"
 
-#include <eggWriter.h>
-#include <luse.h>
-#include <pnmImage.h>
+#include "eggWriter.h"
+#include "luse.h"
+#include "pnmImage.h"
 
 class CharPlacement;
 class CharBitmap;

+ 2 - 0
pandatool/src/egg-optchar/eggOptchar.cxx

@@ -37,6 +37,8 @@ EggOptchar::
 EggOptchar() {
   add_path_replace_options();
   add_path_store_options();
+  add_normals_options();
+  add_transform_options();
 
   set_program_description
     ("egg-optchar performs basic optimizations of a character model "

+ 5 - 3
pandatool/src/eggbase/Sources.pp

@@ -9,18 +9,20 @@
 
   #define SOURCES \
      eggBase.h eggConverter.h eggFilter.h eggMultiBase.h \
-     eggMultiFilter.h eggReader.h eggToSomething.h eggWriter.h \
+     eggMultiFilter.h eggReader.h eggSingleBase.h \
+     eggToSomething.h eggWriter.h \
      somethingToEgg.h 
     
   #define INCLUDED_SOURCES \
      eggBase.cxx eggConverter.cxx eggFilter.cxx eggMultiBase.cxx \
-     eggMultiFilter.cxx eggReader.cxx eggToSomething.cxx \
+     eggMultiFilter.cxx eggReader.cxx eggSingleBase.cxx \
+     eggToSomething.cxx \
      eggWriter.cxx somethingToEgg.cxx 
 
   #define INSTALL_HEADERS \
     eggBase.h eggConverter.h eggFilter.h \
     eggMultiBase.h eggMultiFilter.h \
-    eggReader.h eggToSomething.h eggWriter.h somethingToEgg.h
+    eggReader.h eggSingleBase.h eggToSomething.h eggWriter.h somethingToEgg.h
 
 #end ss_lib_target
 

+ 284 - 43
pandatool/src/eggbase/eggBase.cxx

@@ -23,6 +23,7 @@
 #include "eggFilenameNode.h"
 #include "eggComment.h"
 #include "dcast.h"
+#include "string_utils.h"
 
 ////////////////////////////////////////////////////////////////////
 //     Function: EggBase::Constructor
@@ -39,40 +40,86 @@ EggBase() {
      &_got_coordinate_system, &_coordinate_system);
 
   _coordinate_system = CS_yup_right;
+
+  _normals_mode = NM_preserve;
+  _normals_threshold = 0.0;
+
+  _got_transform = false;
+  _transform = LMatrix4d::ident_mat();
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: EggBase::as_reader
-//       Access: Public, Virtual
-//  Description: Returns this object as an EggReader pointer, if it is
-//               in fact an EggReader, or NULL if it is not.
-//
-//               This is intended to work around the C++ limitation
-//               that prevents downcasts past virtual inheritance.
-//               Since both EggReader and EggWriter inherit virtually
-//               from EggBase, we need functions like this to downcast
-//               to the appropriate pointer.
-////////////////////////////////////////////////////////////////////
-EggReader *EggBase::
-as_reader() {
-  return (EggReader *)NULL;
+//     Function: EggBase::add_normals_options
+//       Access: Public
+//  Description: Adds -no, -np, etc. as valid options for this
+//               program.  If the user specifies one of the options on
+//               the command line, the normals will be adjusted when
+//               the egg file is written out.
+////////////////////////////////////////////////////////////////////
+void EggBase::
+add_normals_options() {
+  static NormalsMode strip = NM_strip;
+  static NormalsMode polygon = NM_polygon;
+  static NormalsMode vertex = NM_vertex;
+  static NormalsMode preserve = NM_preserve;
+
+  add_option
+    ("no", "", 48,
+     "Strip all normals.",
+     &EggBase::dispatch_normals, NULL, &strip);
+
+  add_option
+    ("np", "", 48,
+     "Strip existing normals and redefine polygon normals.",
+     &EggBase::dispatch_normals, NULL, &polygon);
+
+  add_option
+    ("nv", "threshold", 48,
+     "Strip existing normals and redefine vertex normals.  Consider an edge "
+     "between adjacent polygons to be smooth if the angle between them "
+     "is less than threshold degrees.",
+     &EggBase::dispatch_normals, NULL, &vertex);
+
+  add_option
+    ("nn", "", 48,
+     "Preserve normals exactly as they are.  This is the default.",
+     &EggBase::dispatch_normals, NULL, &preserve);
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: EggBase::as_writer
-//       Access: Public, Virtual
-//  Description: Returns this object as an EggWriter pointer, if it is
-//               in fact an EggWriter, or NULL if it is not.
-//
-//               This is intended to work around the C++ limitation
-//               that prevents downcasts past virtual inheritance.
-//               Since both EggReader and EggWriter inherit virtually
-//               from EggBase, we need functions like this to downcast
-//               to the appropriate pointer.
-////////////////////////////////////////////////////////////////////
-EggWriter *EggBase::
-as_writer() {
-  return (EggWriter *)NULL;
+//     Function: EggBase::add_transform_options
+//       Access: Public
+//  Description: Adds -TS, -TT, etc. as valid options for this
+//               program.  If the user specifies one of the options on
+//               the command line, the data will be transformed when
+//               the egg file is written out.
+////////////////////////////////////////////////////////////////////
+void EggBase::
+add_transform_options() {
+  add_option
+    ("TS", "sx[,sy,sz]", 49,
+     "Scale the model uniformly by the given factor (if only one number "
+     "is given) or in each axis by sx, sy, sz (if three numbers are given).",
+     &EggBase::dispatch_scale, &_got_transform, &_transform);
+
+  add_option
+    ("TR", "x,y,z", 49,
+     "Rotate the model x degrees about the x axis, then y degrees about the "
+     "y axis, and then z degrees about the z axis.",
+     &EggBase::dispatch_rotate_xyz, &_got_transform, &_transform);
+
+  add_option
+    ("TA", "angle,x,y,z", 49,
+     "Rotate the model angle degrees counterclockwise about the given "
+     "axis.",
+     &EggBase::dispatch_rotate_axis, &_got_transform, &_transform);
+
+  add_option
+    ("TT", "x,y,z", 49,
+     "Translate the model by the indicated amount.\n\n"
+     "All transformation options (-TS, -TR, -TA, -TT) are cumulative and are "
+     "applied in the order they are encountered on the command line.",
+     &EggBase::dispatch_translate, &_got_transform, &_transform);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -116,21 +163,6 @@ convert_paths(EggNode *node, PathReplace *path_replace,
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: EggBase::post_command_line
-//       Access: Protected, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-bool EggBase::
-post_command_line() {
-  if (_got_coordinate_system) {
-    _data.set_coordinate_system(_coordinate_system);
-  }
-
-  return ProgramBase::post_command_line();
-}
-
-
 ////////////////////////////////////////////////////////////////////
 //     Function: EggBase::append_command_comment
 //       Access: Protected
@@ -162,3 +194,212 @@ void EggBase::
 append_command_comment(EggData &data, const string &comment) {
   data.insert(data.begin(), new EggComment("", comment));
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggBase::dispatch_normals
+//       Access: Protected, Static
+//  Description: Accepts one of -no, -np, etc. and sets _normals_mode
+//               as indicated.  The void * argument is a pointer to a
+//               NormalsMode variable that indicates which switch was
+//               passed.
+////////////////////////////////////////////////////////////////////
+bool EggBase::
+dispatch_normals(ProgramBase *self, const string &opt, const string &arg, void *mode) {
+  EggBase *base = (EggBase *)self;
+  return base->ns_dispatch_normals(opt, arg, mode);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggBase::ns_dispatch_normals
+//       Access: Protected
+//  Description: Accepts one of -no, -np, etc. and sets _normals_mode
+//               as indicated.  The void * argument is a pointer to a
+//               NormalsMode variable that indicates which switch was
+//               passed.
+////////////////////////////////////////////////////////////////////
+bool EggBase::
+ns_dispatch_normals(const string &opt, const string &arg, void *mode) {
+  _normals_mode = *(NormalsMode *)mode;
+
+  if (_normals_mode == NM_vertex) {
+    if (!string_to_double(arg, _normals_threshold)) {
+      nout << "Invalid numeric parameter for -" << opt << ": "
+           << arg << "\n";
+      return false;
+    }
+  }
+
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggBase::dispatch_scale
+//       Access: Protected, Static
+//  Description: Handles -TS, which specifies a scale transform.  Var
+//               is an LMatrix4d.
+////////////////////////////////////////////////////////////////////
+bool EggBase::
+dispatch_scale(const string &opt, const string &arg, void *var) {
+  LMatrix4d *transform = (LMatrix4d *)var;
+
+  vector_string words;
+  tokenize(arg, words, ",");
+
+  double sx, sy, sz;
+
+  bool okflag = false;
+  if (words.size() == 3) {
+    okflag =
+      string_to_double(words[0], sx) &&
+      string_to_double(words[1], sy) &&
+      string_to_double(words[2], sz);
+
+  } else if (words.size() == 1) {
+    okflag =
+      string_to_double(words[0], sx);
+    sy = sz = sx;
+  }
+
+  if (!okflag) {
+    nout << "-" << opt
+         << " requires one or three numbers separated by commas.\n";
+    return false;
+  }
+
+  *transform = (*transform) * LMatrix4d::scale_mat(sx, sy, sz);
+
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggBase::dispatch_rotate_xyz
+//       Access: Protected, Static
+//  Description: Handles -TR, which specifies a rotate transform about
+//               the three cardinal axes.  Var is an LMatrix4d.
+////////////////////////////////////////////////////////////////////
+bool EggBase::
+dispatch_rotate_xyz(ProgramBase *self, const string &opt, const string &arg, void *var) {
+  EggBase *base = (EggBase *)self;
+  return base->ns_dispatch_rotate_xyz(opt, arg, var);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggBase::ns_dispatch_rotate_xyz
+//       Access: Protected
+//  Description: Handles -TR, which specifies a rotate transform about
+//               the three cardinal axes.  Var is an LMatrix4d.
+////////////////////////////////////////////////////////////////////
+bool EggBase::
+ns_dispatch_rotate_xyz(const string &opt, const string &arg, void *var) {
+  LMatrix4d *transform = (LMatrix4d *)var;
+
+  vector_string words;
+  tokenize(arg, words, ",");
+
+  LVecBase3d xyz;
+
+  bool okflag = false;
+  if (words.size() == 3) {
+    okflag =
+      string_to_double(words[0], xyz[0]) &&
+      string_to_double(words[1], xyz[1]) &&
+      string_to_double(words[2], xyz[2]);
+  }
+
+  if (!okflag) {
+    nout << "-" << opt
+         << " requires three numbers separated by commas.\n";
+    return false;
+  }
+
+  LMatrix4d mat =
+    LMatrix4d::rotate_mat(xyz[0], LVector3d(1.0, 0.0, 0.0), _coordinate_system) *
+    LMatrix4d::rotate_mat(xyz[1], LVector3d(0.0, 1.0, 0.0), _coordinate_system) *
+    LMatrix4d::rotate_mat(xyz[2], LVector3d(0.0, 0.0, 1.0), _coordinate_system);
+
+  *transform = (*transform) * mat;
+
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggBase::dispatch_rotate_axis
+//       Access: Protected, Static
+//  Description: Handles -TA, which specifies a rotate transform about
+//               an arbitrary axis.  Var is an LMatrix4d.
+////////////////////////////////////////////////////////////////////
+bool EggBase::
+dispatch_rotate_axis(ProgramBase *self, const string &opt, const string &arg, void *var) {
+  EggBase *base = (EggBase *)self;
+  return base->ns_dispatch_rotate_axis(opt, arg, var);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggBase::ns_dispatch_rotate_axis
+//       Access: Protected
+//  Description: Handles -TA, which specifies a rotate transform about
+//               an arbitrary axis.  Var is an LMatrix4d.
+////////////////////////////////////////////////////////////////////
+bool EggBase::
+ns_dispatch_rotate_axis(const string &opt, const string &arg, void *var) {
+  LMatrix4d *transform = (LMatrix4d *)var;
+
+  vector_string words;
+  tokenize(arg, words, ",");
+
+  double angle;
+  LVecBase3d axis;
+
+  bool okflag = false;
+  if (words.size() == 4) {
+    okflag =
+      string_to_double(words[0], angle) &&
+      string_to_double(words[1], axis[0]) &&
+      string_to_double(words[2], axis[1]) &&
+      string_to_double(words[3], axis[2]);
+  }
+
+  if (!okflag) {
+    nout << "-" << opt
+         << " requires four numbers separated by commas.\n";
+    return false;
+  }
+
+  *transform = (*transform) * LMatrix4d::rotate_mat(angle, axis, _coordinate_system);
+
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggBase::dispatch_translate
+//       Access: Protected, Static
+//  Description: Handles -TT, which specifies a translate transform.
+//               Var is an LMatrix4d.
+////////////////////////////////////////////////////////////////////
+bool EggBase::
+dispatch_translate(const string &opt, const string &arg, void *var) {
+  LMatrix4d *transform = (LMatrix4d *)var;
+
+  vector_string words;
+  tokenize(arg, words, ",");
+
+  LVector3d trans;
+
+  bool okflag = false;
+  if (words.size() == 3) {
+    okflag =
+      string_to_double(words[0], trans[0]) &&
+      string_to_double(words[1], trans[1]) &&
+      string_to_double(words[2], trans[2]);
+  }
+
+  if (!okflag) {
+    nout << "-" << opt
+         << " requires three numbers separated by commas.\n";
+    return false;
+  }
+
+  *transform = (*transform) * LMatrix4d::translate_mat(trans);
+
+  return true;
+}

+ 27 - 14
pandatool/src/eggbase/eggBase.h

@@ -22,20 +22,13 @@
 #include "pandatoolbase.h"
 
 #include "programBase.h"
-#include "coordinateSystem.h"
 #include "eggData.h"
 
-class EggReader;
-class EggWriter;
-class EggNode;
-class PathReplace;
-
 ////////////////////////////////////////////////////////////////////
 //       Class : EggBase
-// Description : This specialization of ProgramBase is intended for
-//               programs that read and/or write a single egg file.
-//               (See EggMultiBase for programs that operate on
-//               multiple egg files at once.)
+// Description : This is a base class for both EggSingleBase and
+//               EggMultiBase.  Don't inherit directly from this; use
+//               one of those two classes instead.
 //
 //               This is just a base class; see EggReader, EggWriter,
 //               or EggFilter according to your particular I/O needs.
@@ -44,21 +37,41 @@ class EggBase : public ProgramBase {
 public:
   EggBase();
 
-  virtual EggReader *as_reader();
-  virtual EggWriter *as_writer();
+  void add_normals_options();
+  void add_transform_options();
 
   static void convert_paths(EggNode *node, PathReplace *path_replace,
                             const DSearchPath &additional_path);
 
 protected:
-  virtual bool post_command_line();
   void append_command_comment(EggData &_data);
   static void append_command_comment(EggData &_data, const string &comment);
 
+  static bool dispatch_normals(ProgramBase *self, const string &opt, const string &arg, void *mode);
+  bool ns_dispatch_normals(const string &opt, const string &arg, void *mode);
+
+  static bool dispatch_scale(const string &opt, const string &arg, void *var);
+  static bool dispatch_rotate_xyz(ProgramBase *self, const string &opt, const string &arg, void *var);
+  bool ns_dispatch_rotate_xyz(const string &opt, const string &arg, void *var);
+  static bool dispatch_rotate_axis(ProgramBase *self, const string &opt, const string &arg, void *var);
+  bool ns_dispatch_rotate_axis(const string &opt, const string &arg, void *var);
+  static bool dispatch_translate(const string &opt, const string &arg, void *var);
+
 protected:
+  enum NormalsMode {
+    NM_strip,
+    NM_polygon,
+    NM_vertex,
+    NM_preserve
+  };
+  NormalsMode _normals_mode;
+  double _normals_threshold;
+
+  bool _got_transform;
+  LMatrix4d _transform;
+
   bool _got_coordinate_system;
   CoordinateSystem _coordinate_system;
-  EggData _data;
 };
 
 #endif

+ 59 - 35
pandatool/src/eggbase/eggMultiBase.cxx

@@ -30,55 +30,79 @@
 ////////////////////////////////////////////////////////////////////
 EggMultiBase::
 EggMultiBase() {
-  add_option
-    ("cs", "coordinate-system", 80,
-     "Specify the coordinate system to operate in.  This may be one of "
-     "'y-up', 'z-up', 'y-up-left', or 'z-up-left'.",
-     &EggMultiBase::dispatch_coordinate_system,
-     &_got_coordinate_system, &_coordinate_system);
-
   add_option
     ("f", "", 80,
      "Force complete loading: load up the egg file along with all of its "
      "external references.",
      &EggMultiBase::dispatch_none, &_force_complete);
-
-  _coordinate_system = CS_yup_right;
 }
 
-
 ////////////////////////////////////////////////////////////////////
-//     Function: EggMultiBase::append_command_comment
-//       Access: Protected
-//  Description: Inserts a comment into the beginning of the indicated
-//               egg file corresponding to the command line that
-//               invoked this program.
+//     Function: EggMultiBase::post_process_egg_files
+//       Access: Public
+//  Description: Performs any processing of the egg file(s) that is
+//               appropriate before writing them out.  This includes any
+//               normal adjustments the user requested via -np, etc.
 //
-//               Normally this function is called automatically when
-//               appropriate by EggWriter, and it's not necessary to
-//               call it explicitly.
+//               Normally, you should not need to call this function
+//               directly; write_egg_files() calls it for you.  You
+//               should call this only if you do not use
+//               write_egg_files() to write out the resulting egg
+//               files.
 ////////////////////////////////////////////////////////////////////
 void EggMultiBase::
-append_command_comment(EggData &data) {
-  append_command_comment(data, get_exec_command());
-}
+post_process_egg_files() {
+  if (_eggs.empty()) {
+    return;
+  }
 
-////////////////////////////////////////////////////////////////////
-//     Function: EggMultiBase::append_command_comment
-//       Access: Protected, Static
-//  Description: Inserts a comment into the beginning of the indicated
-//               egg file corresponding to the command line that
-//               invoked this program.
-//
-//               Normally this function is called automatically when
-//               appropriate by EggWriter, and it's not necessary to
-//               call it explicitly.
-////////////////////////////////////////////////////////////////////
-void EggMultiBase::
-append_command_comment(EggData &data, const string &comment) {
-  data.insert(data.begin(), new EggComment("", comment));
+  Eggs::iterator ei;
+  if (_got_transform) {
+    nout << "Applying transform matrix:\n";
+    _transform.write(nout, 2);
+    LVecBase3d scale, hpr, translate;
+    if (decompose_matrix(_transform, scale, hpr, translate,
+                         _eggs[0]->get_coordinate_system())) {
+      nout << "(scale " << scale << ", hpr " << hpr << ", translate "
+           << translate << ")\n";
+    }
+    for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
+      (*ei)->transform(_transform);
+    }
+  }
+
+  switch (_normals_mode) {
+  case NM_strip:
+    nout << "Stripping normals.\n";
+    for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
+      (*ei)->strip_normals();
+      (*ei)->remove_unused_vertices();
+    }
+    break;
+
+  case NM_polygon:
+    nout << "Recomputing polygon normals.\n";
+    for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
+      (*ei)->recompute_polygon_normals();
+      (*ei)->remove_unused_vertices();
+    }
+    break;
+
+  case NM_vertex:
+    nout << "Recomputing vertex normals.\n";
+    for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
+      (*ei)->recompute_vertex_normals(_normals_threshold);
+      (*ei)->remove_unused_vertices();
+    }
+    break;
+
+  case NM_preserve:
+    // Do nothing.
+    break;
+  }
 }
 
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggMultiBase::read_egg
 //       Access: Protected, Virtual

+ 9 - 13
pandatool/src/eggbase/eggMultiBase.h

@@ -19,12 +19,12 @@
 #ifndef EGGMULTIBASE_H
 #define EGGMULTIBASE_H
 
-#include <pandatoolbase.h>
+#include "pandatoolbase.h"
 
-#include <programBase.h>
-#include <coordinateSystem.h>
-#include <eggData.h>
-#include <pointerTo.h>
+#include "eggBase.h"
+#include "coordinateSystem.h"
+#include "eggData.h"
+#include "pointerTo.h"
 
 class Filename;
 
@@ -37,21 +37,17 @@ class Filename;
 //               how to read a bunch of egg files in and write them
 //               out again.
 ////////////////////////////////////////////////////////////////////
-class EggMultiBase : public ProgramBase {
+class EggMultiBase : public EggBase {
 public:
   EggMultiBase();
 
-protected:
-  void append_command_comment(EggData &_data);
-  static void append_command_comment(EggData &_data, const string &comment);
+  void post_process_egg_files();
 
+protected:
   virtual PT(EggData) read_egg(const Filename &filename);
 
 protected:
-  bool _got_coordinate_system;
-  CoordinateSystem _coordinate_system;
-
-  typedef pvector<PT(EggData)> Eggs;
+  typedef pvector< PT(EggData) > Eggs;
   Eggs _eggs;
 
   bool _force_complete;

+ 1 - 0
pandatool/src/eggbase/eggMultiFilter.cxx

@@ -189,6 +189,7 @@ get_output_filename(const Filename &source_filename) const {
 void EggMultiFilter::
 write_eggs() {
   nassertv(!_read_only);
+  post_process_egg_files();
   Eggs::iterator ei;
   for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
     EggData *data = (*ei);

+ 2 - 2
pandatool/src/eggbase/eggReader.cxx

@@ -136,7 +136,7 @@ add_delod_options(double default_delod) {
 //               This is intended to work around the C++ limitation
 //               that prevents downcasts past virtual inheritance.
 //               Since both EggReader and EggWriter inherit virtually
-//               from EggBase, we need functions like this to downcast
+//               from EggSingleBase, we need functions like this to downcast
 //               to the appropriate pointer.
 ////////////////////////////////////////////////////////////////////
 EggReader *EggReader::
@@ -211,7 +211,7 @@ handle_args(ProgramBase::Args &args) {
 ////////////////////////////////////////////////////////////////////
 bool EggReader::
 post_command_line() {
-  return EggBase::post_command_line();
+  return EggSingleBase::post_command_line();
 }
 
 ////////////////////////////////////////////////////////////////////

+ 2 - 2
pandatool/src/eggbase/eggReader.h

@@ -21,7 +21,7 @@
 
 #include "pandatoolbase.h"
 
-#include "eggBase.h"
+#include "eggSingleBase.h"
 #include "filename.h"
 
 class PNMFileType;
@@ -31,7 +31,7 @@ class PNMFileType;
 // Description : This is the base class for a program that reads egg
 //               files, but doesn't write an egg file.
 ////////////////////////////////////////////////////////////////////
-class EggReader : virtual public EggBase {
+class EggReader : virtual public EggSingleBase {
 public:
   EggReader();
 

+ 84 - 0
pandatool/src/eggbase/eggSingleBase.cxx

@@ -0,0 +1,84 @@
+// Filename: eggSingleBase.cxx
+// Created by:  drose (21Jul03)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "eggSingleBase.h"
+
+#include "eggGroupNode.h"
+#include "eggTexture.h"
+#include "eggFilenameNode.h"
+#include "eggComment.h"
+#include "dcast.h"
+#include "string_utils.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggSingleBase::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+EggSingleBase::
+EggSingleBase() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggSingleBase::as_reader
+//       Access: Public, Virtual
+//  Description: Returns this object as an EggReader pointer, if it is
+//               in fact an EggReader, or NULL if it is not.
+//
+//               This is intended to work around the C++ limitation
+//               that prevents downcasts past virtual inheritance.
+//               Since both EggReader and EggWriter inherit virtually
+//               from EggSingleBase, we need functions like this to downcast
+//               to the appropriate pointer.
+////////////////////////////////////////////////////////////////////
+EggReader *EggSingleBase::
+as_reader() {
+  return (EggReader *)NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggSingleBase::as_writer
+//       Access: Public, Virtual
+//  Description: Returns this object as an EggWriter pointer, if it is
+//               in fact an EggWriter, or NULL if it is not.
+//
+//               This is intended to work around the C++ limitation
+//               that prevents downcasts past virtual inheritance.
+//               Since both EggReader and EggWriter inherit virtually
+//               from EggSingleBase, we need functions like this to downcast
+//               to the appropriate pointer.
+////////////////////////////////////////////////////////////////////
+EggWriter *EggSingleBase::
+as_writer() {
+  return (EggWriter *)NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggSingleBase::post_command_line
+//       Access: Protected, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+bool EggSingleBase::
+post_command_line() {
+  if (_got_coordinate_system) {
+    _data.set_coordinate_system(_coordinate_system);
+  }
+
+  return EggBase::post_command_line();
+}
+

+ 59 - 0
pandatool/src/eggbase/eggSingleBase.h

@@ -0,0 +1,59 @@
+// Filename: eggSingleBase.h
+// Created by:  drose (21Jul03)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef EGGSINGLEBASE_H
+#define EGGSINGLEBASE_H
+
+#include "pandatoolbase.h"
+
+#include "eggBase.h"
+#include "coordinateSystem.h"
+#include "eggData.h"
+
+class EggReader;
+class EggWriter;
+class EggNode;
+class PathReplace;
+
+////////////////////////////////////////////////////////////////////
+//       Class : EggSingleBase
+// Description : This specialization of EggBase is intended for
+//               programs that read and/or write a single egg file.
+//               (See EggMultiBase for programs that operate on
+//               multiple egg files at once.)
+//
+//               This is just a base class; see EggReader, EggWriter,
+//               or EggFilter according to your particular I/O needs.
+////////////////////////////////////////////////////////////////////
+class EggSingleBase : public EggBase {
+public:
+  EggSingleBase();
+
+  virtual EggReader *as_reader();
+  virtual EggWriter *as_writer();
+
+protected:
+  virtual bool post_command_line();
+
+protected:
+  EggData _data;
+};
+
+#endif
+
+

+ 2 - 294
pandatool/src/eggbase/eggWriter.cxx

@@ -92,89 +92,9 @@ EggWriter(bool allow_last_param, bool allow_stdout) :
      "Specify the coordinate system of the resulting egg file.  This may be "
      "one of 'y-up', 'z-up', 'y-up-left', or 'z-up-left'.  The default is "
      "y-up.");
-
-  _normals_mode = NM_preserve;
-  _normals_threshold = 0.0;
-
-  _got_transform = false;
-  _transform = LMatrix4d::ident_mat();
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: EggWriter::add_normals_options
-//       Access: Public
-//  Description: Adds -no, -np, etc. as valid options for this
-//               program.  If the user specifies one of the options on
-//               the command line, the normals will be adjusted when
-//               the egg file is written out.
-////////////////////////////////////////////////////////////////////
-void EggWriter::
-add_normals_options() {
-  static NormalsMode strip = NM_strip;
-  static NormalsMode polygon = NM_polygon;
-  static NormalsMode vertex = NM_vertex;
-  static NormalsMode preserve = NM_preserve;
-
-  add_option
-    ("no", "", 48,
-     "Strip all normals.",
-     &EggWriter::dispatch_normals, NULL, &strip);
-
-  add_option
-    ("np", "", 48,
-     "Strip existing normals and redefine polygon normals.",
-     &EggWriter::dispatch_normals, NULL, &polygon);
-
-  add_option
-    ("nv", "threshold", 48,
-     "Strip existing normals and redefine vertex normals.  Consider an edge "
-     "between adjacent polygons to be smooth if the angle between them "
-     "is less than threshold degrees.",
-     &EggWriter::dispatch_normals, NULL, &vertex);
-
-  add_option
-    ("nn", "", 48,
-     "Preserve normals exactly as they are.  This is the default.",
-     &EggWriter::dispatch_normals, NULL, &preserve);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggWriter::add_transform_options
-//       Access: Public
-//  Description: Adds -TS, -TT, etc. as valid options for this
-//               program.  If the user specifies one of the options on
-//               the command line, the data will be transformed when
-//               the egg file is written out.
-////////////////////////////////////////////////////////////////////
-void EggWriter::
-add_transform_options() {
-  add_option
-    ("TS", "sx[,sy,sz]", 49,
-     "Scale the model uniformly by the given factor (if only one number "
-     "is given) or in each axis by sx, sy, sz (if three numbers are given).",
-     &EggWriter::dispatch_scale, &_got_transform, &_transform);
-
-  add_option
-    ("TR", "x,y,z", 49,
-     "Rotate the model x degrees about the x axis, then y degrees about the "
-     "y axis, and then z degrees about the z axis.",
-     &EggWriter::dispatch_rotate_xyz, &_got_transform, &_transform);
-
-  add_option
-    ("TA", "angle,x,y,z", 49,
-     "Rotate the model angle degrees counterclockwise about the given "
-     "axis.",
-     &EggWriter::dispatch_rotate_axis, &_got_transform, &_transform);
-
-  add_option
-    ("TT", "x,y,z", 49,
-     "Translate the model by the indicated amount.\n\n"
-     "All transformation options (-TS, -TR, -TA, -TT) are cumulative and are "
-     "applied in the order they are encountered on the command line.",
-     &EggWriter::dispatch_translate, &_got_transform, &_transform);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: EggWriter::as_writer
 //       Access: Public, Virtual
@@ -184,7 +104,7 @@ add_transform_options() {
 //               This is intended to work around the C++ limitation
 //               that prevents downcasts past virtual inheritance.
 //               Since both EggReader and EggWriter inherit virtually
-//               from EggBase, we need functions like this to downcast
+//               from EggSingleBase, we need functions like this to downcast
 //               to the appropriate pointer.
 ////////////////////////////////////////////////////////////////////
 EggWriter *EggWriter::
@@ -304,217 +224,5 @@ post_command_line() {
 
   append_command_comment(_data);
 
-  return EggBase::post_command_line();
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggWriter::dispatch_normals
-//       Access: Protected, Static
-//  Description: Accepts one of -no, -np, etc. and sets _normals_mode
-//               as indicated.  The void * argument is a pointer to a
-//               NormalsMode variable that indicates which switch was
-//               passed.
-////////////////////////////////////////////////////////////////////
-bool EggWriter::
-dispatch_normals(ProgramBase *self, const string &opt, const string &arg, void *mode) {
-  EggBase *base = (EggBase *)self;
-  EggWriter *me = base->as_writer();
-  return me->ns_dispatch_normals(opt, arg, mode);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggWriter::ns_dispatch_normals
-//       Access: Protected
-//  Description: Accepts one of -no, -np, etc. and sets _normals_mode
-//               as indicated.  The void * argument is a pointer to a
-//               NormalsMode variable that indicates which switch was
-//               passed.
-////////////////////////////////////////////////////////////////////
-bool EggWriter::
-ns_dispatch_normals(const string &opt, const string &arg, void *mode) {
-  _normals_mode = *(NormalsMode *)mode;
-
-  if (_normals_mode == NM_vertex) {
-    if (!string_to_double(arg, _normals_threshold)) {
-      nout << "Invalid numeric parameter for -" << opt << ": "
-           << arg << "\n";
-      return false;
-    }
-  }
-
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggWriter::dispatch_scale
-//       Access: Protected, Static
-//  Description: Handles -TS, which specifies a scale transform.  Var
-//               is an LMatrix4d.
-////////////////////////////////////////////////////////////////////
-bool EggWriter::
-dispatch_scale(const string &opt, const string &arg, void *var) {
-  LMatrix4d *transform = (LMatrix4d *)var;
-
-  vector_string words;
-  tokenize(arg, words, ",");
-
-  double sx, sy, sz;
-
-  bool okflag = false;
-  if (words.size() == 3) {
-    okflag =
-      string_to_double(words[0], sx) &&
-      string_to_double(words[1], sy) &&
-      string_to_double(words[2], sz);
-
-  } else if (words.size() == 1) {
-    okflag =
-      string_to_double(words[0], sx);
-    sy = sz = sx;
-  }
-
-  if (!okflag) {
-    nout << "-" << opt
-         << " requires one or three numbers separated by commas.\n";
-    return false;
-  }
-
-  *transform = (*transform) * LMatrix4d::scale_mat(sx, sy, sz);
-
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggWriter::dispatch_rotate_xyz
-//       Access: Protected, Static
-//  Description: Handles -TR, which specifies a rotate transform about
-//               the three cardinal axes.  Var is an LMatrix4d.
-////////////////////////////////////////////////////////////////////
-bool EggWriter::
-dispatch_rotate_xyz(ProgramBase *self, const string &opt, const string &arg, void *var) {
-  EggBase *base = (EggBase *)self;
-  EggWriter *me = base->as_writer();
-  return me->ns_dispatch_rotate_xyz(opt, arg, var);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggWriter::ns_dispatch_rotate_xyz
-//       Access: Protected
-//  Description: Handles -TR, which specifies a rotate transform about
-//               the three cardinal axes.  Var is an LMatrix4d.
-////////////////////////////////////////////////////////////////////
-bool EggWriter::
-ns_dispatch_rotate_xyz(const string &opt, const string &arg, void *var) {
-  LMatrix4d *transform = (LMatrix4d *)var;
-
-  vector_string words;
-  tokenize(arg, words, ",");
-
-  LVecBase3d xyz;
-
-  bool okflag = false;
-  if (words.size() == 3) {
-    okflag =
-      string_to_double(words[0], xyz[0]) &&
-      string_to_double(words[1], xyz[1]) &&
-      string_to_double(words[2], xyz[2]);
-  }
-
-  if (!okflag) {
-    nout << "-" << opt
-         << " requires three numbers separated by commas.\n";
-    return false;
-  }
-
-  LMatrix4d mat =
-    LMatrix4d::rotate_mat(xyz[0], LVector3d(1.0, 0.0, 0.0), _coordinate_system) *
-    LMatrix4d::rotate_mat(xyz[1], LVector3d(0.0, 1.0, 0.0), _coordinate_system) *
-    LMatrix4d::rotate_mat(xyz[2], LVector3d(0.0, 0.0, 1.0), _coordinate_system);
-
-  *transform = (*transform) * mat;
-
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggWriter::dispatch_rotate_axis
-//       Access: Protected, Static
-//  Description: Handles -TA, which specifies a rotate transform about
-//               an arbitrary axis.  Var is an LMatrix4d.
-////////////////////////////////////////////////////////////////////
-bool EggWriter::
-dispatch_rotate_axis(ProgramBase *self, const string &opt, const string &arg, void *var) {
-  EggBase *base = (EggBase *)self;
-  EggWriter *me = base->as_writer();
-  return me->ns_dispatch_rotate_axis(opt, arg, var);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggWriter::ns_dispatch_rotate_axis
-//       Access: Protected
-//  Description: Handles -TA, which specifies a rotate transform about
-//               an arbitrary axis.  Var is an LMatrix4d.
-////////////////////////////////////////////////////////////////////
-bool EggWriter::
-ns_dispatch_rotate_axis(const string &opt, const string &arg, void *var) {
-  LMatrix4d *transform = (LMatrix4d *)var;
-
-  vector_string words;
-  tokenize(arg, words, ",");
-
-  double angle;
-  LVecBase3d axis;
-
-  bool okflag = false;
-  if (words.size() == 4) {
-    okflag =
-      string_to_double(words[0], angle) &&
-      string_to_double(words[1], axis[0]) &&
-      string_to_double(words[2], axis[1]) &&
-      string_to_double(words[3], axis[2]);
-  }
-
-  if (!okflag) {
-    nout << "-" << opt
-         << " requires four numbers separated by commas.\n";
-    return false;
-  }
-
-  *transform = (*transform) * LMatrix4d::rotate_mat(angle, axis, _coordinate_system);
-
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggWriter::dispatch_translate
-//       Access: Protected, Static
-//  Description: Handles -TT, which specifies a translate transform.
-//               Var is an LMatrix4d.
-////////////////////////////////////////////////////////////////////
-bool EggWriter::
-dispatch_translate(const string &opt, const string &arg, void *var) {
-  LMatrix4d *transform = (LMatrix4d *)var;
-
-  vector_string words;
-  tokenize(arg, words, ",");
-
-  LVector3d trans;
-
-  bool okflag = false;
-  if (words.size() == 3) {
-    okflag =
-      string_to_double(words[0], trans[0]) &&
-      string_to_double(words[1], trans[1]) &&
-      string_to_double(words[2], trans[2]);
-  }
-
-  if (!okflag) {
-    nout << "-" << opt
-         << " requires three numbers separated by commas.\n";
-    return false;
-  }
-
-  *transform = (*transform) * LMatrix4d::translate_mat(trans);
-
-  return true;
+  return EggSingleBase::post_command_line();
 }

+ 2 - 28
pandatool/src/eggbase/eggWriter.h

@@ -20,7 +20,7 @@
 #define EGGWRITER_H
 
 #include "pandatoolbase.h"
-#include "eggBase.h"
+#include "eggSingleBase.h"
 #include "withOutputFile.h"
 
 #include "filename.h"
@@ -31,13 +31,10 @@
 // Description : This is the base class for a program that generates
 //               an egg file output, but doesn't read any for input.
 ////////////////////////////////////////////////////////////////////
-class EggWriter : virtual public EggBase, public WithOutputFile {
+class EggWriter : virtual public EggSingleBase, public WithOutputFile {
 public:
   EggWriter(bool allow_last_param = false, bool allow_stdout = true);
 
-  void add_normals_options();
-  void add_transform_options();
-
   virtual EggWriter *as_writer();
 
   virtual void post_process_egg_file();
@@ -47,29 +44,6 @@ protected:
   virtual bool handle_args(Args &args);
   virtual bool post_command_line();
 
-  static bool dispatch_normals(ProgramBase *self, const string &opt, const string &arg, void *mode);
-  bool ns_dispatch_normals(const string &opt, const string &arg, void *mode);
-
-  static bool dispatch_scale(const string &opt, const string &arg, void *var);
-  static bool dispatch_rotate_xyz(ProgramBase *self, const string &opt, const string &arg, void *var);
-  bool ns_dispatch_rotate_xyz(const string &opt, const string &arg, void *var);
-  static bool dispatch_rotate_axis(ProgramBase *self, const string &opt, const string &arg, void *var);
-  bool ns_dispatch_rotate_axis(const string &opt, const string &arg, void *var);
-  static bool dispatch_translate(const string &opt, const string &arg, void *var);
-
-protected:
-  enum NormalsMode {
-    NM_strip,
-    NM_polygon,
-    NM_vertex,
-    NM_preserve
-  };
-  NormalsMode _normals_mode;
-  double _normals_threshold;
-
-  bool _got_transform;
-  LMatrix4d _transform;
-
 private:
   ofstream _output_stream;
   ostream *_output_ptr;

+ 1 - 0
pandatool/src/eggbase/eggbase_composite1.cxx

@@ -6,6 +6,7 @@
 #include "eggMultiFilter.cxx"
 #include "eggReader.cxx"
 #include "eggWriter.cxx"
+#include "eggSingleBase.cxx"
 #include "eggToSomething.cxx"
 #include "somethingToEgg.cxx"