*** empty log message ***

This commit is contained in:
David Rose 2001-04-24 19:06:00 +00:00
parent 30c079bd15
commit 2b0b4b7dad
49 changed files with 2571 additions and 0 deletions

View File

@ -0,0 +1,51 @@
#define LOCAL_LIBS pandatoolbase
#define OTHER_LIBS \
mathutil:c linmath:c putil:c express:c panda:m dtoolconfig dtool
#define UNIX_SYS_LIBS \
m
#begin ss_lib_target
#define TARGET lwo
#define SOURCES \
config_lwo.cxx config_lwo.h iffChunk.I iffChunk.cxx iffChunk.h \
iffGenericChunk.I iffGenericChunk.cxx iffGenericChunk.h iffId.I \
iffId.cxx iffId.h iffInputFile.I iffInputFile.cxx iffInputFile.h \
lwoChunk.I lwoChunk.cxx lwoChunk.h \
lwoDiscontinuousVertexMap.I lwoDiscontinuousVertexMap.cxx lwoDiscontinuousVertexMap.h \
lwoGroupChunk.I lwoGroupChunk.cxx lwoGroupChunk.h \
lwoHeader.I lwoHeader.cxx \
lwoHeader.h lwoInputFile.I lwoInputFile.cxx lwoInputFile.h \
lwoLayer.h lwoLayer.I lwoLayer.cxx \
lwoPoints.h lwoPoints.I lwoPoints.cxx \
lwoPolygons.h lwoPolygons.I lwoPolygons.cxx \
lwoPolygonTags.h lwoPolygonTags.I lwoPolygonTags.cxx \
lwoTags.h lwoTags.I lwoTags.cxx \
lwoVertexMap.h lwoVertexMap.I lwoVertexMap.cxx
#define INSTALL_HEADERS \
iffChunk.I iffChunk.h iffGenericChunk.I iffGenericChunk.h iffId.I \
iffId.h iffInputFile.I iffInputFile.h \
lwoChunk.I lwoChunk.h \
lwoDiscontinuousVertexMap.I lwoDiscontinuousVertexMap.h \
lwoGroupChunk.I lwoGroupChunk.h \
lwoHeader.I lwoHeader.h \
lwoInputFile.I lwoInputFile.h \
lwoLayer.I lwoLayer.h \
lwoPoints.I lwoPoints.h \
lwoPolygons.I lwoPolygons.h \
lwoPolygonTags.I lwoPolygonTags.h \
lwoTags.I lwoTags.h \
lwoVertexMap.I lwoVertexMap.h
#end ss_lib_target
#begin test_bin_target
#define TARGET test_lwo
#define LOCAL_LIBS lwo $[LOCAL_LIBS]
#define OTHER_LIBS $[OTHER_LIBS] pystub:c
#define SOURCES \
test_lwo.cxx
#end test_bin_target

View File

@ -0,0 +1,42 @@
// Filename: config_lwo.cxx
// Created by: drose (23Apr01)
//
////////////////////////////////////////////////////////////////////
#include "config_lwo.h"
#include "iffChunk.h"
#include "iffGenericChunk.h"
#include "iffInputFile.h"
#include "lwoChunk.h"
#include "lwoDiscontinuousVertexMap.h"
#include "lwoGroupChunk.h"
#include "lwoHeader.h"
#include "lwoInputFile.h"
#include "lwoLayer.h"
#include "lwoPoints.h"
#include "lwoPolygons.h"
#include "lwoPolygonTags.h"
#include "lwoTags.h"
#include "lwoVertexMap.h"
#include <dconfig.h>
Configure(config_lwo);
ConfigureFn(config_lwo) {
IffChunk::init_type();
IffGenericChunk::init_type();
IffInputFile::init_type();
LwoChunk::init_type();
LwoDiscontinuousVertexMap::init_type();
LwoGroupChunk::init_type();
LwoHeader::init_type();
LwoInputFile::init_type();
LwoLayer::init_type();
LwoPoints::init_type();
LwoPolygons::init_type();
LwoPolygonTags::init_type();
LwoTags::init_type();
LwoVertexMap::init_type();
}

View File

@ -0,0 +1,11 @@
// Filename: config_lwo.h
// Created by: drose (23Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef CONFIG_LWO_H
#define CONFIG_LWO_H
#include <pandatoolbase.h>
#endif

View File

@ -0,0 +1,34 @@
// Filename: iffChunk.I
// Created by: drose (23Apr01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: IffChunk::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE IffChunk::
IffChunk() {
}
////////////////////////////////////////////////////////////////////
// Function: IffChunk::get_id
// Access: Public
// Description: Returns the ID associated with this chunk.
////////////////////////////////////////////////////////////////////
INLINE IffId IffChunk::
get_id() const {
return _id;
}
////////////////////////////////////////////////////////////////////
// Function: IffChunk::set_id
// Access: Public
// Description: Changes the ID associated with this chunk.
////////////////////////////////////////////////////////////////////
INLINE void IffChunk::
set_id(IffId id) {
_id = id;
}

View File

@ -0,0 +1,43 @@
// Filename: iffChunk.cxx
// Created by: drose (23Apr01)
//
////////////////////////////////////////////////////////////////////
#include "iffChunk.h"
#include "iffInputFile.h"
#include <indent.h>
TypeHandle IffChunk::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: IffChunk::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void IffChunk::
output(ostream &out) const {
out << _id << " (" << get_type() << ")";
}
////////////////////////////////////////////////////////////////////
// Function: IffChunk::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void IffChunk::
write(ostream &out, int indent_level) const {
indent(out, indent_level) << _id << " { ... }\n";
}
////////////////////////////////////////////////////////////////////
// Function: IffChunk::make_new_chunk
// Access: Public, Virtual
// Description: Allocates and returns a new chunk of the appropriate
// type based on the given ID, according to the context
// given by this chunk itself.
////////////////////////////////////////////////////////////////////
IffChunk *IffChunk::
make_new_chunk(IffInputFile *in, IffId id) {
return in->make_new_chunk(id);
}

View File

@ -0,0 +1,67 @@
// Filename: iffChunk.h
// Created by: drose (23Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef IFFCHUNK_H
#define IFFCHUNK_H
#include <pandatoolbase.h>
#include "iffId.h"
#include <typeHandle.h>
#include <typedReferenceCount.h>
class IffInputFile;
////////////////////////////////////////////////////////////////////
// Class : IffChunk
// Description : The basic kind of record in an EA "IFF" file, which
// the LightWave object file is based on.
////////////////////////////////////////////////////////////////////
class IffChunk : public TypedReferenceCount {
public:
INLINE IffChunk();
INLINE IffId get_id() const;
INLINE void set_id(IffId id);
virtual bool read_iff(IffInputFile *in, size_t stop_at)=0;
virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level = 0) const;
virtual IffChunk *make_new_chunk(IffInputFile *in, IffId id);
private:
IffId _id;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "IffChunk",
TypedReferenceCount::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "iffChunk.I"
INLINE ostream &operator << (ostream &out, const IffChunk &chunk) {
chunk.output(out);
return out;
}
#endif

View File

