From fac0aa6246f1b9b9371fb4ab740fd2d56a5bead8 Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 26 Apr 2001 01:18:10 +0000 Subject: [PATCH] *** empty log message *** --- panda/src/egg/eggAttributes.cxx | 13 ++- pandatool/src/lwo/lwoSurfaceBlockWrap.cxx | 6 +- pandatool/src/lwo/lwoSurfaceBlockWrap.h | 2 +- pandatool/src/lwoegg/Sources.pp | 1 + pandatool/src/lwoegg/cLwoPoints.cxx | 2 +- pandatool/src/lwoegg/cLwoPolygons.I | 2 + pandatool/src/lwoegg/cLwoPolygons.cxx | 92 +++++++++++++++++++++- pandatool/src/lwoegg/cLwoPolygons.h | 13 +++ pandatool/src/lwoegg/lwoToEggConverter.I | 12 ++- pandatool/src/lwoegg/lwoToEggConverter.cxx | 59 +++++++++++++- pandatool/src/lwoegg/lwoToEggConverter.h | 10 +++ 11 files changed, 200 insertions(+), 12 deletions(-) diff --git a/panda/src/egg/eggAttributes.cxx b/panda/src/egg/eggAttributes.cxx index bc10810b77..95f574222d 100644 --- a/panda/src/egg/eggAttributes.cxx +++ b/panda/src/egg/eggAttributes.cxx @@ -135,6 +135,8 @@ void EggAttributes:: transform(const LMatrix4d &mat) { if (has_normal()) { _normal = _normal * mat; + LVector3d old_normal = _normal; + _normal.normalize(); EggMorphNormalList::iterator mi; for (mi = _dnormals.begin(); mi != _dnormals.end(); ++mi) { @@ -142,8 +144,15 @@ transform(const LMatrix4d &mat) { // we're not changing its name, which is the only thing the set // cares about preserving. EggMorphNormal &morph = (EggMorphNormal &)(*mi); - - morph.set_offset((*mi).get_offset() * mat); + + // A bit of funny business to ensure the offset normal is + // normalized after the transform. This will break strange + // normal morphs that want to change the length of the normal, + // but what else can we do? + LVector3d offset = (*mi).get_offset() * mat; + LVector3d n = old_normal + offset; + n.normalize(); + morph.set_offset(n - _normal); } } } diff --git a/pandatool/src/lwo/lwoSurfaceBlockWrap.cxx b/pandatool/src/lwo/lwoSurfaceBlockWrap.cxx index 124138a3d7..cd02ca9dc9 100644 --- a/pandatool/src/lwo/lwoSurfaceBlockWrap.cxx +++ b/pandatool/src/lwo/lwoSurfaceBlockWrap.cxx @@ -24,7 +24,8 @@ bool LwoSurfaceBlockWrap:: read_iff(IffInputFile *in, size_t stop_at) { LwoInputFile *lin = DCAST(LwoInputFile, in); - _mode = (Mode)lin->get_be_uint16(); + _width = (Mode)lin->get_be_uint16(); + _height = (Mode)lin->get_be_uint16(); return true; } @@ -37,5 +38,6 @@ read_iff(IffInputFile *in, size_t stop_at) { void LwoSurfaceBlockWrap:: write(ostream &out, int indent_level) const { indent(out, indent_level) - << get_id() << " { mode = " << (int)_mode << " }\n"; + << get_id() << " { width = " << (int)_width + << ", height = " << (int)_height << " }\n"; } diff --git a/pandatool/src/lwo/lwoSurfaceBlockWrap.h b/pandatool/src/lwo/lwoSurfaceBlockWrap.h index 02818b1834..15e83ea1b3 100644 --- a/pandatool/src/lwo/lwoSurfaceBlockWrap.h +++ b/pandatool/src/lwo/lwoSurfaceBlockWrap.h @@ -23,7 +23,7 @@ public: M_mirror = 2, // repeat with reflection M_edge = 3 // GL-style clamping }; - Mode _mode; + Mode _width, _height; public: virtual bool read_iff(IffInputFile *in, size_t stop_at); diff --git a/pandatool/src/lwoegg/Sources.pp b/pandatool/src/lwoegg/Sources.pp index cb0c81dea4..b1049b85f3 100644 --- a/pandatool/src/lwoegg/Sources.pp +++ b/pandatool/src/lwoegg/Sources.pp @@ -11,6 +11,7 @@ cLwoLayer.I cLwoLayer.cxx cLwoLayer.h \ cLwoPoints.I cLwoPoints.cxx cLwoPoints.h \ cLwoPolygons.I cLwoPolygons.cxx cLwoPolygons.h \ + cLwoSurface.I cLwoSurface.cxx cLwoSurface.h \ lwoToEggConverter.I lwoToEggConverter.cxx lwoToEggConverter.h #define INSTALL_HEADERS \ diff --git a/pandatool/src/lwoegg/cLwoPoints.cxx b/pandatool/src/lwoegg/cLwoPoints.cxx index 16e0b472ec..4fc9bc90a7 100644 --- a/pandatool/src/lwoegg/cLwoPoints.cxx +++ b/pandatool/src/lwoegg/cLwoPoints.cxx @@ -13,7 +13,7 @@ //////////////////////////////////////////////////////////////////// // Function: CLwoPoints::add_vmap // Access: Public -// Description: Associated the indicated VertexMap with the points +// Description: Associates the indicated VertexMap with the points // set. This may define such niceties as UV coordinates // or per-vertex color. //////////////////////////////////////////////////////////////////// diff --git a/pandatool/src/lwoegg/cLwoPolygons.I b/pandatool/src/lwoegg/cLwoPolygons.I index c6315a6f18..1eaef6b9e4 100644 --- a/pandatool/src/lwoegg/cLwoPolygons.I +++ b/pandatool/src/lwoegg/cLwoPolygons.I @@ -16,4 +16,6 @@ CLwoPolygons(LwoToEggConverter *converter, const LwoPolygons *polygons, _polygons(polygons), _points(points) { + _tags = (LwoTags *)NULL; + _surf_ptags = (LwoPolygonTags *)NULL; } diff --git a/pandatool/src/lwoegg/cLwoPolygons.cxx b/pandatool/src/lwoegg/cLwoPolygons.cxx index 10c84be240..0669e7341f 100644 --- a/pandatool/src/lwoegg/cLwoPolygons.cxx +++ b/pandatool/src/lwoegg/cLwoPolygons.cxx @@ -7,8 +7,79 @@ #include "lwoToEggConverter.h" #include "cLwoPoints.h" #include "cLwoLayer.h" +#include "cLwoSurface.h" +#include +#include #include +#include + +//////////////////////////////////////////////////////////////////// +// Function: CLwoPolygons::add_ptags +// Access: Public +// Description: Associates the indicated PolygonTags and Tags with +// the polygons in this chunk. This may define features +// such as per-polygon surfaces, parts, and smoothing +// groups. +//////////////////////////////////////////////////////////////////// +void CLwoPolygons:: +add_ptags(const LwoPolygonTags *lwo_ptags, const LwoTags *tags) { + if (_tags != (LwoTags *)NULL && _tags != tags) { + nout << "Multiple Tags fields in effect on the same polygons.\n"; + } + _tags = tags; + + IffId type = lwo_ptags->_tag_type; + + bool inserted = _ptags.insert(PTags::value_type(type, lwo_ptags)).second; + if (!inserted) { + nout << "Multiple polygon tags on the same polygons of type " + << type << "\n"; + + } else { + if (type == IffId("SURF")) { + _surf_ptags = lwo_ptags; + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: CLwoPolygons::get_surface +// Access: Public +// Description: Returns the surface associated with the given +// polygon, or NULL if no surface is associated. +//////////////////////////////////////////////////////////////////// +CLwoSurface *CLwoPolygons:: +get_surface(int polygon_index) const { + if (_surf_ptags == (LwoPolygonTags *)NULL) { + // No surface definitions. + return (CLwoSurface *)NULL; + } + + if (!_surf_ptags->has_tag(polygon_index)) { + // The polygon isn't tagged. + return (CLwoSurface *)NULL; + } + + int tag_index = _surf_ptags->get_tag(polygon_index); + if (_tags == (LwoTags *)NULL || tag_index < 0 || + tag_index >= _tags->get_num_tags()) { + // The tag index is out-of-bounds. + nout << "Invalid polygon tag index " << tag_index << "\n"; + return (CLwoSurface *)NULL; + } + + string tag = _tags->get_tag(tag_index); + + // Now look up the surface name in the header. + CLwoSurface *surface = _converter->get_surface(tag); + if (surface == (CLwoSurface *)NULL) { + nout << "Unknown surface " << tag << "\n"; + return (CLwoSurface *)NULL; + } + + return surface; +} //////////////////////////////////////////////////////////////////// // Function: CLwoPolygons::make_egg @@ -38,9 +109,8 @@ make_egg() { make_faces(); } else { - nout << "Unknown geometry type " << _polygons->_polygon_type - << "; treating as FACE.\n"; - make_faces(); + nout << "Ignoring unknown geometry type " << _polygons->_polygon_type + << ".\n"; } } @@ -64,10 +134,12 @@ connect_egg() { //////////////////////////////////////////////////////////////////// void CLwoPolygons:: make_faces() { + float smooth_angle = -1.0; + 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; @@ -97,8 +169,20 @@ make_faces() { } if (is_valid) { + CLwoSurface *surface = get_surface(i); + if (surface != (CLwoSurface *)NULL) { + surface->apply_properties(egg_poly, smooth_angle); + } + _egg_group->add_child(egg_poly.p()); } } + + CoordinateSystem cs = _converter->get_egg_data().get_coordinate_system(); + if (smooth_angle > 0.0) { + _egg_group->recompute_vertex_normals(rad_2_deg(smooth_angle), cs); + } else { + _egg_group->recompute_polygon_normals(cs); + } } diff --git a/pandatool/src/lwoegg/cLwoPolygons.h b/pandatool/src/lwoegg/cLwoPolygons.h index 45faa166e2..00563d35d8 100644 --- a/pandatool/src/lwoegg/cLwoPolygons.h +++ b/pandatool/src/lwoegg/cLwoPolygons.h @@ -14,6 +14,9 @@ class LwoToEggConverter; class CLwoPoints; +class CLwoSurface; +class LwoTags; +class LwoPolygonTags; //////////////////////////////////////////////////////////////////// // Class : CLwoPolygons @@ -27,6 +30,10 @@ public: const LwoPolygons *polygons, CLwoPoints *points); + void add_ptags(const LwoPolygonTags *lwo_ptags, const LwoTags *tags); + + CLwoSurface *get_surface(int polygon_index) const; + void make_egg(); void connect_egg(); @@ -35,6 +42,12 @@ public: CLwoPoints *_points; PT(EggGroup) _egg_group; + const LwoTags *_tags; + typedef map PTags; + PTags _ptags; + + const LwoPolygonTags *_surf_ptags; + private: void make_faces(); }; diff --git a/pandatool/src/lwoegg/lwoToEggConverter.I b/pandatool/src/lwoegg/lwoToEggConverter.I index 424ecc3494..a7f25d393c 100644 --- a/pandatool/src/lwoegg/lwoToEggConverter.I +++ b/pandatool/src/lwoegg/lwoToEggConverter.I @@ -10,7 +10,17 @@ // Description: Returns a root node suitable for parenting egg // structures to. //////////////////////////////////////////////////////////////////// -EggGroupNode *LwoToEggConverter:: +INLINE EggGroupNode *LwoToEggConverter:: get_egg_root() const { return &_egg_data; } + +//////////////////////////////////////////////////////////////////// +// Function: LwoToEggConverter::get_egg_data +// Access: Public +// Description: Returns the EggData structure. +//////////////////////////////////////////////////////////////////// +INLINE EggData &LwoToEggConverter:: +get_egg_data() { + return _egg_data; +} diff --git a/pandatool/src/lwoegg/lwoToEggConverter.cxx b/pandatool/src/lwoegg/lwoToEggConverter.cxx index 0c7a173d5c..f88afa4434 100644 --- a/pandatool/src/lwoegg/lwoToEggConverter.cxx +++ b/pandatool/src/lwoegg/lwoToEggConverter.cxx @@ -7,12 +7,15 @@ #include "cLwoLayer.h" #include "cLwoPoints.h" #include "cLwoPolygons.h" +#include "cLwoSurface.h" #include #include #include #include #include +#include +#include //////////////////////////////////////////////////////////////////// @@ -56,6 +59,12 @@ LwoToEggConverter:: CLwoPolygons *polygons = (*gi); delete polygons; } + + Surfaces::iterator si; + for (si = _surfaces.begin(); si != _surfaces.end(); ++si) { + CLwoSurface *surface = (*si).second; + delete surface; + } } //////////////////////////////////////////////////////////////////// @@ -72,6 +81,8 @@ convert_lwo(const LwoHeader *lwo_header) { make_egg(); connect_egg(); + _egg_data.remove_unused_vertices(); + return !_error; } @@ -89,6 +100,22 @@ get_layer(int number) const { return (CLwoLayer *)NULL; } +//////////////////////////////////////////////////////////////////// +// Function: LwoToEggConverter::get_surface +// Access: Public +// Description: Returns a pointer to the surface definition with the +// given name, or NULL if there is no such surface. +//////////////////////////////////////////////////////////////////// +CLwoSurface *LwoToEggConverter:: +get_surface(const string &name) const { + Surfaces::const_iterator si; + si = _surfaces.find(name); + if (si != _surfaces.end()) { + return (*si).second; + } + return (CLwoSurface *)NULL; +} + //////////////////////////////////////////////////////////////////// // Function: LwoToEggConverter::collect_lwo // Access: Private @@ -101,6 +128,8 @@ collect_lwo() { CLwoPoints *last_points = (CLwoPoints *)NULL; CLwoPolygons *last_polygons = (CLwoPolygons *)NULL; + const LwoTags *tags = (const LwoTags *)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); @@ -137,15 +166,43 @@ collect_lwo() { last_points->add_vmap(lwo_vmap); } + } else if (chunk->is_of_type(LwoTags::get_class_type())) { + tags = DCAST(LwoTags, chunk); + } 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); + CLwoPolygons *polygons = + new CLwoPolygons(this, lwo_polygons, last_points); _polygons.push_back(polygons); last_polygons = polygons; } + + } else if (chunk->is_of_type(LwoPolygonTags::get_class_type())) { + if (last_polygons == (CLwoPolygons *)NULL) { + nout << "Polygon tags chunk encountered without a preceding polygons chunk.\n"; + } else if (tags == (LwoTags *)NULL) { + nout << "Polygon tags chunk encountered without a preceding tags chunk.\n"; + } else { + const LwoPolygonTags *lwo_ptags = DCAST(LwoPolygonTags, chunk); + last_polygons->add_ptags(lwo_ptags, tags); + } + + } else if (chunk->is_of_type(LwoSurface::get_class_type())) { + if (last_layer == (CLwoLayer *)NULL) { + last_layer = make_generic_layer(); + } + + const LwoSurface *lwo_surface = DCAST(LwoSurface, chunk); + CLwoSurface *surface = new CLwoSurface(this, lwo_surface); + + bool inserted = _surfaces.insert(Surfaces::value_type(surface->get_name(), surface)).second; + if (!inserted) { + nout << "Multiple surface definitions named " << surface->get_name() << "\n"; + delete surface; + } } } } diff --git a/pandatool/src/lwoegg/lwoToEggConverter.h b/pandatool/src/lwoegg/lwoToEggConverter.h index a96d6ae5c4..37d3085b46 100644 --- a/pandatool/src/lwoegg/lwoToEggConverter.h +++ b/pandatool/src/lwoegg/lwoToEggConverter.h @@ -12,9 +12,13 @@ #include #include +#include +#include + class CLwoLayer; class CLwoPoints; class CLwoPolygons; +class CLwoSurface; //////////////////////////////////////////////////////////////////// // Class : LwoToEggConverter @@ -31,8 +35,11 @@ public: bool convert_lwo(const LwoHeader *lwo_header); INLINE EggGroupNode *get_egg_root() const; + INLINE EggData &get_egg_data(); CLwoLayer *get_layer(int number) const; + CLwoSurface *get_surface(const string &name) const; + private: void collect_lwo(); void make_egg(); @@ -54,6 +61,9 @@ private: typedef vector Polygons; Polygons _polygons; + typedef map Surfaces; + Surfaces _surfaces; + bool _error; };