*** empty log message ***

This commit is contained in:
David Rose 2001-04-25 22:22:02 +00:00
parent 9e1e9f09f6
commit 28b5f9e924
19 changed files with 290 additions and 25 deletions

View File

@ -62,6 +62,12 @@ run() {
}
LwoHeader *header = DCAST(LwoHeader, chunk);
if (!header->is_valid()) {
nout << "File " << _input_filename
<< " is not recognized as a Lightwave Object file. "
<< "Perhaps the version is too recent.\n";
exit(1);
}
_data.set_coordinate_system(_coordinate_system);

View File

@ -16,8 +16,8 @@
lwoClip.cxx lwoClip.h \
lwoDiscontinuousVertexMap.cxx lwoDiscontinuousVertexMap.h \
lwoGroupChunk.cxx lwoGroupChunk.h \
lwoHeader.cxx \
lwoHeader.h lwoInputFile.cxx lwoInputFile.h \
lwoHeader.I lwoHeader.cxx lwoHeader.h \
lwoInputFile.I lwoInputFile.cxx lwoInputFile.h \
lwoLayer.h lwoLayer.cxx \
lwoPoints.h lwoPoints.cxx \
lwoPolygons.h lwoPolygons.cxx \
@ -53,8 +53,8 @@
lwoClip.h \
lwoDiscontinuousVertexMap.h \
lwoGroupChunk.h \
lwoHeader.h \
lwoInputFile.h \
lwoHeader.I lwoHeader.h \
lwoInputFile.I lwoInputFile.h \
lwoLayer.h \
lwoPoints.h \
lwoPolygons.h \

View File

@ -4,3 +4,32 @@
////////////////////////////////////////////////////////////////////
#include "iffId.h"
#include <ctype.h>
////////////////////////////////////////////////////////////////////
// Function: IffId::output
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void IffId::
output(ostream &out) const {
// If all of the characters are printable, just output them.
if (isprint(_id._c[0]) && isprint(_id._c[1]) &&
isprint(_id._c[2]) && isprint(_id._c[3])) {
out << _id._c[0] << _id._c[1] << _id._c[2] << _id._c[3];
} else if (isprint(_id._c[0]) && isprint(_id._c[1]) &&
isprint(_id._c[2]) && _id._c[3] == '\0') {
// If the last character is 0, output a 3-letter ID.
out << _id._c[0] << _id._c[1] << _id._c[2];
} else {
// Otherwise, write out the hex.
out << "0x" << hex << setfill('0');
for (int i = 0; i < 4; i++) {
out << setw(2) << (int)(unsigned char)_id._c[i];
}
out << dec << setfill(' ');
}
}

View File