@ -0,0 +1,34 @@
// Filename: iffGenericChunk.I
// Created by: drose (23Apr01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: IffGenericChunk::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE IffGenericChunk::
IffGenericChunk() {
}
////////////////////////////////////////////////////////////////////
// Function: IffGenericChunk::get_data
// Access: Public
// Description: Returns the data in the chunk.
////////////////////////////////////////////////////////////////////
INLINE const Datagram &IffGenericChunk::
get_data() const {
return _data;
}
////////////////////////////////////////////////////////////////////
// Function: IffGenericChunk::set_data
// Access: Public
// Description: Changes the data in the chunk
////////////////////////////////////////////////////////////////////
INLINE void IffGenericChunk::
set_data(const Datagram &data) {
_data = data;
}

View File

@ -0,0 +1,42 @@
// Filename: iffGenericChunk.cxx
// Created by: drose (23Apr01)
//
////////////////////////////////////////////////////////////////////
#include "iffGenericChunk.h"
#include "iffInputFile.h"
#include <indent.h>
TypeHandle IffGenericChunk::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: IffGenericChunk::read_iff
// Access: Public, Virtual
// Description: Reads the data of the chunk in from the given input
// file, if possible. The ID and length of the chunk
// have already been read. stop_at is the byte position
// of the file to stop at (based on the current position
// at in->get_bytes_read()). Returns true on success,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool IffGenericChunk::
read_iff(IffInputFile *in, size_t stop_at) {
size_t length = stop_at - in->get_bytes_read();
bool result = in->read_bytes(_data, length);
in->align();
return result;
}
////////////////////////////////////////////////////////////////////
// Function: IffGenericChunk::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void IffGenericChunk::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< get_id() << " { " << _data.get_length() << " bytes }\n";
}

View File

