Browse Source

*** empty log message ***

David Rose 25 years ago
parent
commit
69c2c5a08c

+ 15 - 0
pandatool/src/eggprogs/Sources.pp

@@ -29,3 +29,18 @@
     eggTopstrip.cxx eggTopstrip.h
 
 #end bin_target
+
+#begin bin_target
+  #define TARGET lwo2egg
+  #define LOCAL_LIBS lwo lwoegg eggbase progbase
+
+  #define OTHER_LIBS \
+    egg:c pandaegg:m \
+    linmath:c panda:m \
+    express:c pandaexpress:m \
+    dtoolutil:c dconfig:c dtoolconfig:m dtool:m pystub
+
+  #define SOURCES \
+    lwoToEgg.cxx lwoToEgg.h
+
+#end bin_target

+ 89 - 0
pandatool/src/eggprogs/lwoToEgg.cxx

@@ -0,0 +1,89 @@
+// Filename: lwoToEgg.cxx
+// Created by:  drose (17Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+#include "lwoToEgg.h"
+
+#include <lwoToEggConverter.h>
+#include <lwoHeader.h>
+#include <lwoInputFile.h>
+
+////////////////////////////////////////////////////////////////////
+//     Function: LwoToEgg::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+LwoToEgg::
+LwoToEgg() :
+  SomethingToEgg("MultiGen", ".lwo")
+{
+  add_normals_options();
+  add_transform_options();
+
+  set_program_description
+    ("This program converts Lightwave Object (.lwo) files to egg.  Many "
+     "rendering characteristics of Lightwave (like layered shaders, etc.) "
+     "are not supported, but fundamental things like polygons and texture "
+     "maps are.");
+
+  redescribe_option
+    ("cs",
+     "Specify the coordinate system of the input " + _format_name +
+     " file.  Normally, this is y-up-left.");
+
+  _coordinate_system = CS_yup_left;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LwoToEgg::run
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void LwoToEgg::
+run() {
+  LwoInputFile in;
+
+  nout << "Reading " << _input_filename << "\n";
+  if (!in.open_read(_input_filename)) {
+    nout << "Unable to open " << _input_filename << "\n";
+    exit(1);
+  }
+
+  PT(IffChunk) chunk = in.get_chunk();
+  if (chunk == (IffChunk *)NULL) {
+    nout << "Unable to read " << _input_filename << "\n";
+    exit(1);
+  }
+
+  if (!chunk->is_of_type(LwoHeader::get_class_type())) {
+    nout << "File " << _input_filename << " is not a Lightwave Object file.\n";
+    exit(1);
+  }
+
+  LwoHeader *header = DCAST(LwoHeader, chunk);
+
+  _data.set_coordinate_system(_coordinate_system);
+
+  if (_input_units == DU_invalid) {
+    _input_units = DU_meters;
+  }
+
+  LwoToEggConverter converter(_data);
+
+  if (!converter.convert_lwo(header)) {
+    nout << "Errors in conversion.\n";
+    exit(1);
+  }
+
+  write_egg_file();
+  nout << "\n";
+}
+
+
+int main(int argc, char *argv[]) {
+  LwoToEgg prog;
+  prog.parse_command_line(argc, argv);
+  prog.run();
+  return 0;
+}

+ 31 - 0
pandatool/src/eggprogs/lwoToEgg.h

@@ -0,0 +1,31 @@
+// Filename: lwoToEgg.h
+// Created by:  drose (17Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+#ifndef LWOTOEGG_H
+#define LWOTOEGG_H
+
+#include <pandatoolbase.h>
+
+#include <somethingToEgg.h>
+#include <lwoToEggConverter.h>
+
+#include <dSearchPath.h>
+
+////////////////////////////////////////////////////////////////////
+// 	 Class : LwoToEgg
+// Description : A program to read a Lightwave file and generate an egg
+//               file.
+////////////////////////////////////////////////////////////////////
+class LwoToEgg : public SomethingToEgg {
+public:
+  LwoToEgg();
+
+  void run();
+
+protected:
+};
+
+#endif
+

+ 3 - 2
pandatool/src/fltegg/fltToEggConverter.cxx

@@ -35,13 +35,14 @@ FltToEggConverter::
 FltToEggConverter(EggData &egg_data) : _egg_data(egg_data) {
   _tpc = PC_unchanged;
   _mpc = PC_unchanged;
+  _error = false;
 }
 
 ////////////////////////////////////////////////////////////////////
 //     Function: FltToEggConverter::convert_flt
 //       Access: Public
-//  Description: Returns a newly-allocated EggData structure
-//               corresponding to the indicated flt structure.
+//  Description: Fills up the egg_data structure according to the
+//               indicated lwo structure.
 ////////////////////////////////////////////////////////////////////
 bool FltToEggConverter::
 convert_flt(const FltHeader *flt_header) {

+ 15 - 0
pandatool/src/lwo/lwoLayer.cxx

@@ -10,6 +10,21 @@
 
 TypeHandle LwoLayer::_type_handle;
 
+////////////////////////////////////////////////////////////////////
+//     Function: LwoLayer::make_generic
+//       Access: Public
+//  Description: Resets the layer's parameters to initial defaults for
+//               a generic layer created implicitly.
+////////////////////////////////////////////////////////////////////
+void LwoLayer::
+make_generic() {
+  _number = -1;
+  _flags = 0;
+  _pivot.set(0.0, 0.0, 0.0);
+  _name = "Generic";
+  _parent = -1;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: LwoLayer::read_iff
 //       Access: Public, Virtual

+ 2 - 0
pandatool/src/lwo/lwoLayer.h

@@ -22,6 +22,8 @@
 ////////////////////////////////////////////////////////////////////
 class LwoLayer : public LwoChunk {
 public:
+  void make_generic();
+
   enum Flags {
     F_hidden   = 0x0001
   };

+ 19 - 0
pandatool/src/lwoegg/Sources.pp

@@ -0,0 +1,19 @@
+#begin ss_lib_target
+  #define TARGET lwoegg
+  #define LOCAL_LIBS pandatoolbase lwo
+  #define OTHER_LIBS \
+    egg:c pandaegg:m \
+    mathutil:c linmath:c putil:c express:c panda:m dtoolconfig dtool
+  #define UNIX_SYS_LIBS \
+    m
+
+  #define SOURCES \
+    cLwoLayer.I cLwoLayer.cxx cLwoLayer.h \
+    cLwoPoints.I cLwoPoints.cxx cLwoPoints.h \
+    cLwoPolygons.I cLwoPolygons.cxx cLwoPolygons.h \
+    lwoToEggConverter.I lwoToEggConverter.cxx lwoToEggConverter.h
+
+  #define INSTALL_HEADERS \
+    lwoToEggConverter.I lwoToEggConverter.h
+
+#end ss_lib_target

+ 29 - 0
pandatool/src/lwoegg/cLwoLayer.I

@@ -0,0 +1,29 @@
+// Filename: cLwoLayer.I
+// Created by:  drose (25Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLwoLayer::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE CLwoLayer::
+CLwoLayer(LwoToEggConverter *converter, const LwoLayer *layer) : 
+  _converter(converter),
+  _layer(layer) 
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLwoLayer::get_number
+//       Access: Public
+//  Description: Returns the index number associated with this
+//               particular layer.  This should be unique among all
+//               Lightwave layers in a single file.
+////////////////////////////////////////////////////////////////////
+INLINE int CLwoLayer::
+get_number() const {
+  return _layer->_number;
+}

+ 49 - 0
pandatool/src/lwoegg/cLwoLayer.cxx

@@ -0,0 +1,49 @@
+// Filename: cLwoLayer.cxx
+// Created by:  drose (25Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+#include "cLwoLayer.h"
+#include "lwoToEggConverter.h"
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLwoLayer::make_egg
+//       Access: Public
+//  Description: Creates the egg structures associated with this
+//               Lightwave object.
+////////////////////////////////////////////////////////////////////
+void CLwoLayer::
+make_egg() {
+  _egg_group = new EggGroup(_layer->_name);
+
+  if (_layer->_pivot != LPoint3f::zero()) {
+    // If we have a nonzero pivot point, that's a translation
+    // transform.
+    LPoint3d translate = LCAST(double, _layer->_pivot);
+    _egg_group->set_transform(LMatrix4d::translate_mat(translate));
+    _egg_group->set_group_type(EggGroup::GT_instance);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLwoLayer::connect_egg
+//       Access: Public
+//  Description: Connects all the egg structures together.
+////////////////////////////////////////////////////////////////////
+void CLwoLayer::
+connect_egg() {
+  if (_layer->_parent != -1) {
+    const CLwoLayer *parent = _converter->get_layer(_layer->_parent);
+    if (parent != (CLwoLayer *)NULL) {
+      parent->_egg_group->add_child(_egg_group.p());
+      return;
+    }
+
+    nout << "No layer found with number " << _layer->_parent 
+	 << "; cannot parent layer " << _layer->_number << " properly.\n";
+  }
+  
+  _converter->get_egg_root()->add_child(_egg_group.p());
+}
+

+ 40 - 0
pandatool/src/lwoegg/cLwoLayer.h

@@ -0,0 +1,40 @@
+// Filename: cLwoLayer.h
+// Created by:  drose (25Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+#ifndef CLWOLAYER_H
+#define CLWOLAYER_H
+
+#include <pandatoolbase.h>
+
+#include <lwoLayer.h>
+#include <eggGroup.h>
+#include <pointerTo.h>
+
+class LwoToEggConverter;
+
+////////////////////////////////////////////////////////////////////
+// 	 Class : CLwoLayer
+// Description : This class is a wrapper around LwoLayer and stores
+//               additional information useful during the
+//               conversion-to-egg process.
+////////////////////////////////////////////////////////////////////
+class CLwoLayer {
+public:
+  INLINE CLwoLayer(LwoToEggConverter *converter, const LwoLayer *layer);
+  INLINE int get_number() const;
+
+  void make_egg();
+  void connect_egg();
+
+  LwoToEggConverter *_converter;
+  CPT(LwoLayer) _layer;
+  PT(EggGroup) _egg_group;
+};
+
+#include "cLwoLayer.I"
+
+#endif
+
+

+ 19 - 0
pandatool/src/lwoegg/cLwoPoints.I

@@ -0,0 +1,19 @@
+// Filename: cLwoPoints.I
+// Created by:  drose (25Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLwoPoints::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE CLwoPoints::
+CLwoPoints(LwoToEggConverter *converter, const LwoPoints *points,
+	   CLwoLayer *layer) : 
+  _converter(converter),
+  _points(points),
+  _layer(layer)
+{
+}

+ 37 - 0
pandatool/src/lwoegg/cLwoPoints.cxx

@@ -0,0 +1,37 @@
+// Filename: cLwoPoints.cxx
+// Created by:  drose (25Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+#include "cLwoPoints.h"
+#include "lwoToEggConverter.h"
+#include "cLwoLayer.h"
+
+#include <string_utils.h>
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLwoPoints::make_egg
+//       Access: Public
+//  Description: Creates the egg structures associated with this
+//               Lightwave object.
+////////////////////////////////////////////////////////////////////
+void CLwoPoints::
+make_egg() {
+  // Generate a vpool name based on the layer index, for lack of
+  // anything better.
+  string vpool_name = "layer" + format_string(_layer->get_number());
+  _egg_vpool = new EggVertexPool(vpool_name);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLwoPoints::connect_egg
+//       Access: Public
+//  Description: Connects all the egg structures together.
+////////////////////////////////////////////////////////////////////
+void CLwoPoints::
+connect_egg() {
+  if (!_egg_vpool->empty()) {
+    _layer->_egg_group->add_child(_egg_vpool.p());
+  }
+}
+

+ 42 - 0
pandatool/src/lwoegg/cLwoPoints.h

@@ -0,0 +1,42 @@
+// Filename: cLwoPoints.h
+// Created by:  drose (25Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+#ifndef CLWOPOINTS_H
+#define CLWOPOINTS_H
+
+#include <pandatoolbase.h>
+
+#include <lwoPoints.h>
+#include <eggVertexPool.h>
+#include <pointerTo.h>
+
+class LwoToEggConverter;
+class CLwoLayer;
+
+////////////////////////////////////////////////////////////////////
+// 	 Class : CLwoPoints
+// Description : This class is a wrapper around LwoPoints and stores
+//               additional information useful during the
+//               conversion-to-egg process.
+////////////////////////////////////////////////////////////////////
+class CLwoPoints {
+public:
+  INLINE CLwoPoints(LwoToEggConverter *converter, const LwoPoints *points,
+		    CLwoLayer *layer);
+
+  void make_egg();
+  void connect_egg();
+
+  LwoToEggConverter *_converter;
+  CPT(LwoPoints) _points;
+  CLwoLayer *_layer;
+  PT(EggVertexPool) _egg_vpool;
+};
+
+#include "cLwoPoints.I"
+
+#endif
+
+

+ 19 - 0
pandatool/src/lwoegg/cLwoPolygons.I

@@ -0,0 +1,19 @@
+// Filename: cLwoPolygons.I
+// Created by:  drose (25Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLwoPolygons::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE CLwoPolygons::
+CLwoPolygons(LwoToEggConverter *converter, const LwoPolygons *polygons,
+	     CLwoPoints *points) : 
+  _converter(converter),
+  _polygons(polygons),
+  _points(points)
+{
+}

+ 101 - 0
pandatool/src/lwoegg/cLwoPolygons.cxx

@@ -0,0 +1,101 @@
+// Filename: cLwoPolygons.cxx
+// Created by:  drose (25Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+#include "cLwoPolygons.h"
+#include "lwoToEggConverter.h"
+#include "cLwoPoints.h"
+#include "cLwoLayer.h"
+
+#include <eggPolygon.h>
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLwoPolygons::make_egg
+//       Access: Public
+//  Description: Creates the egg structures associated with this
+//               Lightwave object.
+////////////////////////////////////////////////////////////////////
+void CLwoPolygons::
+make_egg() {
+  // First, we need a temporary group to hold all of the polygons
+  // we'll create.
+  _egg_group = new EggGroup;
+
+  if (_polygons->_polygon_type == IffId("CURV")) {
+    nout << "Ignoring Catmull-Rom splines.\n";
+
+  } else if (_polygons->_polygon_type == IffId("PTCH")) {
+    nout << "Ignoring subdivision patches.\n";
+
+  } else if (_polygons->_polygon_type == IffId("MBAL")) {
+    nout << "Ignoring metaballs.\n";
+
+  } else if (_polygons->_polygon_type == IffId("BONE")) {
+    nout << "Ignoring bones.\n";
+
+  } else if (_polygons->_polygon_type == IffId("FACE")) {
+    make_faces();
+
+  } else {
+    nout << "Ignoring unknown geometry type " << _polygons->_polygon_type
+	 << "\n";
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLwoPolygons::connect_egg
+//       Access: Public
+//  Description: Connects all the egg structures together.
+////////////////////////////////////////////////////////////////////
+void CLwoPolygons::
+connect_egg() {
+  _points->_layer->_egg_group->steal_children(*_egg_group);
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLwoPolygons::make_faces
+//       Access: Public
+//  Description: Generates "face" polygons, i.e. actual polygons.
+////////////////////////////////////////////////////////////////////
+void CLwoPolygons::
+make_faces() {
+  int num_polygons = _polygons->get_num_polygons();
+  for (int i = 0; i < num_polygons; i++) {
+    LwoPolygons::Polygon *poly = _polygons->get_polygon(i);
+
+    PT(EggPolygon) egg_poly = new EggPolygon;
+
+    bool is_valid = true;
+
+    // Set up the vertices.
+    const LwoPoints *points = _points->_points;
+    int num_points = points->get_num_points();
+    EggVertexPool *egg_vpool = _points->_egg_vpool;
+
+    // We reverse the vertex ordering to compensate for Lightwave's
+    // clockwise ordering convention.
+    vector_int::reverse_iterator vi;
+    for (vi = poly->_vertices.rbegin(); 
+	 vi != poly->_vertices.rend() && is_valid; 
+	 ++vi) {
+      int vindex = (*vi);
+      if (vindex < 0 || vindex >= num_points) {
+	nout << "Invalid vertex index " << vindex << " in polygon.\n";
+	is_valid = false;
+
+      } else {
+	EggVertex egg_vert;
+	egg_vert.set_pos(LCAST(double, points->get_point(vindex)));
+	EggVertex *new_vert = egg_vpool->create_unique_vertex(egg_vert);
+	egg_poly->add_vertex(new_vert);
+      }
+    }
+
+    if (is_valid) {
+      _egg_group->add_child(egg_poly.p());
+    }
+  }
+}
+

+ 46 - 0
pandatool/src/lwoegg/cLwoPolygons.h

@@ -0,0 +1,46 @@
+// Filename: cLwoPolygons.h
+// Created by:  drose (25Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+#ifndef CLWOPOLYGONS_H
+#define CLWOPOLYGONS_H
+
+#include <pandatoolbase.h>
+
+#include <lwoPolygons.h>
+#include <eggGroup.h>
+#include <pointerTo.h>
+
+class LwoToEggConverter;
+class CLwoPoints;
+
+////////////////////////////////////////////////////////////////////
+// 	 Class : CLwoPolygons
+// Description : This class is a wrapper around LwoPolygons and stores
+//               additional information useful during the
+//               conversion-to-egg process.
+////////////////////////////////////////////////////////////////////
+class CLwoPolygons {
+public:
+  INLINE CLwoPolygons(LwoToEggConverter *converter, 
+		      const LwoPolygons *polygons,
+		      CLwoPoints *points);
+
+  void make_egg();
+  void connect_egg();
+
+  LwoToEggConverter *_converter;
+  CPT(LwoPolygons) _polygons;
+  CLwoPoints *_points;
+  PT(EggGroup) _egg_group;
+
+private:
+  void make_faces();
+};
+
+#include "cLwoPolygons.I"
+
+#endif
+
+

+ 16 - 0
pandatool/src/lwoegg/lwoToEggConverter.I

@@ -0,0 +1,16 @@
+// Filename: lwoToEggConverter.I
+// Created by:  drose (25Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: LwoToEggConverter::get_egg_root
+//       Access: Public
+//  Description: Returns a root node suitable for parenting egg
+//               structures to.
+////////////////////////////////////////////////////////////////////
+EggGroupNode *LwoToEggConverter::
+get_egg_root() const {
+  return &_egg_data;
+}

+ 230 - 0
pandatool/src/lwoegg/lwoToEggConverter.cxx

@@ -0,0 +1,230 @@
+// Filename: lwoToEggConverter.cxx
+// Created by:  drose (25Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+#include "lwoToEggConverter.h"
+#include "cLwoLayer.h"
+#include "cLwoPoints.h"
+#include "cLwoPolygons.h"
+
+#include <lwoHeader.h>
+#include <lwoLayer.h>
+#include <lwoPoints.h>
+#include <lwoPolygons.h>
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: LwoToEggConverter::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+LwoToEggConverter::
+LwoToEggConverter(EggData &egg_data) : _egg_data(egg_data) {
+  _generic_layer = (CLwoLayer *)NULL;
+  _error = false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LwoToEggConverter::Destructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+LwoToEggConverter::
+~LwoToEggConverter() {
+  if (_generic_layer != (CLwoLayer *)NULL) {
+    delete _generic_layer;
+  }
+
+  Layers::iterator li;
+  for (li = _layers.begin(); li != _layers.end(); ++li) {
+    CLwoLayer *layer = (*li);
+    if (layer != (CLwoLayer *)NULL) {
+      delete layer;
+    }
+  }
+
+  Points::iterator pi;
+  for (pi = _points.begin(); pi != _points.end(); ++pi) {
+    CLwoPoints *points = (*pi);
+    delete points;
+  }
+
+  Polygons::iterator gi;
+  for (gi = _polygons.begin(); gi != _polygons.end(); ++gi) {
+    CLwoPolygons *polygons = (*gi);
+    delete polygons;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LwoToEggConverter::convert_lwo
+//       Access: Public
+//  Description: Fills up the egg_data structure according to the
+//               indicated lwo structure.
+////////////////////////////////////////////////////////////////////
+bool LwoToEggConverter::
+convert_lwo(const LwoHeader *lwo_header) {
+  _lwo_header = lwo_header;
+
+  collect_lwo();
+  make_egg();
+  connect_egg();
+
+  return !_error;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LwoToEggConverter::get_layer
+//       Access: Public
+//  Description: Returns a pointer to the layer with the given index
+//               number, or NULL if there is no such layer.
+////////////////////////////////////////////////////////////////////
+CLwoLayer *LwoToEggConverter::
+get_layer(int number) const {
+  if (number >= 0 && number < (int)_layers.size()) {
+    return _layers[number];
+  }
+  return (CLwoLayer *)NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LwoToEggConverter::collect_lwo
+//       Access: Private
+//  Description: Walks through the chunks in the Lightwave data and
+//               creates wrapper objects for each relevant piece.
+////////////////////////////////////////////////////////////////////
+void LwoToEggConverter::
+collect_lwo() {  
+  CLwoLayer *last_layer = (CLwoLayer *)NULL;
+  CLwoPoints *last_points = (CLwoPoints *)NULL;
+
+  int num_chunks = _lwo_header->get_num_chunks();
+  for (int i = 0; i < num_chunks; i++) {
+    const IffChunk *chunk = _lwo_header->get_chunk(i);
+
+    if (chunk->is_of_type(LwoLayer::get_class_type())) {
+      const LwoLayer *lwo_layer = DCAST(LwoLayer, chunk);
+      CLwoLayer *layer = new CLwoLayer(this, lwo_layer);
+      int number = layer->get_number();
+      slot_layer(number);
+
+      if (_layers[number] != (CLwoLayer *)NULL) {
+	nout << "Warning: multiple layers with number " << number << "\n";
+      }
+      _layers[number] = layer;
+      last_layer = layer;
+      last_points = (CLwoPoints *)NULL;
+
+    } else if (chunk->is_of_type(LwoPoints::get_class_type())) {
+      if (last_layer == (CLwoLayer *)NULL) {
+	last_layer = make_generic_layer();
+      }
+
+      const LwoPoints *lwo_points = DCAST(LwoPoints, chunk);
+      CLwoPoints *points = new CLwoPoints(this, lwo_points, last_layer);
+      _points.push_back(points);
+      last_points = points;
+
+    } else if (chunk->is_of_type(LwoPolygons::get_class_type())) {
+      if (last_points == (CLwoPoints *)NULL) {
+	nout << "Polygon chunk encountered without a preceding points chunk.\n";
+      } else {
+	const LwoPolygons *lwo_polygons = DCAST(LwoPolygons, chunk);
+	CLwoPolygons *polygons = new CLwoPolygons(this, lwo_polygons, last_points);
+	_polygons.push_back(polygons);
+      }
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LwoToEggConverter::make_egg
+//       Access: Private
+//  Description: Makes egg structures for all of the conversion
+//               wrapper objects.
+////////////////////////////////////////////////////////////////////
+void LwoToEggConverter::
+make_egg() {  
+  Layers::iterator li;
+  for (li = _layers.begin(); li != _layers.end(); ++li) {
+    CLwoLayer *layer = (*li);
+    if (layer != (CLwoLayer *)NULL) {
+      layer->make_egg();
+    }
+  }
+
+  Points::iterator pi;
+  for (pi = _points.begin(); pi != _points.end(); ++pi) {
+    CLwoPoints *points = (*pi);
+    points->make_egg();
+  }
+
+  Polygons::iterator gi;
+  for (gi = _polygons.begin(); gi != _polygons.end(); ++gi) {
+    CLwoPolygons *polygons = (*gi);
+    polygons->make_egg();
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LwoToEggConverter::connect_egg
+//       Access: Private
+//  Description: Connects together all of the egg structures.
+////////////////////////////////////////////////////////////////////
+void LwoToEggConverter::
+connect_egg() {  
+  Layers::iterator li;
+  for (li = _layers.begin(); li != _layers.end(); ++li) {
+    CLwoLayer *layer = (*li);
+    if (layer != (CLwoLayer *)NULL) {
+      layer->connect_egg();
+    }
+  }
+
+  Points::iterator pi;
+  for (pi = _points.begin(); pi != _points.end(); ++pi) {
+    CLwoPoints *points = (*pi);
+    points->connect_egg();
+  }
+
+  Polygons::iterator gi;
+  for (gi = _polygons.begin(); gi != _polygons.end(); ++gi) {
+    CLwoPolygons *polygons = (*gi);
+    polygons->connect_egg();
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LwoToEggConverter::slot_layer
+//       Access: Private
+//  Description: Ensures that there is space in the _layers array to
+//               store an element at position number.
+////////////////////////////////////////////////////////////////////
+void LwoToEggConverter::
+slot_layer(int number) {
+  while (number >= (int)_layers.size()) {
+    _layers.push_back((CLwoLayer *)NULL);
+  }
+  nassertv(number >= 0 && number < (int)_layers.size());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LwoToEggConverter::make_generic_layer
+//       Access: Private
+//  Description: If a geometry definition is encountered in the
+//               Lightwave file before a layer definition, we should
+//               make a generic layer to hold the geometry.  This
+//               makes and returns a single layer for this purpose.
+//               It should not be called twice.
+////////////////////////////////////////////////////////////////////
+CLwoLayer *LwoToEggConverter::
+make_generic_layer() {
+  nassertr(_generic_layer == (CLwoLayer *)NULL, _generic_layer);
+
+  PT(LwoLayer) layer = new LwoLayer;
+  layer->make_generic();
+
+  _generic_layer = new CLwoLayer(this, layer);
+  return _generic_layer;
+}

+ 64 - 0
pandatool/src/lwoegg/lwoToEggConverter.h

@@ -0,0 +1,64 @@
+// Filename: lwoToEggConverter.h
+// Created by:  drose (17Apr01)
+// 
+////////////////////////////////////////////////////////////////////
+
+#ifndef LWOTOEGGCONVERTER_H
+#define LWOTOEGGCONVERTER_H
+
+#include <pandatoolbase.h>
+
+#include <lwoHeader.h>
+#include <eggData.h>
+#include <pointerTo.h>
+
+class CLwoLayer;
+class CLwoPoints;
+class CLwoPolygons;
+
+////////////////////////////////////////////////////////////////////
+// 	 Class : LwoToEggConverter
+// Description : This class supervises the construction of an EggData
+//               structure from the data represented by the LwoHeader.
+//               Reading and writing the egg and lwo structures is
+//               left to the user.
+////////////////////////////////////////////////////////////////////
+class LwoToEggConverter {
+public:
+  LwoToEggConverter(EggData &egg_data);
+  ~LwoToEggConverter();
+
+  bool convert_lwo(const LwoHeader *lwo_header);
+
+  INLINE EggGroupNode *get_egg_root() const;
+  CLwoLayer *get_layer(int number) const;
+
+private:
+  void collect_lwo();
+  void make_egg();
+  void connect_egg();
+
+  void slot_layer(int number);
+  CLwoLayer *make_generic_layer();
+
+  EggData &_egg_data;
+  CPT(LwoHeader) _lwo_header;
+  
+  CLwoLayer *_generic_layer;
+  typedef vector<CLwoLayer *> Layers;
+  Layers _layers;
+
+  typedef vector<CLwoPoints *> Points;
+  Points _points;
+
+  typedef vector<CLwoPolygons *> Polygons;
+  Polygons _polygons;
+
+  bool _error;
+};
+
+#include "lwoToEggConverter.I"
+
+#endif
+
+