diff --git a/pandatool/src/eggprogs/Sources.pp b/pandatool/src/eggprogs/Sources.pp index fa2812a0a6..236f38eeed 100644 --- a/pandatool/src/eggprogs/Sources.pp +++ b/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 diff --git a/pandatool/src/eggprogs/lwoToEgg.cxx b/pandatool/src/eggprogs/lwoToEgg.cxx new file mode 100644 index 0000000000..ad1c0aed0c --- /dev/null +++ b/pandatool/src/eggprogs/lwoToEgg.cxx @@ -0,0 +1,89 @@ +// Filename: lwoToEgg.cxx +// Created by: drose (17Apr01) +// +//////////////////////////////////////////////////////////////////// + +#include "lwoToEgg.h" + +#include +#include +#include + +//////////////////////////////////////////////////////////////////// +// 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; +} diff --git a/pandatool/src/eggprogs/lwoToEgg.h b/pandatool/src/eggprogs/lwoToEgg.h new file mode 100644 index 0000000000..fb6c1a4734 --- /dev/null +++ b/pandatool/src/eggprogs/lwoToEgg.h @@ -0,0 +1,31 @@ +// Filename: lwoToEgg.h +// Created by: drose (17Apr01) +// +//////////////////////////////////////////////////////////////////// + +#ifndef LWOTOEGG_H +#define LWOTOEGG_H + +#include + +#include +#include + +#include + +//////////////////////////////////////////////////////////////////// +// 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 + diff --git a/pandatool/src/fltegg/fltToEggConverter.cxx b/pandatool/src/fltegg/fltToEggConverter.cxx index 811947bbac..4cb2c54df6 100644 --- a/pandatool/src/fltegg/fltToEggConverter.cxx +++ b/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) { diff --git a/pandatool/src/lwo/lwoLayer.cxx b/pandatool/src/lwo/lwoLayer.cxx index 9c66210494..1903a3250a 100644 --- a/pandatool/src/lwo/lwoLayer.cxx +++ b/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 diff --git a/pandatool/src/lwo/lwoLayer.h b/pandatool/src/lwo/lwoLayer.h index 8cbbec0b59..6ce5beb0bf 100644 --- a/pandatool/src/lwo/lwoLayer.h +++ b/pandatool/src/lwo/lwoLayer.h @@ -22,6 +22,8 @@ //////////////////////////////////////////////////////////////////// class LwoLayer : public LwoChunk { public: + void make_generic(); + enum Flags { F_hidden = 0x0001 }; diff --git a/pandatool/src/lwoegg/Sources.pp b/pandatool/src/lwoegg/Sources.pp new file mode 100644 index 0000000000..cb0c81dea4 --- /dev/null +++ b/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 diff --git a/pandatool/src/lwoegg/cLwoLayer.I b/pandatool/src/lwoegg/cLwoLayer.I new file mode 100644 index 0000000000..f02280daf5 --- /dev/null +++ b/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; +} diff --git a/pandatool/src/lwoegg/cLwoLayer.cxx b/pandatool/src/lwoegg/cLwoLayer.cxx new file mode 100644 index 0000000000..4987c56e3a --- /dev/null +++ b/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()); +} + diff --git a/pandatool/src/lwoegg/cLwoLayer.h b/pandatool/src/lwoegg/cLwoLayer.h new file mode 100644 index 0000000000..6892742e86 --- /dev/null +++ b/pandatool/src/lwoegg/cLwoLayer.h @@ -0,0 +1,40 @@ +// Filename: cLwoLayer.h +// Created by: drose (25Apr01) +// +//////////////////////////////////////////////////////////////////// + +#ifndef CLWOLAYER_H +#define CLWOLAYER_H + +#include + +#include +#include +#include + +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 + + diff --git a/pandatool/src/lwoegg/cLwoPoints.I b/pandatool/src/lwoegg/cLwoPoints.I new file mode 100644 index 0000000000..79e9ef441a --- /dev/null +++ b/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) +{ +} diff --git a/pandatool/src/lwoegg/cLwoPoints.cxx b/pandatool/src/lwoegg/cLwoPoints.cxx new file mode 100644 index 0000000000..6410d23810 --- /dev/null +++ b/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 + +//////////////////////////////////////////////////////////////////// +// 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()); + } +} + diff --git a/pandatool/src/lwoegg/cLwoPoints.h b/pandatool/src/lwoegg/cLwoPoints.h new file mode 100644 index 0000000000..8c55b62cbf --- /dev/null +++ b/pandatool/src/lwoegg/cLwoPoints.h @@ -0,0 +1,42 @@ +// Filename: cLwoPoints.h +// Created by: drose (25Apr01) +// +//////////////////////////////////////////////////////////////////// + +#ifndef CLWOPOINTS_H +#define CLWOPOINTS_H + +#include + +#include +#include +#include + +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 + + diff --git a/pandatool/src/lwoegg/cLwoPolygons.I b/pandatool/src/lwoegg/cLwoPolygons.I new file mode 100644 index 0000000000..c6315a6f18 --- /dev/null +++ b/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) +{ +} diff --git a/pandatool/src/lwoegg/cLwoPolygons.cxx b/pandatool/src/lwoegg/cLwoPolygons.cxx new file mode 100644 index 0000000000..e85731526f --- /dev/null +++ b/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 + +//////////////////////////////////////////////////////////////////// +// 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()); + } + } +} + diff --git a/pandatool/src/lwoegg/cLwoPolygons.h b/pandatool/src/lwoegg/cLwoPolygons.h new file mode 100644 index 0000000000..45faa166e2 --- /dev/null +++ b/pandatool/src/lwoegg/cLwoPolygons.h @@ -0,0 +1,46 @@ +// Filename: cLwoPolygons.h +// Created by: drose (25Apr01) +// +//////////////////////////////////////////////////////////////////// + +#ifndef CLWOPOLYGONS_H +#define CLWOPOLYGONS_H + +#include + +#include +#include +#include + +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 + + diff --git a/pandatool/src/lwoegg/lwoToEggConverter.I b/pandatool/src/lwoegg/lwoToEggConverter.I new file mode 100644 index 0000000000..424ecc3494 --- /dev/null +++ b/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; +} diff --git a/pandatool/src/lwoegg/lwoToEggConverter.cxx b/pandatool/src/lwoegg/lwoToEggConverter.cxx new file mode 100644 index 0000000000..6c09aa6c55 --- /dev/null +++ b/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 +#include +#include +#include + + +//////////////////////////////////////////////////////////////////// +// 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; +} diff --git a/pandatool/src/lwoegg/lwoToEggConverter.h b/pandatool/src/lwoegg/lwoToEggConverter.h new file mode 100644 index 0000000000..a96d6ae5c4 --- /dev/null +++ b/pandatool/src/lwoegg/lwoToEggConverter.h @@ -0,0 +1,64 @@ +// Filename: lwoToEggConverter.h +// Created by: drose (17Apr01) +// +//////////////////////////////////////////////////////////////////// + +#ifndef LWOTOEGGCONVERTER_H +#define LWOTOEGGCONVERTER_H + +#include + +#include +#include +#include + +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 Layers; + Layers _layers; + + typedef vector Points; + Points _points; + + typedef vector Polygons; + Polygons _polygons; + + bool _error; +}; + +#include "lwoToEggConverter.I" + +#endif + +