@ -0,0 +1,57 @@
// Filename: iffGenericChunk.h
// Created by: drose (23Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef IFFGENERICCHUNK_H
#define IFFGENERICCHUNK_H
#include <pandatoolbase.h>
#include "iffChunk.h"
#include <datagram.h>
////////////////////////////////////////////////////////////////////
// Class : IffGenericChunk
// Description : A class for a generic kind of IffChunk that is not
// understood by a particular IffReader. It remembers
// its entire contents.
////////////////////////////////////////////////////////////////////
class IffGenericChunk : public IffChunk {
public:
INLINE IffGenericChunk();
INLINE const Datagram &get_data() const;
INLINE void set_data(const Datagram &data);
virtual bool read_iff(IffInputFile *in, size_t stop_at);
virtual void write(ostream &out, int indent_level = 0) const;
private:
Datagram _data;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
IffChunk::init_type();
register_type(_type_handle, "IffGenericChunk",
IffChunk::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "iffGenericChunk.I"
#endif

96
pandatool/src/lwo/iffId.I Normal file
View File

@ -0,0 +1,96 @@
// Filename: iffId.I
// Created by: drose (23Apr01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: IffId::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE IffId::
IffId() {
_id._c[0] = 0;
_id._c[1] = 0;
_id._c[2] = 0;
_id._c[3] = 0;
}
////////////////////////////////////////////////////////////////////
// Function: IffId::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE IffId::
IffId(const char id[4]) {
_id._c[0] = id[0];
_id._c[1] = id[1];
_id._c[2] = id[2];
_id._c[3] = id[3];
}
////////////////////////////////////////////////////////////////////
// Function: IffId::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE IffId::
IffId(const IffId &copy) {
_id._n = copy._id._n;
}
////////////////////////////////////////////////////////////////////
// Function: IffId::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void IffId::
operator = (const IffId &copy) {
_id._n = copy._id._n;
}
////////////////////////////////////////////////////////////////////
// Function: IffId::Equivalence Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool IffId::
operator == (const IffId &other) const {
return (_id._n == other._id._n);
}
////////////////////////////////////////////////////////////////////
// Function: IffId::Nonequivalence Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool IffId::
operator != (const IffId &other) const {
return (_id._n != other._id._n);
}
////////////////////////////////////////////////////////////////////
// Function: IffId::Ordering Operator
// Access: Public
// Description: The ordering is arbitrary, and may not even be
// consistent between different architectures
// (e.g. big-endian and little-endian). It is useful
// mainly for putting IffId's into a sorted container,
// like sets and maps.
////////////////////////////////////////////////////////////////////
INLINE bool IffId::
operator < (const IffId &other) const {
return (_id._n < other._id._n);
}
////////////////////////////////////////////////////////////////////
// Function: IffId::get_name
// Access: Public
// Description: Returns the four-character name of the Id, for
// outputting.
////////////////////////////////////////////////////////////////////
INLINE string IffId::
get_name() const {
return string(_id._c, 4);
}

View File

@ -0,0 +1,6 @@
// Filename: iffId.cxx
// Created by: drose (23Apr01)
//
////////////////////////////////////////////////////////////////////
#include "iffId.h"

46
pandatool/src/lwo/iffId.h Normal file
View File

@ -0,0 +1,46 @@
// Filename: iffId.h
// Created by: drose (23Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef IFFID_H
#define IFFID_H
#include <pandatoolbase.h>
#include <numeric_types.h>
////////////////////////////////////////////////////////////////////
// Class : IffId
// Description : A four-byte chunk ID appearing in an "IFF" file.
// This is used to identify the meaning of each chunk,
// and can be treated either as a concrete object or as
// a string, something like a TypeHandle.
////////////////////////////////////////////////////////////////////
class IffId {
public:
INLINE IffId();
INLINE IffId(const char id[4]);
INLINE IffId(const IffId &copy);
INLINE void operator = (const IffId &copy);
INLINE bool operator == (const IffId &other) const;
INLINE bool operator != (const IffId &other) const;
INLINE bool operator < (const IffId &other) const;
INLINE string get_name() const;
private:
union {
PN_uint32 _n;
char _c[4];
} _id;
};
#include "iffId.I"
INLINE ostream &operator << (ostream &out, const IffId &id) {
return out << id.get_name();
}
#endif

View File

@ -0,0 +1,63 @@
// Filename: iffInputFile.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::set_filename
// Access: Public
// Description: Indicates the filename that the InputFile is
// currently opened on.
////////////////////////////////////////////////////////////////////
INLINE void IffInputFile::
set_filename(const Filename &filename) {
_filename = filename;
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::get_filename
// Access: Public
// Description: Returns the filename that the InputFile is
// currently opened on, if available.
////////////////////////////////////////////////////////////////////
INLINE const Filename &IffInputFile::
get_filename() const {
return _filename;
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::is_eof
// Access: Public
// Description: Returns true if the last read operation failed
// because of reaching EOF, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool IffInputFile::
is_eof() const {
return _eof;
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::get_bytes_read
// Access: Public
// Description: Returns the number of bytes read so far from the
// input file.
////////////////////////////////////////////////////////////////////
INLINE size_t IffInputFile::
get_bytes_read() const {
return _bytes_read;
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::align
// Access: Public
// Description: If the current file pointer is not positioned on an
// even-byte boundary, reads and discards one byte so
// that it is.
////////////////////////////////////////////////////////////////////
INLINE void IffInputFile::
align() {
if ((_bytes_read & 1) != 0) {
get_int8();
}
}

View File

@ -0,0 +1,374 @@
// Filename: iffInputFile.cxx
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#include "iffInputFile.h"
#include "iffGenericChunk.h"
#include <datagram.h>
#include <datagramIterator.h>
TypeHandle IffInputFile::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
IffInputFile::
IffInputFile() {
_input = (istream *)NULL;
_owns_istream = false;
_eof = true;
_bytes_read = 0;
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
IffInputFile::
~IffInputFile() {
if (_owns_istream) {
delete _input;
}
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::open_read
// Access: Public
// Description: Attempts to open the indicated filename for reading.
// Returns true if successful, false otherwise.
////////////////////////////////////////////////////////////////////
bool IffInputFile::
open_read(Filename filename) {
filename.set_binary();
ifstream *in = new ifstream;
if (filename.open_read(*in)) {
set_input(in, true);
set_filename(filename);
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::set_input
// Access: Public
// Description: Sets up the input to use an arbitrary istream. If
// owns_istream is true, the istream will be deleted
// when the IffInputFile destructs.
////////////////////////////////////////////////////////////////////
void IffInputFile::
set_input(istream *input, bool owns_istream) {
if (_owns_istream) {
delete _input;
}
_input = input;
_owns_istream = owns_istream;
_eof = false;
_bytes_read = 0;
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::get_int8
// Access: Public
// Description: Extracts a signed 8-bit integer.
////////////////////////////////////////////////////////////////////
PN_int8 IffInputFile::
get_int8() {
Datagram dg;
if (!read_bytes(dg, 1)) {
return 0;
}
DatagramIterator dgi(dg);
return dgi.get_int8();
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::get_uint8
// Access: Public
// Description: Extracts an unsigned 8-bit integer.
////////////////////////////////////////////////////////////////////
PN_uint8 IffInputFile::
get_uint8() {
Datagram dg;
if (!read_bytes(dg, 1)) {
return 0;
}
DatagramIterator dgi(dg);
return dgi.get_int8();
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::get_be_int16
// Access: Public
// Description: Extracts a signed 16-bit big-endian integer.
////////////////////////////////////////////////////////////////////
PN_int16 IffInputFile::
get_be_int16() {
Datagram dg;
if (!read_bytes(dg, 2)) {
return 0;
}
DatagramIterator dgi(dg);
return dgi.get_be_int16();
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::get_be_int32
// Access: Public
// Description: Extracts a signed 32-bit big-endian integer.
////////////////////////////////////////////////////////////////////
PN_int32 IffInputFile::
get_be_int32() {
Datagram dg;
if (!read_bytes(dg, 4)) {
return 0;
}
DatagramIterator dgi(dg);
return dgi.get_be_int32();
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::get_be_uint16
// Access: Public
// Description: Extracts an unsigned 16-bit big-endian integer.
////////////////////////////////////////////////////////////////////
PN_uint16 IffInputFile::
get_be_uint16() {
Datagram dg;
if (!read_bytes(dg, 2)) {
return 0;
}
DatagramIterator dgi(dg);
return dgi.get_be_uint16();
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::get_be_uint32
// Access: Public
// Description: Extracts an unsigned 32-bit big-endian integer.
////////////////////////////////////////////////////////////////////
PN_uint32 IffInputFile::
get_be_uint32() {
Datagram dg;
if (!read_bytes(dg, 4)) {
return 0;
}
DatagramIterator dgi(dg);
return dgi.get_be_uint32();
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::get_be_float32
// Access: Public
// Description: Extracts a 32-bit big-endian single-precision
// floating-point number.
////////////////////////////////////////////////////////////////////
float IffInputFile::
get_be_float32() {
Datagram dg;
if (!read_bytes(dg, 4)) {
return 0;
}
DatagramIterator dgi(dg);
return dgi.get_be_float32();
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::get_string
// Access: Public
// Description: Extracts a null-terminated string.
////////////////////////////////////////////////////////////////////
string IffInputFile::
get_string() {
string result;
char byte;
while (read_byte(byte)) {
if (byte == 0) {
break;
}
result += byte;
}
align();
return result;
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::get_id
// Access: Public
// Description: Extracts a 4-character IFF ID.
////////////////////////////////////////////////////////////////////
IffId IffInputFile::
get_id() {
Datagram dg;
if (!read_bytes(dg, 4)) {
return IffId();
}
const char *id = (const char *)dg.get_data();
return IffId(id);
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::get_chunk
// Access: Public
// Description: Reads a single IffChunk, determining its type based
// on its ID. Allocates and returns a new IffChunk
// object of the appropriate type. Returns NULL if EOF
// is reached before the chunk can be read completely,
// or if there is some other error in reading the chunk.
////////////////////////////////////////////////////////////////////
PT(IffChunk) IffInputFile::
get_chunk() {
IffId id = get_id();
PN_uint32 length = get_be_uint32();
if (!is_eof()) {
PT(IffChunk) chunk = make_new_chunk(id);
chunk->set_id(id);
size_t start_point = get_bytes_read();
size_t end_point = start_point + length;
if (chunk->read_iff(this, end_point)) {
size_t num_bytes_read = get_bytes_read() - start_point;
if (num_bytes_read > length) {
nout << *chunk << " read " << num_bytes_read
<< " instead of " << length << " bytes.\n";
return (IffChunk *)NULL;
} else if (num_bytes_read < length) {
size_t skip_count = length - num_bytes_read;
nout << "Ignoring " << skip_count << " bytes at the end of "
<< *chunk << "\n";
skip_bytes(skip_count);
}
return chunk;
}
}
return (IffChunk *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::get_sub_chunk
// Access: Public
// Description: Similar to get_chunk(), except the chunk size is only
// a 16-bit number instead of 32-bit, and it takes a
// context, which is the chunk in which this chunk is
// encountered. The parent chunk may (or may not)
// decide what kind of chunk is meant by the various
// id's encountered.
////////////////////////////////////////////////////////////////////
PT(IffChunk) IffInputFile::
get_sub_chunk(IffChunk *context) {
IffId id = get_id();
PN_uint16 length = get_be_uint16();
if (!is_eof()) {
PT(IffChunk) chunk = context->make_new_chunk(this, id);
chunk->set_id(id);
size_t start_point = get_bytes_read();
size_t end_point = start_point + length;
if (chunk->read_iff(this, end_point)) {
size_t num_bytes_read = get_bytes_read() - start_point;
if (num_bytes_read > length) {
nout << *chunk << " read " << num_bytes_read
<< " instead of " << length << " bytes.\n";
return (IffChunk *)NULL;
} else if (num_bytes_read < length) {
size_t skip_count = length - num_bytes_read;
nout << "Ignoring " << skip_count << " bytes at the end of "
<< *chunk << "\n";
skip_bytes(skip_count);
}
return chunk;
}
}
return (IffChunk *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::read_byte
// Access: Public
// Description: Reads a single byte. Returns true if successful,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool IffInputFile::
read_byte(char &byte) {
if (is_eof()) {
return false;
}
_input->get(byte);
_bytes_read++;
_eof = _input->eof() || _input->fail();
return !is_eof();
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::read_bytes
// Access: Public
// Description: Reads a series of bytes, and stores them in the
// indicated Datagram. Returns true if successful,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool IffInputFile::
read_bytes(Datagram &datagram, size_t length) {
if (is_eof()) {
return false;
}
char *buffer = new char[length];
_input->read(buffer, length);
_eof = (_input->gcount() != length);
if (is_eof()) {
return false;
}
_bytes_read += length;
datagram = Datagram(buffer, length);
delete[] buffer;
return true;
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::skip_bytes
// Access: Public
// Description: Reads a series of bytes, but does not store them.
// Returns true if successful, false otherwise.
////////////////////////////////////////////////////////////////////
bool IffInputFile::
skip_bytes(size_t length) {
if (is_eof()) {
return false;
}
char byte;
while (length > 0 && !is_eof()) {
read_byte(byte);
length--;
}
return !is_eof();
}
////////////////////////////////////////////////////////////////////
// Function: IffInputFile::make_new_chunk
// Access: Protected, Virtual
// Description: Allocates and returns a new chunk of the appropriate
// type based on the given ID.
////////////////////////////////////////////////////////////////////
IffChunk *IffInputFile::
make_new_chunk(IffId) {
return new IffGenericChunk;
}

View File

@ -0,0 +1,93 @@
// Filename: iffInputFile.h
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef IFFINPUTFILE_H
#define IFFINPUTFILE_H
#include <pandatoolbase.h>
#include "iffId.h"
#include "iffChunk.h"
#include <typeHandle.h>
#include <pointerTo.h>
class Datagram;
////////////////////////////////////////////////////////////////////
// Class : IffInputFile
// Description : A wrapper around an istream used for reading an IFF
// file.
////////////////////////////////////////////////////////////////////
class IffInputFile : public TypedObject {
public:
IffInputFile();
virtual ~IffInputFile();
bool open_read(Filename filename);
void set_input(istream *input, bool owns_istream);
INLINE void set_filename(const Filename &filename);
INLINE const Filename &get_filename() const;
INLINE bool is_eof() const;
INLINE size_t get_bytes_read() const;
INLINE void align();
PN_int8 get_int8();
PN_uint8 get_uint8();
PN_int16 get_be_int16();
PN_int32 get_be_int32();
PN_uint16 get_be_uint16();
PN_uint32 get_be_uint32();
float get_be_float32();
string get_string();
IffId get_id();
PT(IffChunk) get_chunk();
PT(IffChunk) get_sub_chunk(IffChunk *context);
bool read_byte(char &byte);
bool read_bytes(Datagram &datagram, size_t length);
bool skip_bytes(size_t length);
protected:
virtual IffChunk *make_new_chunk(IffId id);
istream *_input;
Filename _filename;
bool _owns_istream;
bool _eof;
size_t _bytes_read;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedObject::init_type();
register_type(_type_handle, "IffInputFile",
TypedObject::get_class_type());
}
private:
static TypeHandle _type_handle;
friend IffChunk;
};
#include "iffInputFile.I"
#endif

View File

@ -0,0 +1,4 @@
// Filename: lwoChunk.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,8 @@
// Filename: lwoChunk.cxx
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#include "lwoChunk.h"
TypeHandle LwoChunk::_type_handle;

View File

@ -0,0 +1,46 @@
// Filename: lwoChunk.h
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef LWOCHUNK_H
#define LWOCHUNK_H
#include <pandatoolbase.h>
#include "iffChunk.h"
////////////////////////////////////////////////////////////////////
// Class : LwoChunk
// Description : A specialization of IffChunk for Lightwave Object
// files. Each kind of chunk that is specific to a
// Lightwave file should inherit directly or indirectly
// from LwoChunk.
////////////////////////////////////////////////////////////////////
class LwoChunk : public IffChunk {
public:
// No particular interface here.
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
IffChunk::init_type();
register_type(_type_handle, "LwoChunk",
IffChunk::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "lwoChunk.I"
#endif

View File

@ -0,0 +1,4 @@
// Filename: lwoDiscontinuousVertexMap.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,104 @@
// Filename: lwoDiscontinuousVertexMap.cxx
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#include "lwoDiscontinuousVertexMap.h"
#include "lwoInputFile.h"
#include <indent.h>
TypeHandle LwoDiscontinuousVertexMap::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LwoDiscontinuousVertexMap::has_value
// Access: Public
// Description: Returns true if the map has a value associated with
// the given index, false otherwise.
////////////////////////////////////////////////////////////////////
bool LwoDiscontinuousVertexMap::
has_value(int polygon_index, int vertex_index) const {
VMad::const_iterator di;
di = _vmad.find(polygon_index);
if (di != _vmad.end()) {
const VMap &vmap = (*di).second;
return (vmap.count(vertex_index) != 0);
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: LwoDiscontinuousVertexMap::get_value
// Access: Public
// Description: Returns the mapping value associated with the given
// index, or an empty PTA_float if there is no mapping
// value associated.
////////////////////////////////////////////////////////////////////
PTA_float LwoDiscontinuousVertexMap::
get_value(int polygon_index, int vertex_index) const {
VMad::const_iterator di;
di = _vmad.find(polygon_index);
if (di != _vmad.end()) {
const VMap &vmap = (*di).second;
VMap::const_iterator vi;
vi = vmap.find(vertex_index);
if (vi != vmap.end()) {
return (*vi).second;
}
}
return PTA_float();
}
////////////////////////////////////////////////////////////////////
// Function: LwoDiscontinuousVertexMap::read_iff
// Access: Public, Virtual
// Description: Reads the data of the chunk in from the given input
// file, if possible. The ID and length of the chunk
// have already been read. stop_at is the byte position
// of the file to stop at (based on the current position
// at in->get_bytes_read()). Returns true on success,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool LwoDiscontinuousVertexMap::
read_iff(IffInputFile *in, size_t stop_at) {
LwoInputFile *lin = DCAST(LwoInputFile, in);
_map_type = lin->get_id();
_dimension = lin->get_be_uint16();
_name = lin->get_string();
while (lin->get_bytes_read() < stop_at && !lin->is_eof()) {
int vertex_index = lin->get_vx();
int polygon_index = lin->get_vx();
PTA_float value;
for (int i = 0; i < _dimension; i++) {
value.push_back(lin->get_be_float32());
}
bool inserted = _vmad[polygon_index].insert(VMap::value_type(vertex_index, value)).second;
if (!inserted) {
nout << "Duplicate pair " << polygon_index << ", " << vertex_index
<< " in map.\n";
}
}
return (lin->get_bytes_read() == stop_at);
}
////////////////////////////////////////////////////////////////////
// Function: LwoDiscontinuousVertexMap::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void LwoDiscontinuousVertexMap::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< get_id() << " { map_type = " << _map_type
<< ", dimension = " << _dimension
<< ", name = \"" << _name << "\", "
<< _vmad.size() << " polygons }\n";
}

View File

@ -0,0 +1,61 @@
// Filename: lwoDiscontinuousVertexMap.h
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef LWODISCONTINUOUSVERTEXMAP_H
#define LWODISCONTINUOUSVERTEXMAP_H
#include <pandatoolbase.h>
#include "lwoChunk.h"
#include <pta_float.h>
////////////////////////////////////////////////////////////////////
// Class : LwoDiscontinuousVertexMap
// Description : A mapping of floating-point values per integer index.
// The meaning of these values is determined by the
// mapping type code and/or its name.
////////////////////////////////////////////////////////////////////
class LwoDiscontinuousVertexMap : public LwoChunk {
public:
bool has_value(int polygon_index, int vertex_index) const;
PTA_float get_value(int polygon_index, int vertex_index) const;
IffId _map_type;
int _dimension;
string _name;
public:
virtual bool read_iff(IffInputFile *in, size_t stop_at);
virtual void write(ostream &out, int indent_level = 0) const;
private:
typedef map<int, PTA_float> VMap;
typedef map<int, VMap> VMad;
VMad _vmad;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
LwoChunk::init_type();
register_type(_type_handle, "LwoDiscontinuousVertexMap",
LwoChunk::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "lwoDiscontinuousVertexMap.I"
#endif

View File

@ -0,0 +1,4 @@
// Filename: lwoGroupChunk.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,68 @@
// Filename: lwoGroupChunk.cxx
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#include "lwoGroupChunk.h"
#include "lwoInputFile.h"
#include <notify.h>
TypeHandle LwoGroupChunk::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LwoGroupChunk::get_num_children
// Access: Public
// Description: Returns the number of child chunks of this group.
////////////////////////////////////////////////////////////////////
int LwoGroupChunk::
get_num_children() const {
return _children.size();
}
////////////////////////////////////////////////////////////////////
// Function: LwoGroupChunk::get_child
// Access: Public
// Description: Returns the nth child chunk of this group.
////////////////////////////////////////////////////////////////////
IffChunk *LwoGroupChunk::
get_child(int n) const {
nassertr(n >= 0 && n < (int)_children.size(), (IffChunk *)NULL);
return _children[n];
}
////////////////////////////////////////////////////////////////////
// Function: LwoGroupChunk::read_children_iff
// Access: Public
// Description: Reads a sequence of child chunks, until byte stop_at
// has been been reached, and stores them as the
// children. Returns true if successful (and exactly
// the correct number of bytes were read), or false
// otherwise.
////////////////////////////////////////////////////////////////////
bool LwoGroupChunk::
read_children_iff(IffInputFile *in, size_t stop_at) {
while (in->get_bytes_read() < stop_at && !in->is_eof()) {
PT(IffChunk) chunk = in->get_chunk();
if (chunk == (IffChunk *)NULL) {
return false;
}
_children.push_back(chunk);
}
return (in->get_bytes_read() == stop_at);
}
////////////////////////////////////////////////////////////////////
// Function: LwoGroupChunk::write_children
// Access: Public
// Description: Formats the list of children for output to the user
// (primarily for debugging), one per line.
////////////////////////////////////////////////////////////////////
void LwoGroupChunk::
write_children(ostream &out, int indent_level) const {
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
(*ci)->write(out, indent_level);
}
}

View File

@ -0,0 +1,57 @@
// Filename: lwoGroupChunk.h
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef LWOGROUPCHUNK_H
#define LWOGROUPCHUNK_H
#include <pandatoolbase.h>
#include "lwoChunk.h"
#include "iffChunk.h"
#include <pointerTo.h>
#include <vector>
////////////////////////////////////////////////////////////////////
// Class : LwoGroupChunk
// Description : A particular kind of LwoChunk that is expected to
// contain an arbitrary number of child chunks.
////////////////////////////////////////////////////////////////////
class LwoGroupChunk : public LwoChunk {
public:
int get_num_children() const;
IffChunk *get_child(int n) const;
protected:
bool read_children_iff(IffInputFile *in, size_t stop_at);
void write_children(ostream &out, int indent_level) const;
typedef vector< PT(IffChunk) > Children;
Children _children;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
LwoChunk::init_type();
register_type(_type_handle, "LwoGroupChunk",
LwoChunk::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "lwoGroupChunk.I"
#endif

View File

@ -0,0 +1,16 @@
// Filename: lwoHeader.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: LwoHeader::get_lwid
// Access: Public
// Description: Returns the Lightwave ID of the file. This is the
// first ID read within the header, and indicates the
// version of the Lightwave file in some mysterious way.
////////////////////////////////////////////////////////////////////
IffId LwoHeader::
get_lwid() const {
return _lwid;
}

View File

@ -0,0 +1,43 @@
// Filename: lwoHeader.cxx
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#include "lwoHeader.h"
#include "iffInputFile.h"
#include <indent.h>
TypeHandle LwoHeader::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LwoHeader::read_iff
// Access: Public, Virtual
// Description: Reads the data of the chunk in from the given input
// file, if possible. The ID and length of the chunk
// have already been read. stop_at is the byte position
// of the file to stop at (based on the current position
// at in->get_bytes_read()). Returns true on success,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool LwoHeader::
read_iff(IffInputFile *in, size_t stop_at) {
_lwid = in->get_id();
return read_children_iff(in, stop_at);
}
////////////////////////////////////////////////////////////////////
// Function: LwoHeader::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void LwoHeader::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< get_id() << " {\n";
indent(out, indent_level + 2)
<< _lwid << "\n";
write_children(out, indent_level + 2);
indent(out, indent_level)
<< "}\n";
}

View File

@ -0,0 +1,50 @@
// Filename: lwoHeader.h
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef LWOHEADER_H
#define LWOHEADER_H
#include <pandatoolbase.h>
#include "lwoGroupChunk.h"
////////////////////////////////////////////////////////////////////
// Class : LwoHeader
// Description : The first chunk in a Lightwave Object file.
////////////////////////////////////////////////////////////////////
class LwoHeader : public LwoGroupChunk {
public:
INLINE IffId get_lwid() const;
public:
virtual bool read_iff(IffInputFile *in, size_t stop_at);
virtual void write(ostream &out, int indent_level = 0) const;
private:
IffId _lwid;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
LwoGroupChunk::init_type();
register_type(_type_handle, "LwoHeader",
LwoGroupChunk::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "lwoHeader.I"
#endif

View File

@ -0,0 +1,4 @@
// Filename: lwoInputFile.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,129 @@
// Filename: lwoInputFile.cxx
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#include "lwoInputFile.h"
#include "lwoDiscontinuousVertexMap.h"
#include "lwoHeader.h"
#include "lwoLayer.h"
#include "lwoPoints.h"
#include "lwoPolygons.h"
#include "lwoPolygonTags.h"
#include "lwoVertexMap.h"
#include "lwoTags.h"
TypeHandle LwoInputFile::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LwoInputFile::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
LwoInputFile::
LwoInputFile() {
}
////////////////////////////////////////////////////////////////////
// Function: LwoInputFile::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
LwoInputFile::
~LwoInputFile() {
}
////////////////////////////////////////////////////////////////////
// Function: LwoInputFile::get_vx
// Access: Public
// Description: Reads a Lightwave variable-length index. This is
// either a 2-byte or 4-byte integer.
////////////////////////////////////////////////////////////////////
int LwoInputFile::
get_vx() {
PN_uint16 top = get_be_uint16();
if ((top & 0xff00) == 0xff00) {
// The first byte is 0xff, which indicates we have a 4-byte
// integer.
PN_uint16 bottom = get_be_uint16();
return ((int)(top & 0xff) << 16) | bottom;
}
// The first byte is not 0xff, which indicates we have a 2-byte
// integer.
return top;
}
////////////////////////////////////////////////////////////////////
// Function: LwoInputFile::get_vec3
// Access: Public
// Description: Reads a three-component vector of floats.
////////////////////////////////////////////////////////////////////
LVecBase3f LwoInputFile::
get_vec3() {
LVecBase3f result;
result[0] = get_be_float32();
result[1] = get_be_float32();
result[2] = get_be_float32();
return result;
}
////////////////////////////////////////////////////////////////////
// Function: LwoInputFile::get_filename
// Access: Public
// Description: Reads a Lightwave platform-neutral filename and
// converts it to a Panda platform-neutral filename.
////////////////////////////////////////////////////////////////////
Filename LwoInputFile::
get_filename() {
string name = get_string();
size_t colon = name.find(':');
if (colon == string::npos) {
// No colon; it's just a relative path.
return Filename(name);
}
// The colon separates the device and the path.
string device = name.substr(0, colon);
string path = name.substr(colon + 1);
nout << "Ignoring filename device " << device << "\n";
return Filename("/", path);
}
////////////////////////////////////////////////////////////////////
// Function: LwoInputFile::make_new_chunk
// Access: Protected, Virtual
// Description: Allocates and returns a new chunk of the appropriate
// type based on the given ID.
////////////////////////////////////////////////////////////////////
IffChunk *LwoInputFile::
make_new_chunk(IffId id) {
if (id == IffId("FORM")) {
return new LwoHeader;
} else if (id == IffId("LAYR")) {
return new LwoLayer;
} else if (id == IffId("PNTS")) {
return new LwoPoints;
} else if (id == IffId("VMAP")) {
return new LwoVertexMap;
} else if (id == IffId("VMAD")) {
return new LwoDiscontinuousVertexMap;
} else if (id == IffId("POLS")) {
return new LwoPolygons;
} else if (id == IffId("TAGS")) {
return new LwoTags;
} else if (id == IffId("PTAG")) {
return new LwoPolygonTags;
} else {
return IffInputFile::make_new_chunk(id);
}
}

View File

@ -0,0 +1,54 @@
// Filename: lwoInputFile.h
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef LWOINPUTFILE_H
#define LWOINPUTFILE_H
#include <pandatoolbase.h>
#include "iffInputFile.h"
#include <luse.h>
////////////////////////////////////////////////////////////////////
// Class : LwoInputFile
// Description : A specialization of IffInputFile to handle reading a
// Lightwave Object file.
////////////////////////////////////////////////////////////////////
class LwoInputFile : public IffInputFile {
public:
LwoInputFile();
~LwoInputFile();
int get_vx();
LVecBase3f get_vec3();
Filename get_filename();
protected:
virtual IffChunk *make_new_chunk(IffId id);
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
IffInputFile::init_type();
register_type(_type_handle, "LwoInputFile",
IffInputFile::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "lwoInputFile.I"
#endif

View File

@ -0,0 +1,4 @@
// Filename: lwoLayer.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,54 @@
// Filename: lwoLayer.cxx
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#include "lwoLayer.h"
#include "lwoInputFile.h"
#include <indent.h>
TypeHandle LwoLayer::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LwoLayer::read_iff
// Access: Public, Virtual
// Description: Reads the data of the chunk in from the given input
// file, if possible. The ID and length of the chunk
// have already been read. stop_at is the byte position
// of the file to stop at (based on the current position
// at in->get_bytes_read()). Returns true on success,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool LwoLayer::
read_iff(IffInputFile *in, size_t stop_at) {
LwoInputFile *lin = DCAST(LwoInputFile, in);
_number = lin->get_be_uint16();
_flags = lin->get_be_uint16();
_pivot = lin->get_vec3();
_name = lin->get_string();
if (lin->get_bytes_read() >= stop_at) {
_parent = -1;
} else {
_parent = lin->get_be_uint16();
if (_parent == 0xffff) {
_parent = -1;
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: LwoLayer::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void LwoLayer::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< get_id() << " { number = " << _number << ", flags = 0x"
<< hex << _flags << dec << ", pivot = " << _pivot
<< ", _name = \"" << _name << "\", _parent = " << _parent << " }\n";
}

View File

@ -0,0 +1,61 @@
// Filename: lwoLayer.h
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef LWOLAYER_H
#define LWOLAYER_H
#include <pandatoolbase.h>
#include "lwoChunk.h"
#include <luse.h>
////////////////////////////////////////////////////////////////////
// Class : LwoLayer
// Description : Signals the start of a new layer. All the data
// chunks which follow will be included in this layer
// until another layer chunk is encountered. If data is
// encountered before a layer chunk, it goes into an
// arbitrary layer.
////////////////////////////////////////////////////////////////////
class LwoLayer : public LwoChunk {
public:
enum Flags {
F_hidden = 0x0001
};
int _number;
int _flags;
LPoint3f _pivot;
string _name;
int _parent;
public:
virtual bool read_iff(IffInputFile *in, size_t stop_at);
virtual void write(ostream &out, int indent_level = 0) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
LwoChunk::init_type();
register_type(_type_handle, "LwoLayer",
LwoChunk::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "lwoLayer.I"
#endif

View File

@ -0,0 +1,4 @@
// Filename: lwoPoints.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,65 @@
// Filename: lwoPoints.cxx
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#include "lwoPoints.h"
#include "lwoInputFile.h"
#include <indent.h>
TypeHandle LwoPoints::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LwoPoints::get_num_points
// Access: Public
// Description: Returns the number of points of this group.
////////////////////////////////////////////////////////////////////
int LwoPoints::
get_num_points() const {
return _points.size();
}
////////////////////////////////////////////////////////////////////
// Function: LwoPoints::get_point
// Access: Public
// Description: Returns the nth point of this group.
////////////////////////////////////////////////////////////////////
const LPoint3f &LwoPoints::
get_point(int n) const {
nassertr(n >= 0 && n < (int)_points.size(), LPoint3f::zero());
return _points[n];
}
////////////////////////////////////////////////////////////////////
// Function: LwoPoints::read_iff
// Access: Public, Virtual
// Description: Reads the data of the chunk in from the given input
// file, if possible. The ID and length of the chunk
// have already been read. stop_at is the byte position
// of the file to stop at (based on the current position
// at in->get_bytes_read()). Returns true on success,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool LwoPoints::
read_iff(IffInputFile *in, size_t stop_at) {
LwoInputFile *lin = DCAST(LwoInputFile, in);
while (lin->get_bytes_read() < stop_at && !lin->is_eof()) {
LPoint3f point = lin->get_vec3();
_points.push_back(point);
}
return (lin->get_bytes_read() == stop_at);
}
////////////////////////////////////////////////////////////////////
// Function: LwoPoints::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void LwoPoints::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< get_id() << " { " << _points.size() << " points }\n";
}

View File

@ -0,0 +1,55 @@
// Filename: lwoPoints.h
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef LWOPOINTS_H
#define LWOPOINTS_H
#include <pandatoolbase.h>
#include "lwoChunk.h"
#include <luse.h>
////////////////////////////////////////////////////////////////////
// Class : LwoPoints
// Description : An array of points that will be referenced by later
// chunks.
////////////////////////////////////////////////////////////////////
class LwoPoints : public LwoChunk {
public:
int get_num_points() const;
const LPoint3f &get_point(int n) const;
public:
virtual bool read_iff(IffInputFile *in, size_t stop_at);
virtual void write(ostream &out, int indent_level = 0) const;
private:
typedef vector<LPoint3f> Points;
Points _points;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
LwoChunk::init_type();
register_type(_type_handle, "LwoPoints",
LwoChunk::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "lwoPoints.I"
#endif

View File

@ -0,0 +1,4 @@
// Filename: lwoPolygonTags.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,81 @@
// Filename: lwoPolygonTags.cxx
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#include "lwoPolygonTags.h"
#include "lwoInputFile.h"
#include <indent.h>
TypeHandle LwoPolygonTags::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LwoPolygonTags::has_tag
// Access: Public
// Description: Returns true if the map has a tag associated with
// the given polygon index, false otherwise.
////////////////////////////////////////////////////////////////////
bool LwoPolygonTags::
has_tag(int polygon_index) const {
return (_tmap.count(polygon_index) != 0);
}
////////////////////////////////////////////////////////////////////
// Function: LwoPolygonTags::get_tag
// Access: Public
// Description: Returns the tag associated with the given polygon
// index, or -1 if there is no tag associated.
////////////////////////////////////////////////////////////////////
int LwoPolygonTags::
get_tag(int polygon_index) const {
TMap::const_iterator ti;
ti = _tmap.find(polygon_index);
if (ti != _tmap.end()) {
return (*ti).second;
}
return -1;
}
////////////////////////////////////////////////////////////////////
// Function: LwoPolygonTags::read_iff
// Access: Public, Virtual
// Description: Reads the data of the chunk in from the given input
// file, if possible. The ID and length of the chunk
// have already been read. stop_at is the byte position
// of the file to stop at (based on the current position
// at in->get_bytes_read()). Returns true on success,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool LwoPolygonTags::
read_iff(IffInputFile *in, size_t stop_at) {
LwoInputFile *lin = DCAST(LwoInputFile, in);
_tag_type = lin->get_id();
while (lin->get_bytes_read() < stop_at && !lin->is_eof()) {
int polygon_index = lin->get_vx();
int tag = lin->get_be_int16();
bool inserted = _tmap.insert(TMap::value_type(polygon_index, tag)).second;
if (!inserted) {
nout << "Duplicate index " << index << " in map.\n";
}
}
return (lin->get_bytes_read() == stop_at);
}
////////////////////////////////////////////////////////////////////
// Function: LwoPolygonTags::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void LwoPolygonTags::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< get_id() << " { tag_type = " << _tag_type << ", "
<< _tmap.size() << " values }\n";
}

View File

@ -0,0 +1,57 @@
// Filename: lwoPolygonTags.h
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef LWOPOLYGONTAGS_H
#define LWOPOLYGONTAGS_H
#include <pandatoolbase.h>
#include "lwoChunk.h"
////////////////////////////////////////////////////////////////////
// Class : LwoPolygonTags
// Description : An association of polygons defined in the most recent
// LwoPolygons chunk to tag ids defined in the most
// recent LwoTags chunk. This associated properties
// with the polygons, depending on the tag_type.
////////////////////////////////////////////////////////////////////
class LwoPolygonTags : public LwoChunk {
public:
bool has_tag(int polygon_index) const;
int get_tag(int polygon_index) const;
IffId _tag_type;
public:
virtual bool read_iff(IffInputFile *in, size_t stop_at);
virtual void write(ostream &out, int indent_level = 0) const;
private:
typedef map<int, int> TMap;
TMap _tmap;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
LwoChunk::init_type();
register_type(_type_handle, "LwoPolygonTags",
LwoChunk::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "lwoPolygonTags.I"
#endif

View File

@ -0,0 +1,4 @@
// Filename: lwoPolygons.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,77 @@
// Filename: lwoPolygons.cxx
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#include "lwoPolygons.h"
#include "lwoInputFile.h"
#include <indent.h>
TypeHandle LwoPolygons::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LwoPolygons::get_num_polygons
// Access: Public
// Description: Returns the number of polygons of this group.
////////////////////////////////////////////////////////////////////
int LwoPolygons::
get_num_polygons() const {
return _polygons.size();
}
////////////////////////////////////////////////////////////////////
// Function: LwoPolygons::get_polygon
// Access: Public
// Description: Returns the nth polygon of this group.
////////////////////////////////////////////////////////////////////
LwoPolygons::Polygon *LwoPolygons::
get_polygon(int n) const {
nassertr(n >= 0 && n < (int)_polygons.size(), (Polygon *)NULL);
return _polygons[n];
}
////////////////////////////////////////////////////////////////////
// Function: LwoPolygons::read_iff
// Access: Public, Virtual
// Description: Reads the data of the chunk in from the given input
// file, if possible. The ID and length of the chunk
// have already been read. stop_at is the byte position
// of the file to stop at (based on the current position
// at in->get_bytes_read()). Returns true on success,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool LwoPolygons::
read_iff(IffInputFile *in, size_t stop_at) {
LwoInputFile *lin = DCAST(LwoInputFile, in);
_polygon_type = lin->get_id();
while (lin->get_bytes_read() < stop_at && !lin->is_eof()) {
int nf = lin->get_be_int16();
int num_vertices = nf & PF_numverts_mask;
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());
}
_polygons.push_back(poly);
}
return (lin->get_bytes_read() == stop_at);
}
////////////////////////////////////////////////////////////////////
// Function: LwoPolygons::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void LwoPolygons::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< get_id() << " { polygon_type = " << _polygon_type
<< ", " << _polygons.size() << " polygons }\n";
}

View File

@ -0,0 +1,72 @@
// Filename: lwoPolygons.h
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef LWOPOLYGONS_H
#define LWOPOLYGONS_H
#include <pandatoolbase.h>
#include "lwoChunk.h"
#include <luse.h>
#include <vector_int.h>
#include <referenceCount.h>
#include <pointerTo.h>
////////////////////////////////////////////////////////////////////
// Class : LwoPolygons
// Description : An array of polygons that will be referenced by later
// chunks.
////////////////////////////////////////////////////////////////////
class LwoPolygons : public LwoChunk {
public:
enum PolygonFlags {
PF_continuity_1 = 0x0400,
PF_continuity_2 = 0x0800,
PF_numverts_mask = 0x03ff
};
class Polygon : public ReferenceCount {
public:
int _flags;
vector_int _vertices;
};
int get_num_polygons() const;
Polygon *get_polygon(int n) const;
IffId _polygon_type;
public:
virtual bool read_iff(IffInputFile *in, size_t stop_at);
virtual void write(ostream &out, int indent_level = 0) const;
private:
typedef vector< PT(Polygon) > Polygons;
Polygons _polygons;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
LwoChunk::init_type();
register_type(_type_handle, "LwoPolygons",
LwoChunk::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "lwoPolygons.I"
#endif

View File

@ -0,0 +1,4 @@
// Filename: lwoTags.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,76 @@
// Filename: lwoTags.cxx
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#include "lwoTags.h"
#include "lwoInputFile.h"
#include <indent.h>
TypeHandle LwoTags::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LwoTags::get_num_tags
// Access: Public
// Description: Returns the number of tags of this group.
////////////////////////////////////////////////////////////////////
int LwoTags::
get_num_tags() const {
return _tags.size();
}
////////////////////////////////////////////////////////////////////
// Function: LwoTags::get_tag
// Access: Public
// Description: Returns the nth tag of this group.
////////////////////////////////////////////////////////////////////
string LwoTags::
get_tag(int n) const {
nassertr(n >= 0 && n < (int)_tags.size(), string());
return _tags[n];
}
////////////////////////////////////////////////////////////////////
// Function: LwoTags::read_iff
// Access: Public, Virtual
// Description: Reads the data of the chunk in from the given input
// file, if possible. The ID and length of the chunk
// have already been read. stop_at is the byte position
// of the file to stop at (based on the current position
// at in->get_bytes_read()). Returns true on success,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool LwoTags::
read_iff(IffInputFile *in, size_t stop_at) {
LwoInputFile *lin = DCAST(LwoInputFile, in);
while (lin->get_bytes_read() < stop_at && !lin->is_eof()) {
string tag = lin->get_string();
_tags.push_back(tag);
}
return (lin->get_bytes_read() == stop_at);
}
////////////////////////////////////////////////////////////////////
// Function: LwoTags::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void LwoTags::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< get_id() << " { ";
if (!_tags.empty()) {
Tags::const_iterator ti = _tags.begin();
out << *ti;
++ti;
while (ti != _tags.end()) {
out << ", " << *ti;
++ti;
}
}
out << " }\n";
}

View File

@ -0,0 +1,56 @@
// Filename: lwoTags.h
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef LWOTAGS_H
#define LWOTAGS_H
#include <pandatoolbase.h>
#include "lwoChunk.h"
#include <luse.h>
#include <vector_string.h>
////////////////////////////////////////////////////////////////////
// Class : LwoTags
// Description : An array of tag strings that will be referenced by
// later chunks.
////////////////////////////////////////////////////////////////////
class LwoTags : public LwoChunk {
public:
int get_num_tags() const;
string get_tag(int n) const;
public:
virtual bool read_iff(IffInputFile *in, size_t stop_at);
virtual void write(ostream &out, int indent_level = 0) const;
private:
typedef vector_string Tags;
Tags _tags;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
LwoChunk::init_type();
register_type(_type_handle, "LwoTags",
LwoChunk::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "lwoTags.I"
#endif

View File

@ -0,0 +1,4 @@
// Filename: lwoVertexMap.I
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,90 @@
// Filename: lwoVertexMap.cxx
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#include "lwoVertexMap.h"
#include "lwoInputFile.h"
#include <indent.h>
TypeHandle LwoVertexMap::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LwoVertexMap::has_value
// Access: Public
// Description: Returns true if the map has a value associated with
// the given index, false otherwise.
////////////////////////////////////////////////////////////////////
bool LwoVertexMap::
has_value(int index) const {
return (_vmap.count(index) != 0);
}
////////////////////////////////////////////////////////////////////
// Function: LwoVertexMap::get_value
// Access: Public
// Description: Returns the mapping value associated with the given
// index, or an empty PTA_float if there is no mapping
// value associated.
////////////////////////////////////////////////////////////////////
PTA_float LwoVertexMap::
get_value(int index) const {
VMap::const_iterator vi;
vi = _vmap.find(index);
if (vi != _vmap.end()) {
return (*vi).second;
}
return PTA_float();
}
////////////////////////////////////////////////////////////////////
// Function: LwoVertexMap::read_iff
// Access: Public, Virtual
// Description: Reads the data of the chunk in from the given input
// file, if possible. The ID and length of the chunk
// have already been read. stop_at is the byte position
// of the file to stop at (based on the current position
// at in->get_bytes_read()). Returns true on success,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool LwoVertexMap::
read_iff(IffInputFile *in, size_t stop_at) {
LwoInputFile *lin = DCAST(LwoInputFile, in);
_map_type = lin->get_id();
_dimension = lin->get_be_uint16();
_name = lin->get_string();
while (lin->get_bytes_read() < stop_at && !lin->is_eof()) {
int index = lin->get_vx();
PTA_float value;
for (int i = 0; i < _dimension; i++) {
value.push_back(lin->get_be_float32());
}
bool inserted = _vmap.insert(VMap::value_type(index, value)).second;
if (!inserted) {
nout << "Duplicate index " << index << " in map.\n";
}
}
return (lin->get_bytes_read() == stop_at);
}
////////////////////////////////////////////////////////////////////
// Function: LwoVertexMap::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void LwoVertexMap::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< get_id() << " { map_type = " << _map_type
<< ", dimension = " << _dimension
<< ", name = \"" << _name << "\", "
<< _vmap.size() << " values }\n";
}

View File

@ -0,0 +1,60 @@
// Filename: lwoVertexMap.h
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef LWOVERTEXMAP_H
#define LWOVERTEXMAP_H
#include <pandatoolbase.h>
#include "lwoChunk.h"
#include <pta_float.h>
////////////////////////////////////////////////////////////////////
// Class : LwoVertexMap
// Description : A mapping of floating-point values per integer index.
// The meaning of these values is determined by the
// mapping type code and/or its name.
////////////////////////////////////////////////////////////////////
class LwoVertexMap : public LwoChunk {
public:
bool has_value(int index) const;
PTA_float get_value(int index) const;
IffId _map_type;
int _dimension;
string _name;
public:
virtual bool read_iff(IffInputFile *in, size_t stop_at);
virtual void write(ostream &out, int indent_level = 0) const;
private:
typedef map<int, PTA_float> VMap;
VMap _vmap;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
LwoChunk::init_type();
register_type(_type_handle, "LwoVertexMap",
LwoChunk::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "lwoVertexMap.I"
#endif

View File

@ -0,0 +1,32 @@
// Filename: test_lwo.cxx
// Created by: drose (24Apr01)
//
////////////////////////////////////////////////////////////////////
#include "lwoInputFile.h"
#include "lwoChunk.h"
int
main(int argc, char *argv[]) {
if (argc != 2) {
cerr << "test_lwo file.lwo\n";
exit(1);
}
LwoInputFile in;
if (!in.open_read(argv[1])) {
cerr << "Unable to open " << argv[1] << "\n";
exit(1);
}
PT(IffChunk) chunk = in.get_chunk();
while (chunk != (IffChunk *)NULL) {
cerr << "Got chunk type " << chunk->get_type() << ":\n";
chunk->write(cerr, 2);
chunk = in.get_chunk();
}
cerr << "EOF = " << in.is_eof() << "\n";
return (0);
}