@ -29,6 +29,8 @@ public:
INLINE bool operator < (const IffId &other) const;
INLINE string get_name() const;
void output(ostream &out) const;
private:
union {
@ -40,7 +42,8 @@ private:
#include "iffId.I"
INLINE ostream &operator << (ostream &out, const IffId &id) {
return out << id.get_name();
id.output(out);
return out;
}
#endif

View File

@ -21,6 +21,7 @@ IffInputFile() {
_input = (istream *)NULL;
_owns_istream = false;
_eof = true;
_unexpected_eof = false;
_bytes_read = 0;
}
@ -70,6 +71,7 @@ set_input(istream *input, bool owns_istream) {
_input = input;
_owns_istream = owns_istream;
_eof = false;
_unexpected_eof = false;
_bytes_read = 0;
}
@ -241,7 +243,10 @@ get_chunk() {
if (chunk->read_iff(this, end_point)) {
if (is_eof()) {
nout << "Unexpected EOF on file.\n";
if (!_unexpected_eof) {
nout << "Unexpected EOF on file reading " << *chunk << "\n";
_unexpected_eof = true;
}
return (IffChunk *)NULL;
}
@ -292,7 +297,10 @@ get_subchunk(IffChunk *context) {
if (chunk->read_iff(this, end_point)) {
if (is_eof()) {
nout << "Unexpected EOF on file.\n";
if (!_unexpected_eof) {
nout << "Unexpected EOF on file reading " << *chunk << "\n";
_unexpected_eof = true;
}
return (IffChunk *)NULL;
}

View File

@ -64,6 +64,7 @@ protected:
Filename _filename;
bool _owns_istream;
bool _eof;
bool _unexpected_eof;
size_t _bytes_read;
public:

View File

@ -0,0 +1,27 @@
// Filename: lwoHeader.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: LwoHeader::is_valid
// Access: Public
// Description: Returns true if the header represents a valid and
// recognized Lightwave header, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool LwoHeader::
is_valid() const {
return _valid;
}
////////////////////////////////////////////////////////////////////
// Function: LwoHeader::get_version
// Access: Public
// Description: Returns the version of the Lightwave file.
////////////////////////////////////////////////////////////////////
INLINE double LwoHeader::
get_version() const {
return _version;
}

View File

@ -4,12 +4,23 @@
////////////////////////////////////////////////////////////////////
#include "lwoHeader.h"
#include "iffInputFile.h"
#include "lwoInputFile.h"
#include <indent.h>
TypeHandle LwoHeader::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LwoHeader::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
LwoHeader::
LwoHeader() {
_valid = false;
_version = 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: LwoHeader::read_iff
// Access: Public, Virtual
@ -22,8 +33,24 @@ TypeHandle LwoHeader::_type_handle;
////////////////////////////////////////////////////////////////////
bool LwoHeader::
read_iff(IffInputFile *in, size_t stop_at) {
_lwid = in->get_id();
read_chunks_iff(in, stop_at);
LwoInputFile *lin = DCAST(LwoInputFile, in);
_lwid = lin->get_id();
if (_lwid == IffId("LWO2")) {
_valid = true;
_version = 6.0;
} else if (_lwid == IffId("LWOB")) {
_valid = true;
_version = 5.0;
}
if (_valid) {
lin->set_lwo_version(_version);
}
read_chunks_iff(lin, stop_at);
return true;
}

View File

@ -16,11 +16,20 @@
////////////////////////////////////////////////////////////////////
class LwoHeader : public LwoGroupChunk {
public:
LwoHeader();
IffId _lwid;
INLINE bool is_valid() const;
INLINE double get_version() const;
public:
virtual bool read_iff(IffInputFile *in, size_t stop_at);
virtual void write(ostream &out, int indent_level = 0) const;
private:
bool _valid;
double _version;
public:
virtual TypeHandle get_type() const {
@ -40,6 +49,8 @@ private:
static TypeHandle _type_handle;
};
#include "lwoHeader.I"
#endif

View File

@ -0,0 +1,31 @@
// Filename: lwoInputFile.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: LwoInputFile::get_lwo_version
// Access: Public
// Description: Returns the version of the Lightwave file being read.
// This is unknown until the header record has been
// read; then it will be set by the header.
////////////////////////////////////////////////////////////////////
INLINE double LwoInputFile::
get_lwo_version() const {
return _lwo_version;
}
////////////////////////////////////////////////////////////////////
// Function: LwoInputFile::set_lwo_version
// Access: Public
// Description: Changes the version number reported for the Lightwave
// file. Normally this is only called by LwoHeader as
// it is read.
////////////////////////////////////////////////////////////////////
INLINE void LwoInputFile::
set_lwo_version(double lwo_version) {
_lwo_version = lwo_version;
}

View File

@ -120,7 +120,8 @@ make_new_chunk(IffId id) {
} else if (id == IffId("POLS")) {
return new LwoPolygons;
} else if (id == IffId("TAGS")) {
} else if (id == IffId("TAGS") ||
id == IffId("SRFS")) {
return new LwoTags;
} else if (id == IffId("PTAG")) {

View File

@ -22,6 +22,9 @@ public:
LwoInputFile();
~LwoInputFile();
INLINE double get_lwo_version() const;
INLINE void set_lwo_version(double version);
int get_vx();
LVecBase3f get_vec3();
Filename get_filename();
@ -29,6 +32,9 @@ public:
protected:
virtual IffChunk *make_new_chunk(IffId id);
private:
double _lwo_version;
public:
virtual TypeHandle get_type() const {
return get_class_type();
@ -47,6 +53,8 @@ private:
static TypeHandle _type_handle;
};
#include "lwoInputFile.I"
#endif

View File

@ -45,23 +45,68 @@ bool LwoPolygons::
read_iff(IffInputFile *in, size_t stop_at) {
LwoInputFile *lin = DCAST(LwoInputFile, in);
_polygon_type = lin->get_id();
if (lin->get_lwo_version() >= 6.0) {
// 6.x style syntax:
// POLS { type[ID4], ( numvert+flags[U2], vert[VX] # numvert )* }
while (lin->get_bytes_read() < stop_at && !lin->is_eof()) {
int nf = lin->get_be_int16();
int num_vertices = nf & PF_numverts_mask;
_polygon_type = lin->get_id();
PT(Polygon) poly = new Polygon;
poly->_flags = nf & ~PF_numverts_mask;
for (int i = 0; i < num_vertices; i++) {
poly->_vertices.push_back(lin->get_vx());
while (lin->get_bytes_read() < stop_at && !lin->is_eof()) {
int nf = lin->get_be_uint16();
int num_vertices = nf & PF_numverts_mask;
PT(Polygon) poly = new Polygon;
poly->_flags = nf & ~PF_numverts_mask;
poly->_surface_index = -1;
for (int i = 0; i < num_vertices; i++) {
int vindex = lin->get_vx();
poly->_vertices.push_back(vindex);
}
_polygons.push_back(poly);
}
_polygons.push_back(poly);
} else {
// 5.x style syntax:
// POLS { ( numvert[U2], vert[VX] # numvert, +/-(surf+1)[I2], numdetail[U2]? )* }
_polygon_type = IffId("FACE");
int num_decals = 0;
while (lin->get_bytes_read() < stop_at && !lin->is_eof()) {
int num_vertices = lin->get_be_uint16();
PT(Polygon) poly = new Polygon;
poly->_flags = 0;
for (int i = 0; i < num_vertices; i++) {
int vindex = lin->get_vx();
poly->_vertices.push_back(vindex);
}
int surface = lin->get_be_int16();
if (num_decals > 0) {
// This is a decal polygon of a previous polygon.
num_decals--;
poly->_flags |= PF_decal;
} else {
if (surface < 0) {
num_decals = lin->get_be_int16();
surface = -surface;
}
}
// The surface index is stored +1 to allow signedness to be
// examined.
poly->_surface_index = surface - 1;
_polygons.push_back(poly);
}
}
return (lin->get_bytes_read() == stop_at);
return true;
}
////////////////////////////////////////////////////////////////////

View File

@ -25,13 +25,24 @@ public:
enum PolygonFlags {
PF_continuity_1 = 0x0400,
PF_continuity_2 = 0x0800,
PF_numverts_mask = 0x03ff
PF_numverts_mask = 0x03ff,
// This "flag" is stored artificially when reading 5.x LWOB files,
// and indicates that the polygon is a decal of a preceding
// polygon.
PF_decal = 0x0001
};
class Polygon : public ReferenceCount {
public:
int _flags;
vector_int _vertices;
// This value is only filled in when reading 5.x LWOB files, and
// indicates the surface index of the polygon within a preceding
// SRFS (LwoTags) chunk. For 6.x and later files, this will be
// set to -1.
int _surface_index;
};
int get_num_polygons() const;

View File

@ -17,6 +17,11 @@
// Class : LwoTags
// Description : An array of tag strings that will be referenced by
// later chunks.
//
// This also serves as an array of surface names to be
// referenced by a later LwoPolygons chunk, in 5.x LWOB
// files. The chunk id can be used to differentiate the
// meaning (TAGS vs. SRFS).
////////////////////////////////////////////////////////////////////
class LwoTags : public LwoChunk {
public:

View File

@ -7,8 +7,26 @@
#include "lwoToEggConverter.h"
#include "cLwoLayer.h"
#include <lwoVertexMap.h>
#include <string_utils.h>
////////////////////////////////////////////////////////////////////
// Function: CLwoPoints::add_vmap
// Access: Public
// Description: Associated the indicated VertexMap with the points
// set. This may define such niceties as UV coordinates
// or per-vertex color.
////////////////////////////////////////////////////////////////////
void CLwoPoints::
add_vmap(const LwoVertexMap *lwo_vmap) {
VMapNames &names = _vmap[lwo_vmap->_map_type];
bool inserted = names.insert(VMapNames::value_type(lwo_vmap->_name, lwo_vmap)).second;
if (!inserted) {
nout << "Multiple vertex maps on the same points of type "
<< lwo_vmap->_map_type << " named " << lwo_vmap->_name << "\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: CLwoPoints::make_egg
// Access: Public

View File

@ -12,7 +12,10 @@
#include <eggVertexPool.h>
#include <pointerTo.h>
#include <map>
class LwoToEggConverter;
class LwoVertexMap;
class CLwoLayer;
////////////////////////////////////////////////////////////////////
@ -26,6 +29,8 @@ public:
INLINE CLwoPoints(LwoToEggConverter *converter, const LwoPoints *points,
CLwoLayer *layer);
void add_vmap(const LwoVertexMap *lwo_vmap);
void make_egg();
void connect_egg();
@ -33,6 +38,12 @@ public:
CPT(LwoPoints) _points;
CLwoLayer *_layer;
PT(EggVertexPool) _egg_vpool;
// A number of vertex maps may be associated, by type and then by
// name.
typedef map<string, const LwoVertexMap *> VMapNames;
typedef map<IffId, VMapNames> VmapTypes;
VmapTypes _vmap;
};
#include "cLwoPoints.I"

View File

@ -38,8 +38,9 @@ make_egg() {
make_faces();
} else {
nout << "Ignoring unknown geometry type " << _polygons->_polygon_type
<< "\n";
nout << "Unknown geometry type " << _polygons->_polygon_type
<< "; treating as FACE.\n";
make_faces();
}
}
@ -50,6 +51,8 @@ make_egg() {
////////////////////////////////////////////////////////////////////
void CLwoPolygons::
connect_egg() {
nassertv(_points->_layer->_egg_group != (EggGroup *)NULL);
nassertv(_egg_group != (EggGroup *)NULL);
_points->_layer->_egg_group->steal_children(*_egg_group);
}

View File

@ -12,6 +12,7 @@
#include <lwoLayer.h>
#include <lwoPoints.h>
#include <lwoPolygons.h>
#include <lwoVertexMap.h>
////////////////////////////////////////////////////////////////////
@ -98,6 +99,7 @@ void LwoToEggConverter::
collect_lwo() {
CLwoLayer *last_layer = (CLwoLayer *)NULL;
CLwoPoints *last_points = (CLwoPoints *)NULL;
CLwoPolygons *last_polygons = (CLwoPolygons *)NULL;
int num_chunks = _lwo_header->get_num_chunks();
for (int i = 0; i < num_chunks; i++) {
@ -115,6 +117,7 @@ collect_lwo() {
_layers[number] = layer;
last_layer = layer;
last_points = (CLwoPoints *)NULL;
last_polygons = (CLwoPolygons *)NULL;
} else if (chunk->is_of_type(LwoPoints::get_class_type())) {
if (last_layer == (CLwoLayer *)NULL) {
@ -126,6 +129,14 @@ collect_lwo() {
_points.push_back(points);
last_points = points;
} else if (chunk->is_of_type(LwoVertexMap::get_class_type())) {
if (last_points == (CLwoPoints *)NULL) {
nout << "Vertex map chunk encountered without a preceding points chunk.\n";
} else {
const LwoVertexMap *lwo_vmap = DCAST(LwoVertexMap, chunk);
last_points->add_vmap(lwo_vmap);
}
} 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";
@ -133,6 +144,7 @@ collect_lwo() {
const LwoPolygons *lwo_polygons = DCAST(LwoPolygons, chunk);
CLwoPolygons *polygons = new CLwoPolygons(this, lwo_polygons, last_points);
_polygons.push_back(polygons);
last_polygons = polygons;
}
}
}
@ -146,6 +158,10 @@ collect_lwo() {
////////////////////////////////////////////////////////////////////
void LwoToEggConverter::
make_egg() {
if (_generic_layer != (CLwoLayer *)NULL) {
_generic_layer->make_egg();
}
Layers::iterator li;
for (li = _layers.begin(); li != _layers.end(); ++li) {
CLwoLayer *layer = (*li);
@ -174,6 +190,10 @@ make_egg() {
////////////////////////////////////////////////////////////////////
void LwoToEggConverter::
connect_egg() {
if (_generic_layer != (CLwoLayer *)NULL) {
_generic_layer->connect_egg();
}
Layers::iterator li;
for (li = _layers.begin(); li != _layers.end(); ++li) {
CLwoLayer *layer = (*li);