From 0c34502a3ea81e4b13797eb4406e58ea28b099aa Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 2 Nov 2000 00:28:01 +0000 Subject: [PATCH] *** empty log message *** --- pandatool/src/flt/fltVertex.cxx | 16 +- pandatool/src/fltprogs/fltCopy.cxx | 248 +++++++++++++++++++++++++++++ pandatool/src/fltprogs/fltCopy.h | 65 ++++++++ 3 files changed, 327 insertions(+), 2 deletions(-) create mode 100644 pandatool/src/fltprogs/fltCopy.cxx create mode 100644 pandatool/src/fltprogs/fltCopy.h diff --git a/pandatool/src/flt/fltVertex.cxx b/pandatool/src/flt/fltVertex.cxx index fcb5ba7ffe..eecf073745 100644 --- a/pandatool/src/flt/fltVertex.cxx +++ b/pandatool/src/flt/fltVertex.cxx @@ -64,10 +64,10 @@ get_record_length() const { return 40; case FO_vertex_cn: - return 52; + return 56; case FO_vertex_cnu: - return 60; + return 64; case FO_vertex_cu: return 48; @@ -173,6 +173,12 @@ extract_record(FltRecordReader &reader) { } _color_index = iterator.get_be_uint32(); + if (_has_normal) { + // If we extracted a normal, our double-word alignment is off; now + // we have a few extra bytes to ignore. + iterator.skip_bytes(4); + } + nassertr(iterator.get_remaining_size() == 0, true); return true; } @@ -216,6 +222,12 @@ build_record(FltRecordWriter &writer) const { datagram.add_be_uint32(_color_index); + if (_has_normal) { + // If we added a normal, our double-word alignment is off; now we + // have a few extra bytes to add. + datagram.pad_bytes(4); + } + nassertr((int)datagram.get_length() == get_record_length() - 4, true); return true; } diff --git a/pandatool/src/fltprogs/fltCopy.cxx b/pandatool/src/fltprogs/fltCopy.cxx new file mode 100644 index 0000000000..889d91978f --- /dev/null +++ b/pandatool/src/fltprogs/fltCopy.cxx @@ -0,0 +1,248 @@ +// Filename: fltCopy.cxx +// Created by: drose (01Nov00) +// +//////////////////////////////////////////////////////////////////// + +#include "fltCopy.h" + +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////// +// Function: FltCopy::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +FltCopy:: +FltCopy() { + set_program_description + ("This program copies one or more MultiGen .flt files into a " + "CVS source hierarchy. " + "Rather than copying the named files immediately into the current " + "directory, it first scans the entire source hierarchy, identifying all " + "the already-existing files. If the named file to copy matches the " + "name of an already-existing file in the current directory or elsewhere " + "in the hierarchy, that file is overwritten. Other .flt files, as " + "well as texture files, that are externally referenced by the " + "named .flt file(s) are similarly copied."); + + clear_runlines(); + add_runline("[opts] file.flt [file.flt ... ]"); + + add_option + ("s", "dirname", 0, + "Specify the directory or directories that are to be searched for " + "relative pathnames appearing in the flt file. This may be a " + "single directory name or a colon-delimited list of directories. " + "It may also be " + "repeated multiple times on the command line; each time it appears " + "its named directories will be appended to the search path.", + &CVSCopy::dispatch_search_path, NULL, &_search_path); +} + +//////////////////////////////////////////////////////////////////// +// Function: FltCopy::run +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void FltCopy:: +run() { + if (_search_path.get_num_directories() == 0) { + _search_path.append_directory("."); + } + SourceFiles::iterator fi; + for (fi = _source_files.begin(); fi != _source_files.end(); ++fi) { + ExtraData ed; + ed._type = FT_flt; + + CVSSourceDirectory *dest = import(*fi, &ed, _model_dir); + if (dest == (CVSSourceDirectory *)NULL) { + exit(1); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: FltCopy::copy_file +// Access: Protected, Virtual +// Description: Called by import() if the timestamps indicate that a +// file needs to be copied. This does the actual copy +// of a file from source to destination. If new_file is +// true, then dest does not already exist. +//////////////////////////////////////////////////////////////////// +bool FltCopy:: +copy_file(const Filename &source, const Filename &dest, + CVSSourceDirectory *dir, void *extra_data, bool new_file) { + ExtraData *ed = (ExtraData *)extra_data; + switch (ed->_type) { + case FT_flt: + return copy_flt_file(source, dest, dir); + + case FT_texture: + return copy_texture(source, dest, dir, ed->_texture, new_file); + } + + nout << "Internal error: invalid type " << (int)ed->_type << "\n"; + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: FltCopy::copy_flt_file +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +bool FltCopy:: +copy_flt_file(const Filename &source, const Filename &dest, + CVSSourceDirectory *dir) { + PT(FltHeader) header = new FltHeader; + header->set_texture_path(_search_path); + + // We don't want to automatically generate .attr files--we'd rather + // write them out explicitly. + header->set_auto_attr_update(FltHeader::AU_none); + + FltError result = header->read_flt(source); + if (result != FE_ok) { + nout << "Cannot read " << source << "\n"; + return false; + } + + // Now scan the flt file for nested references. + Refs refs; + Textures textures; + scan_flt(header, refs, textures); + + Refs::const_iterator ri; + for (ri = refs.begin(); ri != refs.end(); ++ri) { + FltExternalReference *ref = (*ri); + Filename ref_filename = ref->_filename; + ref_filename.resolve_filename(_search_path); + + if (!ref_filename.exists()) { + nout << "*** Warning: external reference " << ref_filename + << " does not exist.\n"; + } else { + ExtraData ed; + ed._type = FT_flt; + + CVSSourceDirectory *ref_dir = + import(ref_filename, &ed, _model_dir); + if (ref_dir == (CVSSourceDirectory *)NULL) { + return false; + } + + // Update the reference to point to the new flt filename, relative + // to the base flt file. + ref->_filename = dir->get_rel_to(ref_dir) + "/" + + ref_filename.get_basename(); + } + } + + Textures::const_iterator ti; + for (ti = textures.begin(); ti != textures.end(); ++ti) { + FltTexture *tex = (*ti); + Filename texture_filename = tex->get_texture_filename(); + + if (!texture_filename.exists()) { + nout << "*** Warning: texture " << texture_filename + << " does not exist.\n"; + } else { + ExtraData ed; + ed._type = FT_texture; + ed._texture = tex; + + CVSSourceDirectory *texture_dir = + import(texture_filename, &ed, _map_dir); + if (texture_dir == (CVSSourceDirectory *)NULL) { + return false; + } + + // Update the texture reference to point to the new texture + // filename, relative to the flt file. + tex->_filename = dir->get_rel_to(texture_dir) + "/" + + texture_filename.get_basename(); + } + } + + // Finally, write the resulting file out. + result = header->write_flt(dest); + if (result != FE_ok) { + nout << "Cannot write " << dest << "\n"; + return false; + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: FltCopy::copy_texture +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +bool FltCopy:: +copy_texture(const Filename &source, const Filename &dest, + CVSSourceDirectory *dir, FltTexture *tex, bool new_file) { + if (!copy_binary_file(source, dest)) { + return false; + } + + // Also write out the .attr file. + Filename attr_filename = dest.get_fullpath() + ".attr"; + if (!attr_filename.exists()) { + new_file = true; + } + + tex->write_attr_data(attr_filename); + + if (new_file) { + create_file(attr_filename); + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: FltCopy::scan_flt +// Access: Private +// Description: Recursively walks through the flt file hierarchy, +// looking for texture references and external flt file +// references. +//////////////////////////////////////////////////////////////////// +void FltCopy:: +scan_flt(FltRecord *record, FltCopy::Refs &refs, FltCopy::Textures &textures) { + if (record->is_of_type(FltFace::get_class_type())) { + FltFace *face; + DCAST_INTO_V(face, record); + if (face->has_texture()) { + textures.insert(face->get_texture()); + } + + } else if (record->is_of_type(FltExternalReference::get_class_type())) { + FltExternalReference *ref; + DCAST_INTO_V(ref, record); + + refs.insert(ref); + } + + int i; + int num_subfaces = record->get_num_subfaces(); + for (i = 0; i < num_subfaces; i++) { + scan_flt(record->get_subface(i), refs, textures); + } + + int num_children = record->get_num_children(); + for (i = 0; i < num_children; i++) { + scan_flt(record->get_child(i), refs, textures); + } +} + + +int main(int argc, char *argv[]) { + FltCopy prog; + prog.parse_command_line(argc, argv); + prog.run(); + return 0; +} diff --git a/pandatool/src/fltprogs/fltCopy.h b/pandatool/src/fltprogs/fltCopy.h new file mode 100644 index 0000000000..0fe3659285 --- /dev/null +++ b/pandatool/src/fltprogs/fltCopy.h @@ -0,0 +1,65 @@ +// Filename: fltCopy.h +// Created by: drose (01Nov00) +// +//////////////////////////////////////////////////////////////////// + +#ifndef FLTCOPY_H +#define FLTCOPY_H + +#include + +#include "cvsCopy.h" + +#include + +#include + +class FltRecord; +class FltTexture; +class FltExternalReference; + +//////////////////////////////////////////////////////////////////// +// Class : FltCopy +// Description : A program to copy Multigen .flt files into the cvs +// tree. It copies the base file plus all externally +// referenced files as well as all textures. +//////////////////////////////////////////////////////////////////// +class FltCopy : public CVSCopy { +public: + FltCopy(); + + void run(); + +protected: + virtual bool copy_file(const Filename &source, const Filename &dest, + CVSSourceDirectory *dir, void *extra_data, + bool new_file); + +private: + enum FileType { + FT_flt, + FT_texture + }; + + class ExtraData { + public: + FileType _type; + FltTexture *_texture; + }; + + bool copy_flt_file(const Filename &source, const Filename &dest, + CVSSourceDirectory *dir); + bool copy_texture(const Filename &source, const Filename &dest, + CVSSourceDirectory *dir, FltTexture *tex, + bool new_file); + + + typedef set Refs; + typedef set Textures; + + void scan_flt(FltRecord *record, Refs &refs, Textures &textures); + + DSearchPath _search_path; +}; + +#endif